diff --git a/.babelrc b/.babelrc
deleted file mode 100644
index 2f01e1d6..00000000
--- a/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["env"]
-}
\ No newline at end of file
diff --git a/.gitattributes b/.gitattributes
deleted file mode 100644
index aef926ba..00000000
--- a/.gitattributes
+++ /dev/null
@@ -1,6 +0,0 @@
-#
-# Fixing language bar in github. To make this pure JS
-# See: https://github.com/github/linguist#overrides
-#
-test/html/* linguist-vendored
-src/jison/* linguist-vendored
diff --git a/.gitignore b/.gitignore
index 4dab79f1..91b984ce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,3 @@
-# Built files
-doc/*
-
# Logs
logs
*.log
@@ -17,15 +14,9 @@ lib-cov
# Coverage directory used by tools like istanbul
coverage
-# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
-.grunt
-
# node-waf configuration
.lock-wscript
-# Compiled binary addons (http://nodejs.org/api/addons.html)
-build/Release
-
# Dependency directory
node_modules
@@ -40,3 +31,6 @@ node_modules
#yarn
yarn.lock
+
+# OSX .DS_Store
+.DS_Store
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000..e9dac594
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,7 @@
+Thanks for taking the time to contribute to gpu.js. Follow these guidelines to make the process smoother:
+
+1. One feature per pull request. Each PR should have one focus, and all the code changes should be supporting that one feature or bug fix. Using a [separate branch](https://guides.github.com/introduction/flow/index.html) for each feature should help you manage developing multiple features at once.
+
+2. Follow the style of the file when it comes to syntax like curly braces and indents.
+
+3. Add a test for the feature or fix, if possible. See the `test` directory for existing tests and README describing how to run these tests.
diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md
new file mode 100644
index 00000000..5fd7db4a
--- /dev/null
+++ b/ISSUE_TEMPLATE.md
@@ -0,0 +1,20 @@
+
+
+
+## *What* is wrong?
+
+
+## *Where* does it happen?
+
+
+## *How* do we replicate the issue?
+
+
+## *How* important is this (1-5)?
+
+
+## Expected behavior (i.e. solution)
+
+
+
+## Other Comments
diff --git a/LICENSE b/LICENSE
index 8096c406..80c99b25 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
The MIT License
-Copyright (c) 2017 gpu.js Team
+Copyright (c) 2019 gpu.js Team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index d5cb9468..3ac5b9e9 100644
--- a/README.md
+++ b/README.md
@@ -1,62 +1,150 @@
-[](http://gpu.rocks/)
-
-
-# gpu.js
-gpu.js is a JavaScript Acceleration library for GPGPU (General purpose computing on GPUs) in Javascript. gpu.js will automatically compile simple JavaScript functions into shader language and run them on the GPU. In case a GPU is not available, the functions will still run in regular JavaScript.
+[ ](http://gpu.rocks/)
+# GPU.js
+GPU.js is a JavaScript Acceleration library for GPGPU (General purpose computing on GPUs) in JavaScript for Web and Node.
+GPU.js automatically transpiles simple JavaScript functions into shader language and compiles them so they run on your GPU.
+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.
[](https://gitter.im/gpujs/gpu.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[](https://slack.bri.im)
# What is this sorcery?
-Matrix multiplication written in gpu.js:
+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.
+Matrix multiplication (perform matrix multiplication on 2 matrices of size 512 x 512) written in GPU.js:
+
+## Browser
+```html
+
+
+```
+
+## CDN
+```
+https://unpkg.com/gpu.js@latest/dist/gpu-browser.min.js
+https://cdn.jsdelivr.net/npm/gpu.js@latest/dist/gpu-browser.min.js
+```
+## Node
```js
+const { GPU } = require('gpu.js');
const gpu = new GPU();
-
-// Create the GPU accelerated function from a kernel
-// function that computes a single element in the
-// 512 x 512 matrix (2D array). The kernel function
-// is run in a parallel manner in the GPU resulting
-// in very fast computations! (...sometimes)
-const matMult = gpu.createKernel(function(a, b) {
- var sum = 0;
- for (var i = 0; i < 512; i++) {
+const multiplyMatrix = 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]);
-// Perform matrix multiplication on 2 matrices of size 512 x 512
-const c = matMult(a, b);
+const c = multiplyMatrix(a, b);
```
-You can run a benchmark of this [here](http://gpu.rocks). Typically, it will run 1-15x faster depending on your hardware.
+## Typescript
+```typescript
+import { GPU } from 'gpu.js';
+const gpu = new GPU();
+const multiplyMatrix = gpu.createKernel(function(a: number[][], b: number[][]) {
+ 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 = multiplyMatrix(a, b) as number[][];
+```
-Or alternatively you can experiment around with the [kernel playground here](http://gpu.rocks/playground)
+[Click here](/examples) for more typescript examples.
# 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)_!
+
+* [Demos](#demos)
* [Installation](#installation)
-* [Options](#options)
+* [`GPU` Settings](#gpu-settings)
+* [`gpu.createKernel` Settings](#gpucreatekernel-settings)
+ * [Declaring variables/functions within kernels](#declaring-variablesfunctions-within-kernels)
* [Creating and Running Functions](#creating-and-running-functions)
+* [Debugging](#debugging)
* [Accepting Input](#accepting-input)
* [Graphical Output](#graphical-output)
* [Combining Kernels](#combining-kernels)
* [Create Kernel Map](#create-kernel-map)
* [Adding Custom Functions](#adding-custom-functions)
* [Adding Custom Functions Directly to Kernel](#adding-custom-functions-directly-to-kernel)
+* [Types](#types)
* [Loops](#loops)
* [Pipelining](#pipelining)
+ * [Cloning Textures](#cloning-textures-new-in-v2)
+ * [Cleanup pipeline texture memory](#cleanup-pipeline-texture-memory-new-in-v24)
+* [Offscreen Canvas](#offscreen-canvas)
+* [Cleanup](#cleanup)
+* [Flattened typed array support](#flattened-typed-array-support)
+* [Precompiled and Lighter Weight Kernels](#precompiled-and-lighter-weight-kernels)
+ * [using JSON](#using-json)
+ * [Exporting kernel](#exporting-kernel)
* [Supported Math functions](#supported-math-functions)
+* [How to check what is supported](#how-to-check-what-is-supported)
+* [Typescript Typings](#typescript-typings)
+* [Destructured Assignments](#destructured-assignments-new-in-v2)
+* [Dealing With Transpilation](#dealing-with-transpilation)
* [Full API reference](#full-api-reference)
-* [Automatically-built Documentation](#automatically-built-documentation)
+* [How possible in node](#how-possible-in-node)
+* [Testing](#testing)
+* [Building](#building)
* [Contributors](#contributors)
* [Contributing](#contributing)
* [Terms Explained](#terms-explained)
* [License](#license)
+## 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)
+* [Julia Set Fractal using GPU.js](https://observablehq.com/@ukabuer/julia-set-fractal-using-gpu-js)
+* [Hello, gpu.js v2](https://observablehq.com/@fil/hello-gpu-js-v2)
+* [Basic gpu.js canvas example](https://observablehq.com/@rveciana/basic-gpu-js-canvas-example)
+* [Raster projection with GPU.js](https://observablehq.com/@fil/raster-projection-with-gpu-js)
+* [GPU.js Example: Slow Fade](https://observablehq.com/@robertleeplummerjr/gpu-js-example-slow-fade)
+* [GPU.JS CA Proof of Concept](https://observablehq.com/@alexlamb/gpu-js-ca-proof-of-concept)
+* [Image Convolution using GPU.js](https://observablehq.com/@ukabuer/image-convolution-using-gpu-js)
+* [Leaflet + gpu.js canvas](https://observablehq.com/@rveciana/leaflet-gpu-js-canvas)
+* [Image to GPU.js](https://observablehq.com/@fil/image-to-gpu)
+* [GPU Accelerated Heatmap using gpu.js](https://observablehq.com/@tracyhenry/gpu-accelerated-heatmap-using-gpu-js)
+* [Dijkstra’s algorithm in gpu.js](https://observablehq.com/@fil/dijkstras-algorithm-in-gpu-js)
+* [Voronoi with gpu.js](https://observablehq.com/@fil/voronoi-with-gpu-js)
+* [The gpu.js loop](https://observablehq.com/@fil/the-gpu-js-loop)
+* [GPU.js Example: Mandelbrot Set](https://observablehq.com/@robertleeplummerjr/gpu-js-example-mandelbrot-set)
+* [GPU.js Example: Mandelbulb](https://observablehq.com/@robertleeplummerjr/gpu-js-example-mandelbulb)
+* [Inverse of the distance with gpu.js](https://observablehq.com/@rveciana/inverse-of-the-distance-with-gpu-js)
+* [gpu.js laser detection v2](https://observablehq.com/@robertleeplummerjr/gpu-js-laser-detection-v2)
+* [GPU.js Canvas](https://observablehq.com/@hubgit/gpu-js-canvas)
+* [Video Convolution using GPU.js](https://observablehq.com/@robertleeplummerjr/video-convolution-using-gpu-js)
+* [GPU Rock Paper Scissors](https://observablehq.com/@alexlamb/gpu-rock-paper-scissors)
+* [Shaded relief with gpujs and d3js](https://observablehq.com/@rveciana/shaded-relief-with-gpujs-and-d3js/2)
+* [Caesar Cipher GPU.js Example](https://observablehq.com/@robertleeplummerjr/caesar-cipher-gpu-js-example)
+* [Matrix Multiplication GPU.js + Angular Example](https://ng-gpu.surge.sh/)
+* [Conway's game of life](https://observablehq.com/@brakdag/conway-game-of-life-gpu-js)
+
## Installation
+On Linux, ensure you have the correct header files installed: `sudo apt install mesa-common-dev libxi-dev` (adjust for your distribution)
### npm
@@ -71,50 +159,89 @@ yarn add gpu.js
```
[npm package](https://www.npmjs.com/package/gpu.js)
+### Node
+```js
+const { GPU } = require('gpu.js');
+const gpu = new GPU();
+```
+
+### Node Typescript **New in V2!**
+```js
+import { GPU } from 'gpu.js';
+const gpu = new GPU();
+```
### Browser
-Download the latest version of gpu.js and include the files in your HTML page using the following tags:
+Download the latest version of GPU.js and include the files in your HTML page using the following tags:
```html
-
-```
-
-In JavaScript, initialize the library:
-
-```js
-const gpu = new GPU();
+
+
```
-## Options
-Options are an object used to create a `kernel` or `kernelMap`. Example: `gpu.createKernel(options)`
-* `output`: array or object that describes the output of kernel.
+## `GPU` Settings
+Settings are an object used to create an instance of `GPU`. Example: `new GPU(settings)`
+* `canvas`: `HTMLCanvasElement`. Optional. For sharing canvas. Example: use THREE.js and GPU.js on same canvas.
+* `context`: `WebGL2RenderingContext` or `WebGLRenderingContext`. For sharing rendering context. Example: use THREE.js and GPU.js on same rendering context.
+* `mode`: Defaults to 'gpu', other values generally for debugging:
+ * 'dev' **New in V2!**: VERY IMPORTANT! Use this so you can breakpoint and debug your kernel! This wraps your javascript in loops but DOES NOT transpile your code, so debugging is much easier.
+ * 'webgl': Use the `WebGLKernel` for transpiling a kernel
+ * '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
+* `onIstanbulCoverageVariable`: Removed in v2.11.0, use v8 coverage
+* `removeIstanbulCoverage`: Removed in v2.11.0, use v8 coverage
+
+## `gpu.createKernel` Settings
+Settings are an object used to create a `kernel` or `kernelMap`. Example: `gpu.createKernel(settings)`
+* `output` or `kernel.setOutput(output)`: `array` or `object` that describes the output of kernel. When using `kernel.setOutput()` you _can_ call it after the kernel has compiled if `kernel.dynamicOutput` is `true`, to resize your output. Example:
* as array: `[width]`, `[width, height]`, or `[width, height, depth]`
* as object: `{ x: width, y: height, z: depth }`
-* outputToTexture: boolean
-* graphical: boolean
-* loopMaxIterations: number
-* constants: object
-* wraparound: boolean
-* hardcodeConstants: boolean
-* floatTextures: boolean
-* floatOutput: boolean
-* functions: array or boolean
-* nativeFunctions: object
-* subKernels: array
+* `pipeline` or `kernel.setPipeline(true)` **New in V2!**: boolean, default = `false`
+ * Causes `kernel()` calls to output a `Texture`. To get array's from a `Texture`, use:
+ ```js
+ const result = kernel();
+ result.toArray();
+ ```
+ * Can be passed _directly_ into kernels, and is preferred:
+ ```js
+ kernel(texture);
+ ```
+* `graphical` or `kernel.setGraphical(boolean)`: boolean, default = `false`
+* `loopMaxIterations` or `kernel.setLoopMaxIterations(number)`: number, default = 1000
+* `constants` or `kernel.setConstants(object)`: object, default = null
+* `dynamicOutput` or `kernel.setDynamicOutput(boolean)`: boolean, default = false - turns dynamic output on or off
+* `dynamicArguments` or `kernel.setDynamicArguments(boolean)`: boolean, default = false - turns dynamic arguments (use different size arrays and textures) on or off
+* `optimizeFloatMemory` or `kernel.setOptimizeFloatMemory(boolean)` **New in V2!**: boolean - causes a float32 texture to use all 4 channels rather than 1, using less memory, but consuming more GPU.
+* `precision` or `kernel.setPrecision('unsigned' | 'single')` **New in V2!**: 'single' or 'unsigned' - if 'single' output texture uses float32 for each colour channel rather than 8
+* `fixIntegerDivisionAccuracy` or `kernel.setFixIntegerDivisionAccuracy(boolean)` : boolean - some cards have accuracy issues dividing by factors of three and some other primes (most apple kit?). Default on for affected cards, disable if accuracy not required.
+* `functions` or `kernel.setFunctions(array)`: array, array of functions to be used inside kernel. If undefined, inherits from `GPU` instance. Can also be an array of `{ source: function, argumentTypes: object, returnType: string }`.
+* `nativeFunctions` or `kernel.setNativeFunctions(array)`: object, defined as: `{ name: string, source: string, settings: object }`. This is generally set via using GPU.addNativeFunction()
+ * VERY IMPORTANT! - Use this to add special native functions to your environment when you need specific functionality is needed.
+* `injectedNative` or `kernel.setInjectedNative(string)` **New in V2!**: string, defined as: `{ functionName: functionSource }`. This is for injecting native code before translated kernel functions.
+* `subKernels` or `kernel.setSubKernels(array)`: array, generally inherited from `GPU` instance.
+* `immutable` or `kernel.setImmutable(boolean)`: boolean, default = `false`
+ * VERY IMPORTANT! - This was removed in v2.4.0 - v2.7.0, and brought back in v2.8.0 [by popular demand](https://github.com/gpujs/gpu.js/issues/572), please upgrade to get the feature
+* `strictIntegers` or `kernel.setStrictIntegers(boolean)`: boolean, default = `false` - allows undefined argumentTypes and function return values to use strict integer declarations.
+* `useLegacyEncoder` or `kernel.setUseLegacyEncoder(boolean)`: boolean, default `false` - more info [here](https://github.com/gpujs/gpu.js/wiki/Encoder-details).
+* `tactic` or `kernel.setTactic('speed' | 'balanced' | 'precision')` **New in V2!**: Set the kernel's tactic for compilation. Allows for compilation to better fit how GPU.js is being used (internally uses `lowp` for 'speed', `mediump` for 'balanced', and `highp` for 'precision'). Default is lowest resolution supported for output.
## Creating and Running Functions
-Depending on your output type, specify the intended size of your output. You cannot have an accelerated function that does not specify any output size.
+Depending on your output type, specify the intended size of your output.
+You cannot have an accelerated function that does not specify any output size.
-Output size | How to specify output size | How to reference in kernel
------------------------|-------------------------------|--------------------------------
-1D | `[length]` | `myVar[this.thread.x]`
-2D | `[width, height]` | `myVar[this.thread.y][this.thread.x]`
-3D | `[width, height, depth]` | `myVar[this.thread.z][this.thread.y][this.thread.x]`
+Output size | How to specify output size | How to reference in kernel
+--------------|-------------------------------|--------------------------------
+ 1D | `[length]` | `value[this.thread.x]`
+ 2D | `[width, height]` | `value[this.thread.y][this.thread.x]`
+ 3D | `[width, height, depth]` | `value[this.thread.z][this.thread.y][this.thread.x]`
```js
-const opt = {
+const settings = {
output: [100]
};
```
@@ -123,7 +250,7 @@ or
```js
// You can also use x, y, and z
-const opt = {
+const settings = {
output: { x: 100 }
};
```
@@ -131,50 +258,283 @@ const opt = {
Create the function you want to run on the GPU. The first input parameter to `createKernel` is a kernel function which will compute a single number in the output. The thread identifiers, `this.thread.x`, `this.thread.y` or `this.thread.z` will allow you to specify the appropriate behavior of the kernel function at specific positions of the output.
```js
-const myFunc = gpu.createKernel(function() {
+const kernel = gpu.createKernel(function() {
return this.thread.x;
-}, opt);
+}, settings);
```
The created function is a regular JavaScript function, and you can use it like one.
```js
-myFunc();
-// Result: [0, 1, 2, 3, ... 99]
+kernel();
+// Result: Float32Array[0, 1, 2, 3, ... 99]
```
-Note: Instead of creating an object, you can use the chainable shortcut methods as a neater way of specifying options.
+Note: Instead of creating an object, you can use the chainable shortcut methods as a neater way of specifying settings.
```js
-const myFunc = gpu.createKernel(function() {
+const kernel = gpu.createKernel(function() {
return this.thread.x;
}).setOutput([100]);
-
-myFunc();
-// Result: [0, 1, 2, 3, ... 99]
+
+kernel();
+// Result: Float32Array[0, 1, 2, 3, ... 99]
+```
+
+### Declaring variables/functions within kernels
+
+GPU.js makes variable declaration inside kernel functions easy. Variable types supported are:
+* `Number` (Integer or Number), example: `let value = 1` or `let value = 1.1`
+* `Boolean`, example: `let value = true`
+* `Array(2)`, example: `let value = [1, 1]`
+* `Array(3)`, example: `let value = [1, 1, 1]`
+* `Array(4)`, example: `let value = [1, 1, 1, 1]`
+* `private Function`, example: `function myFunction(value) { return value + 1; }`
+
+`Number` kernel example:
+```js
+const kernel = gpu.createKernel(function() {
+ const i = 1;
+ const j = 0.89;
+ return i + j;
+}).setOutput([100]);
+```
+
+`Boolean` kernel example:
+```js
+const kernel = gpu.createKernel(function() {
+ const i = true;
+ if (i) return 1;
+ return 0;
+}).setOutput([100]);
+```
+
+`Array(2)` kernel examples:
+Using declaration
+```js
+const kernel = gpu.createKernel(function() {
+ const array2 = [0.08, 2];
+ return array2;
+}).setOutput([100]);
+```
+
+Directly returned
+```js
+const kernel = gpu.createKernel(function() {
+ return [0.08, 2];
+}).setOutput([100]);
+```
+
+`Array(3)` kernel example:
+Using declaration
+```js
+const kernel = gpu.createKernel(function() {
+ const array2 = [0.08, 2, 0.1];
+ return array2;
+}).setOutput([100]);
+```
+
+Directly returned
+```js
+const kernel = gpu.createKernel(function() {
+ return [0.08, 2, 0.1];
+}).setOutput([100]);
```
-## Accepting Input
-Kernel functions can accept numbers, or 1D, 2D or 3D array of numbers as input. To define an argument, simply add it to the kernel function like regular JavaScript.
+`Array(4)` kernel example:
+Using declaration
+```js
+const kernel = gpu.createKernel(function() {
+ const array2 = [0.08, 2, 0.1, 3];
+ return array2;
+}).setOutput([100]);
+```
+Directly returned
```js
-const myFunc = gpu.createKernel(function(x) {
+const kernel = gpu.createKernel(function() {
+ return [0.08, 2, 0.1, 3];
+}).setOutput([100]);
+```
+
+`private Function` kernel example:
+```js
+const kernel = gpu.createKernel(function() {
+ function myPrivateFunction() {
+ return [0.08, 2, 0.1, 3];
+ }
+
+ return myPrivateFunction(); // <-- type inherited here
+}).setOutput([100]);
+```
+
+## Debugging
+Debugging can be done in a variety of ways, and there are different levels of debugging.
+* Debugging kernels with breakpoints can be done with `new GPU({ mode: 'dev' })`
+ * This puts `GPU.js` into development mode. Here you can insert breakpoints, and be somewhat liberal in how your kernel is developed.
+ * This mode _does not_ actually "compile" (parse, and eval) a kernel, it simply iterates on your code.
+ * You can break a lot of rules here, because your kernel's function still has context of the state it came from.
+ * PLEASE NOTE: Mapped kernels are not supported in this mode. They simply cannot work because of context.
+ * Example:
+ ```js
+ const gpu = new GPU({ mode: 'dev' });
+ const kernel = gpu.createKernel(function(arg1, time) {
+ // put a breakpoint on the next line, and watch it get hit
+ const v = arg1[this.thread.y][this.thread.x * time];
+ return v;
+ }, { output: [100, 100] });
+ ```
+* Debugging actual kernels on CPU with `debugger`:
+ * This will cause "breakpoint" like behaviour, but in an actual CPU kernel. You'll peer into the compiled kernel here, for a CPU.
+ * Example:
+ ```js
+ const gpu = new GPU({ mode: 'cpu' });
+ const kernel = gpu.createKernel(function(arg1, time) {
+ debugger; // <--NOTICE THIS, IMPORTANT!
+ const v = arg1[this.thread.y][this.thread.x * time];
+ return v;
+ }, { output: [100, 100] });
+ ```
+* Debugging an actual GPU kernel:
+ * There are no breakpoints available on the GPU, period. By providing the same level of abstraction and logic, the above methods should give you enough insight to debug, but sometimes we just need to see what is on the GPU.
+ * Be VERY specific and deliberate, and use the kernel to your advantage, rather than just getting frustrated or giving up.
+ * Example:
+ ```js
+ const gpu = new GPU({ mode: 'cpu' });
+ const kernel = gpu.createKernel(function(arg1, time) {
+ const x = this.thread.x * time;
+ return x; // <--NOTICE THIS, IMPORTANT!
+ const v = arg1[this.thread.y][x];
+ return v;
+ }, { output: [100, 100] });
+ ```
+ In this example, we return early the value of x, to see exactly what it is. The rest of the logic is ignored, but now you can see the value that is calculated from `x`, and debug it.
+ This is an overly simplified problem.
+ * Sometimes you need to solve graphical problems, that can be done similarly.
+ * Example:
+ ```js
+ const gpu = new GPU({ mode: 'cpu' });
+ const kernel = gpu.createKernel(function(arg1, time) {
+ const x = this.thread.x * time;
+ if (x < 4 || x > 2) {
+ // RED
+ this.color(1, 0, 0); // <--NOTICE THIS, IMPORTANT!
+ return;
+ }
+ if (x > 6 && x < 12) {
+ // GREEN
+ this.color(0, 1, 0); // <--NOTICE THIS, IMPORTANT!
+ return;
+ }
+ const v = arg1[this.thread.y][x];
+ return v;
+ }, { output: [100, 100], graphical: true });
+ ```
+ Here we are making the canvas red or green depending on the value of `x`.
+
+## Accepting Input
+### Supported Input Types
+* Numbers
+* 1d,2d, or 3d Array of numbers
+ * Arrays of `Array`, `Float32Array`, `Int16Array`, `Int8Array`, `Uint16Array`, `uInt8Array`
+* Pre-flattened 2d or 3d Arrays using 'Input', for faster upload of arrays
+ * Example:
+ ```js
+ const { input } = require('gpu.js');
+ const value = input(flattenedArray, [width, height, depth]);
+ ```
+* HTML Image
+* Array of HTML Images
+* Video Element **New in V2!**
+To define an argument, simply add it to the kernel function like regular JavaScript.
+
+### Input Examples
+```js
+const kernel = gpu.createKernel(function(x) {
return x;
}).setOutput([100]);
-
-myFunc(42);
-// Result: [42, 42, 42, 42, ... 42]
+
+kernel(42);
+// Result: Float32Array[42, 42, 42, 42, ... 42]
```
Similarly, with array inputs:
```js
-const myFunc = gpu.createKernel(function(x) {
+const kernel = gpu.createKernel(function(x) {
return x[this.thread.x % 3];
}).setOutput([100]);
-
-myFunc([1, 2, 3]);
-// Result: [1, 2, 3, 1, ... 1 ]
+
+kernel([1, 2, 3]);
+// Result: Float32Array[1, 2, 3, 1, ... 1 ]
+```
+
+An HTML Image:
+
+```js
+const kernel = gpu.createKernel(function(image) {
+ const pixel = image[this.thread.y][this.thread.x];
+ this.color(pixel[0], pixel[1], pixel[2], pixel[3]);
+})
+ .setGraphical(true)
+ .setOutput([100, 100]);
+
+const image = document.createElement('img');
+image.src = 'my/image/source.png';
+image.onload = () => {
+ kernel(image);
+ // Result: colorful image
+
+ document.getElementsByTagName('body')[0].appendChild(kernel.canvas);
+};
+```
+
+An Array of HTML Images:
+
+```js
+const kernel = gpu.createKernel(function(image) {
+ const pixel = image[this.thread.z][this.thread.y][this.thread.x];
+ this.color(pixel[0], pixel[1], pixel[2], pixel[3]);
+})
+ .setGraphical(true)
+ .setOutput([100, 100]);
+
+const image1 = document.createElement('img');
+image1.src = 'my/image/source1.png';
+image1.onload = onload;
+const image2 = document.createElement('img');
+image2.src = 'my/image/source2.png';
+image2.onload = onload;
+const image3 = document.createElement('img');
+image3.src = 'my/image/source3.png';
+image3.onload = onload;
+const totalImages = 3;
+let loadedImages = 0;
+function onload() {
+ loadedImages++;
+ if (loadedImages === totalImages) {
+ kernel([image1, image2, image3]);
+ // Result: colorful image composed of many images
+
+ document.getElementsByTagName('body')[0].appendChild(kernel.canvas);
+ }
+};
+```
+
+An HTML Video: **New in V2!**
+
+```js
+const kernel = gpu.createKernel(function(videoFrame) {
+ const pixel = videoFrame[this.thread.y][this.thread.x];
+ this.color(pixel[0], pixel[1], pixel[2], pixel[3]);
+})
+ .setGraphical(true)
+ .setOutput([100, 100]);
+
+const video = new document.createElement('video');
+video.src = 'my/video/source.webm';
+kernel(image); //note, try and use requestAnimationFrame, and the video should be ready or playing
+// Result: video frame
```
## Graphical Output
@@ -189,30 +549,68 @@ const render = gpu.createKernel(function() {
})
.setOutput([20, 20])
.setGraphical(true);
-
+
render();
-const canvas = render.getCanvas();
+const canvas = render.canvas;
document.getElementsByTagName('body')[0].appendChild(canvas);
```
Note: To animate the rendering, use `requestAnimationFrame` instead of `setTimeout` for optimal performance. For more information, see [this](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame).
+
+### .getPixels() **New in V2!**
+To make it easier to get pixels from a context, use `kernel.getPixels()`, which returns a flat array similar to what you get from WebGL's `readPixels` method.
+A note on why: webgl's `readPixels` returns an array ordered differently from javascript's `getImageData`.
+This makes them behave similarly.
+While the values may be somewhat different, because of graphical precision available in the kernel, and alpha, this allows us to easily get pixel data in unified way.
+
+Example:
+```js
+const render = gpu.createKernel(function() {
+ this.color(0, 0, 0, 1);
+})
+ .setOutput([20, 20])
+ .setGraphical(true);
+
+render();
+const pixels = render.getPixels();
+// [r,g,b,a, r,g,b,a...
+```
+
+### Alpha
+
+Currently, if you need alpha do something like enabling `premultipliedAlpha` with your own gl context:
+```js
+const canvas = DOM.canvas(500, 500);
+const gl = canvas.getContext('webgl2', { premultipliedAlpha: false });
+
+const gpu = new GPU({
+ canvas,
+ context: gl
+});
+const krender = gpu.createKernel(function(x) {
+ this.color(this.thread.x / 500, this.thread.y / 500, x[0], x[1]);
+})
+ .setOutput([500, 500])
+ .setGraphical(true);
+ ```
+
## Combining kernels
Sometimes you want to do multiple math operations on the gpu without the round trip penalty of data transfer from cpu to gpu to cpu to gpu, etc. To aid this there is the `combineKernels` method.
_**Note:**_ Kernels can have different output sizes.
```js
const add = gpu.createKernel(function(a, b) {
- return a[this.thread.x] + b[this.thread.x];
+ return a[this.thread.x] + b[this.thread.x];
}).setOutput([20]);
const multiply = gpu.createKernel(function(a, b) {
- return a[this.thread.x] * b[this.thread.x];
+ return a[this.thread.x] * b[this.thread.x];
}).setOutput([20]);
const superKernel = gpu.combineKernels(add, multiply, function(a, b, c) {
- return multiply(add(a, b), c);
+ return multiply(add(a, b), c);
});
superKernel(a, b, c);
@@ -227,66 +625,163 @@ Sometimes you want to do multiple math operations in one kernel, and save the ou
```js
const megaKernel = gpu.createKernelMap({
addResult: function add(a, b) {
- return a[this.thread.x] + b[this.thread.x];
+ return a + b;
},
multiplyResult: function multiply(a, b) {
- return a[this.thread.x] * b[this.thread.x];
+ return a * b;
},
}, function(a, b, c) {
- return multiply(add(a, b), c);
-});
+ return multiply(add(a[this.thread.x], b[this.thread.x]), c[this.thread.x]);
+}, { output: [10] });
megaKernel(a, b, c);
-// Result: { addResult: [], multiplyResult: [], result: [] }
+// Result: { addResult: Float32Array, multiplyResult: Float32Array, result: Float32Array }
```
### array outputs
```js
const megaKernel = gpu.createKernelMap([
function add(a, b) {
- return a[this.thread.x] + b[this.thread.x];
+ return a + b;
},
function multiply(a, b) {
- return a[this.thread.x] * b[this.thread.x];
+ return a * b;
}
], function(a, b, c) {
- return multiply(add(a, b), c);
-});
+ return multiply(add(a[this.thread.x], b[this.thread.x]), c[this.thread.x]);
+}, { output: [10] });
megaKernel(a, b, c);
-// Result: [ [], [] ].result []
+// Result: { 0: Float32Array, 1: Float32Array, result: Float32Array }
```
This gives you the flexibility of using parts of a single transformation without the performance penalty, resulting in much much _MUCH_ faster operation.
## Adding custom functions
-Do you have a custom function you'd like to use on the gpu? Although limited, you can:
+### To `GPU` instance
+use `gpu.addFunction(function() {}, settings)` for adding custom functions to all kernels. Needs to be called BEFORE `gpu.createKernel`. Example:
+
+
```js
gpu.addFunction(function mySuperFunction(a, b) {
- return a - b;
+ return a - b;
});
function anotherFunction(value) {
- return value + 1;
+ return value + 1;
}
gpu.addFunction(anotherFunction);
const kernel = gpu.createKernel(function(a, b) {
- return anotherFunction(mySuperFunction(a[this.thread.x], b[this.thread.x]));
+ return anotherFunction(mySuperFunction(a[this.thread.x], b[this.thread.x]));
}).setOutput([20]);
```
+### To `Kernel` instance
+use `kernel.addFunction(function() {}, settings)` for adding custom functions to all kernels. Example:
+
+
+```js
+kernel.addFunction(function mySuperFunction(a, b) {
+ return a - b;
+});
+function anotherFunction(value) {
+ return value + 1;
+}
+kernel.addFunction(anotherFunction);
+const kernel = gpu.createKernel(function(a, b) {
+ return anotherFunction(mySuperFunction(a[this.thread.x], b[this.thread.x]));
+}).setOutput([20]);
+```
+
+### Adding strongly typed functions
+
+To manually strongly type a function you may use settings.
+By setting this value, it makes the build step of the kernel less resource intensive.
+Settings take an optional hash values:
+* `returnType`: optional, defaults to inference from `FunctionBuilder`, the value you'd like to return from the function.
+* `argumentTypes`: optional, defaults to inference from `FunctionBuilder` for each param, a hash of param names with values of the return types.
+
+Example on `GPU` instance:
+```js
+gpu.addFunction(function mySuperFunction(a, b) {
+ return [a - b[1], b[0] - a];
+}, { argumentTypes: { a: 'Number', b: 'Array(2)'}, returnType: 'Array(2)' });
+```
+
+Example on `Kernel` instance:
+```js
+kernel.addFunction(function mySuperFunction(a, b) {
+ return [a - b[1], b[0] - a];
+}, { argumentTypes: { a: 'Number', b: 'Array(2)'}, returnType: 'Array(2)' });
+```
+
+NOTE: GPU.js infers types if they are not defined and is generally able to detect the types you need, however
+'Array(2)', 'Array(3)', and 'Array(4)' are exceptions, at least on the kernel level. Also, it is nice to have power
+over the automatic type inference system.
+
## Adding custom functions directly to kernel
```js
function mySuperFunction(a, b) {
- return a - b;
+ return a - b;
}
const kernel = gpu.createKernel(function(a, b) {
- return mySuperFunction(a[this.thread.x], b[this.thread.x]);
+ return mySuperFunction(a[this.thread.x], b[this.thread.x]);
})
.setOutput([20])
.setFunctions([mySuperFunction]);
```
+
+## Types
+GPU.js does type inference when types are not defined, so even if you code weak type, you are typing strongly typed.
+This is needed because c++, which glsl is a subset of, is, of course, strongly typed.
+Types that can be used with GPU.js are as follows:
+
+### Argument Types
+* 'Array'
+* 'Array(2)' **New in V2!**
+* 'Array(3)' **New in V2!**
+* 'Array(4)' **New in V2!**
+* 'Array1D(2)' **New in V2!**
+* 'Array1D(3)' **New in V2!**
+* 'Array1D(4)' **New in V2!**
+* 'Array2D(2)' **New in V2!**
+* 'Array2D(3)' **New in V2!**
+* 'Array2D(4)' **New in V2!**
+* 'Array3D(2)' **New in V2!**
+* 'Array3D(3)' **New in V2!**
+* 'Array3D(4)' **New in V2!**
+* 'HTMLCanvas' **New in V2.6**
+* 'OffscreenCanvas' **New in V2.13**
+* 'HTMLImage'
+* 'ImageBitmap' **New in V2.14**
+* 'ImageData' **New in V2.15**
+* 'HTMLImageArray'
+* 'HTMLVideo' **New in V2!**
+* 'Number'
+* 'Float'
+* 'Integer'
+* 'Boolean' **New in V2!**
+
+### Return Types
+NOTE: These refer the the return type of the kernel function, the actual result will always be a collection in the size of the defined `output`
+* 'Array(2)'
+* 'Array(3)'
+* 'Array(4)'
+* 'Number'
+* 'Float'
+* 'Integer'
+
+### Internal Types
+Types generally used in the `Texture` class, for #pipelining or for advanced usage.
+* 'ArrayTexture(1)' **New in V2!**
+* 'ArrayTexture(2)' **New in V2!**
+* 'ArrayTexture(3)' **New in V2!**
+* 'ArrayTexture(4)' **New in V2!**
+* 'NumberTexture'
+* 'MemoryOptimizedNumberTexture' **New in V2!**
+
## Loops
-Loops just work
+* Any loops defined inside the kernel must have a maximum iteration count defined by the loopMaxIterations setting.
+* Other than defining the iterations by a constant or fixed value as shown [Dynamic sized via constants](dynamic-sized-via-constants), you can also simply pass the number of iterations as a variable to the kernel
### Dynamic sized via constants
```js
@@ -315,24 +810,185 @@ const matMult = gpu.createKernel(function(a, b) {
## Pipelining
[Pipeline](https://en.wikipedia.org/wiki/Pipeline_(computing)) is a feature where values are sent directly from kernel to kernel via a texture.
-This results in extremely fast computing. This is achieved with the kernel option `outputToTexture: boolean` option or by calling `kernel.setOutputToTexture(true)`
+This results in extremely fast computing. This is achieved with the kernel setting `pipeline: boolean` or by calling `kernel.setPipeline(true)`
+In an effort to make the CPU and GPU work similarly, pipeline on CPU and GPU modes causes the kernel result to be reused when `immutable: false` (which is default).
+If you'd like to keep kernel results around, use `immutable: true` and ensure you cleanup memory:
+* In gpu mode using `texture.delete()` when appropriate.
+* In cpu mode allowing values to go out of context
+
+### Cloning Textures **New in V2!**
+When using pipeline mode the outputs from kernels can be cloned using `texture.clone()`.
+
+```js
+const kernel1 = gpu.createKernel(function(v) {
+ return v[this.thread.x];
+})
+ .setPipeline(true)
+ .setOutput([100]);
+const kernel2 = gpu.createKernel(function(v) {
+ return v[this.thread.x];
+})
+ .setOutput([100]);
+
+const result1 = kernel1(array);
+// Result: Texture
+console.log(result1.toArray());
+// Result: Float32Array[0, 1, 2, 3, ... 99]
+
+const result2 = kernel2(result1);
+// Result: Float32Array[0, 1, 2, 3, ... 99]
+```
+
+### Cleanup pipeline texture memory **New in V2.4!**
+When using `kernel.immutable = true` recycling GPU memory is handled internally, but a good practice is to clean up memory you no longer need it.
+Cleanup kernel outputs by using `texture.delete()` to keep GPU memory as small as possible.
+
+NOTE: Internally textures will only release from memory if there are no references to them.
+When using pipeline mode on a kernel `K` the output for each call will be a newly allocated texture `T`.
+If, after getting texture `T` as an output, `T.delete()` is called, the next call to K will reuse `T` as its output texture.
+
+Alternatively, if you'd like to clear out a `texture` and yet keep it in memory, you may use `texture.clear()`, which
+will cause the `texture` to persist in memory, but its internal values to become all zeros.
+
+## Offscreen Canvas
+GPU.js supports offscreen canvas where available. Here is an example of how to use it with two files, `gpu-worker.js`, and `index.js`:
+
+file: `gpu-worker.js`
+```js
+importScripts('path/to/gpu.js');
+onmessage = function() {
+ // define gpu instance
+ const gpu = new GPU();
+
+ // input values
+ const a = [1,2,3];
+ const b = [3,2,1];
+
+ // setup kernel
+ const kernel = gpu.createKernel(function(a, b) {
+ return a[this.thread.x] - b[this.thread.x];
+ })
+ .setOutput([3]);
+
+ // output some results!
+ postMessage(kernel(a, b));
+};
+```
+
+file: `index.js`
+```js
+var worker = new Worker('gpu-worker.js');
+worker.onmessage = function(e) {
+ var result = e.data;
+ console.log(result);
+};
+```
+
+## Cleanup
+* for instances of `GPU` use the `destroy` method. Example: `gpu.destroy()`
+* for instances of `Kernel` use the `destroy` method. Example: `kernel.destroy()`
+* for instances of `Texture` use the `delete` method. Example: `texture.delete()`
+* for instances of `Texture` that you might want to reuse/reset to zeros, use the `clear` method. Example: `texture.clear()`
## Flattened typed array support
-To use the useful `x`, `y`, `z` `thread` lookup api inside of gpu.js, and yet use flattened arrays, there is the `Input` type.
+To use the useful `x`, `y`, `z` `thread` lookup api inside of GPU.js, and yet use flattened arrays, there is the `Input` type.
This is generally much faster for when sending values to the gpu, especially with larger data sets. Usage example:
```js
-import GPU, { input } from 'gpu.js';
+const { GPU, input, Input } = require('gpu.js');
const gpu = new GPU();
const kernel = gpu.createKernel(function(a, b) {
return a[this.thread.y][this.thread.x] + b[this.thread.y][this.thread.x];
}).setOutput([3,3]);
-kernel(input(new Float32Array([1,2,3,4,5,6,7,8,9]), [3, 3]), input(new Float32Array([1,2,3,4,5,6,7,8,9]), [3, 3]));
+kernel(
+ input(
+ new Float32Array([1,2,3,4,5,6,7,8,9]),
+ [3, 3]
+ ),
+ input(
+ new Float32Array([1,2,3,4,5,6,7,8,9]),
+ [3, 3]
+ )
+);
+```
+
+Note: `input(value, size)` is a simple pointer for `new Input(value, size)`
+
+## Precompiled and Lighter Weight Kernels
+
+### using JSON
+GPU.js packs a lot of functionality into a single file, such as a complete javascript parse, which may not be needed in some cases.
+To aid in keeping your kernels lightweight, the `kernel.toJSON()` method was added.
+This allows you to reuse a previously built kernel, without the need to re-parse the javascript.
+Here is an example:
+
+```js
+const gpu = new GPU();
+const kernel = gpu.createKernel(function() {
+ return [1,2,3,4];
+}, { output: [1] });
+console.log(kernel()); // [Float32Array([1,2,3,4])];
+const json = kernel.toJSON();
+const newKernelFromJson = gpu.createKernel(json);
+console.log(newKernelFromJSON()); // [Float32Array([1,2,3,4])];
```
-Note: `GPU.input(value, size)` is a simple pointer for `new GPU.Input(value, size)`
+NOTE: There is lighter weight, pre-built, version of GPU.js to assist with serializing from to and from json in the dist folder of the project, which include:
+* [dist/gpu-browser-core.js](dist/gpu-browser-core.js)
+* [dist/gpu-browser-core.min.js](dist/gpu-browser-core.min.js)
+
+### Exporting kernel
+GPU.js supports seeing exactly how it is interacting with the graphics processor by means of the `kernel.toString(...)` method.
+This method, when called, creates a kernel that executes _exactly the instruction set given to the GPU (or CPU)_ *as a
+very tiny reusable function* that instantiates a kernel.
+
+NOTE: When exporting a kernel and using `constants` the following constants are *not changeable*:
+* `Array(2)`
+* `Array(3)`
+* `Array(4)`
+* `Integer`
+* `Number`
+* `Float`
+* `Boolean`
+
+Here is an example used to/from file:
+```js
+import { GPU } from 'gpu.js';
+import * as fs from 'fs';
+const gpu = new GPU();
+const kernel = gpu.createKernel(function(v) {
+ return this.thread.x + v + this.constants.v1;
+}, { output: [10], constants: { v1: 100 } });
+const result = kernel(1);
+const kernelString = kernel.toString(1);
+fs.writeFileSync('./my-exported-kernel.js', 'module.exports = ' + kernelString);
+import * as MyExportedKernel from './my-exported-kernel';
+import gl from 'gl';
+const myExportedKernel = MyExportedKernel({ context: gl(1,1), constants: { v1: 100 } });
+```
+
+
+Here is an example for just-in-time function creation:
+
+```js
+const gpu = new GPU();
+const kernel = gpu.createKernel(function(a) {
+ let sum = 0;
+ for (let i = 0; i < 6; i++) {
+ sum += a[this.thread.x][i];
+ }
+ return sum;
+ }, { output: [6] });
+kernel(input(a, [6, 6]));
+const kernelString = kernel.toString(input(a, [6, 6]));
+const newKernel = new Function('return ' + kernelString)()({ context });
+newKernel(input(a, [6, 6]));
+```
+
+#### using constants with `kernel.toString(...args)`
+You can assign _some_ new constants when using the function output from `.toString()`,
## Supported Math functions
@@ -340,81 +996,243 @@ Since the code running in the kernel is actually compiled to GLSL code, not all
This is a list of the supported ones:
+* `Math.abs()`
+* `Math.acos()`
+* `Math.acosh()`
+* `Math.asin()`
+* `Math.asinh()`
+* `Math.atan()`
+* `Math.atanh()`
+* `Math.atan2()`
+* `Math.cbrt()`
+* `Math.ceil()`
+* `Math.cos()`
+* `Math.cosh()`
+* `Math.exp()`
+* `Math.expm1()`
+* `Math.floor()`
+* `Math.fround()`
+* `Math.imul()`
+* `Math.log()`
+* `Math.log10()`
+* `Math.log1p()`
+* `Math.log2()`
+* `Math.max()`
+* `Math.min()`
+* `Math.pow()`
+* `Math.random()`
+ * A note on random. We use [a plugin](src/plugins/math-random-uniformly-distributed.js) to generate random.
+ Random seeded _and_ generated, _both from the GPU_, is not as good as random from the CPU as there are more things that the CPU can seed random from.
+ However, we seed random on the GPU, _from a random value in the CPU_.
+ We then seed the subsequent randoms from the previous random value.
+ So we seed from CPU, and generate from GPU.
+ Which is still not as good as CPU, but closer.
+ While this isn't perfect, it should suffice in most scenarios.
+ In any case, we must give thanks to [RandomPower](https://www.randompower.eu/), and this [issue](https://github.com/gpujs/gpu.js/issues/498), for assisting in improving our implementation of random.
+* `Math.round()`
+* `Math.sign()`
+* `Math.sin()`
+* `Math.sinh()`
+* `Math.sqrt()`
+* `Math.tan()`
+* `Math.tanh()`
+* `Math.trunc()`
+
+This is a list and reasons of unsupported ones:
+* `Math.clz32` - bits directly are hard
+* `Math.hypot` - dynamically sized
+
+## How to check what is supported
+
+To assist with mostly unit tests, but perhaps in scenarios outside of GPU.js, there are the following logical checks to determine what support level the system executing a GPU.js kernel may have:
+* `GPU.disableValidation()` - turn off all kernel validation
+* `GPU.enableValidation()` - turn on all kernel validation
+* `GPU.isGPUSupported`: `boolean` - checks if GPU is in-fact supported
+* `GPU.isKernelMapSupported`: `boolean` - checks if kernel maps are supported
+* `GPU.isOffscreenCanvasSupported`: `boolean` - checks if offscreen canvas is supported
+* `GPU.isWebGLSupported`: `boolean` - checks if WebGL v1 is supported
+* `GPU.isWebGL2Supported`: `boolean` - checks if WebGL v2 is supported
+* `GPU.isHeadlessGLSupported`: `boolean` - checks if headlessgl is supported
+* `GPU.isCanvasSupported`: `boolean` - checks if canvas is supported
+* `GPU.isGPUHTMLImageArraySupported`: `boolean` - checks if the platform supports HTMLImageArray's
+* `GPU.isSinglePrecisionSupported`: `boolean` - checks if the system supports single precision float 32 values
+
+## Typescript Typings
+Typescript is supported! Typings can be found [here](src/index.d.ts)!
+For strongly typed kernels:
+```typescript
+import { GPU, IKernelFunctionThis } from 'gpu.js';
+const gpu = new GPU();
+
+function kernelFunction(this: IKernelFunctionThis): number {
+ return 1 + this.thread.x;
+}
+
+const kernelMap = gpu.createKernel(kernelFunction)
+ .setOutput([3,3,3]);
+
+const result = kernelMap();
+
+console.log(result as number[][][]);
```
-abs
-acos
-asin
-atan
-atan2
-ceil
-cos
-exp
-floor
-log
-log2
-max
-min
-round
-sign
-sin
-sqrt
-tan
+
+For strongly typed mapped kernels:
+```typescript
+import { GPU, Texture, IKernelFunctionThis } from 'gpu.js';
+const gpu = new GPU();
+
+function kernelFunction(this: IKernelFunctionThis): [number, number] {
+ return [1, 1];
+}
+
+function subKernel(): [number, number] {
+ return [1, 1];
+}
+
+const kernelMap = gpu.createKernelMap({
+ test: subKernel,
+}, kernelFunction)
+ .setOutput([1])
+ .setPipeline(true);
+
+const result = kernelMap();
+
+console.log((result.test as Texture).toArray() as [number, number][]);
```
+For extending constants:
+```typescript
+import { GPU, IKernelFunctionThis } from 'gpu.js';
+const gpu = new GPU();
+
+interface IConstants {
+ screen: [number, number];
+}
+
+type This = {
+ constants: IConstants
+} & IKernelFunctionThis;
+
+function kernelFunction(this: This): number {
+ const { screen } = this.constants;
+ return 1 + screen[0];
+}
+
+const kernelMap = gpu.createKernel(kernelFunction)
+ .setOutput([3,3,3])
+ .setConstants({
+ screen: [1, 1]
+ });
+
+const result = kernelMap();
+
+console.log(result as number[][][]);
+```
+
+[Click here](/examples) for more typescript examples.
+
+## Destructured Assignments **New in V2!**
+Destructured Objects and Arrays work in GPU.js.
+* Object destructuring
+ ```js
+ const gpu = new GPU();
+ const kernel = gpu.createKernel(function() {
+ const { thread: {x, y} } = this;
+ return x + y;
+ }, { output: [2] });
+ console.log(kernel());
+ ```
+* Array destructuring
+ ```js
+ const gpu = new GPU();
+ const kernel = gpu.createKernel(function(array) {
+ const [first, second] = array;
+ return first + second;
+ }, {
+ output: [2],
+ argumentTypes: { array: 'Array(2)' }
+ });
+ console.log(kernel([1, 2]));
+ ```
+
+## Dealing With Transpilation
+Transpilation doesn't do the best job of keeping code beautiful. To aid in this endeavor GPU.js can handle some scenarios to still aid you harnessing the GPU in less than ideal circumstances.
+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.
## Full API Reference
-You can find a [complete API reference here](http://gpu.rocks/api/).
+You can find a [complete API reference here](https://doxdox.org/gpujs/gpu.js/).
+
+## How possible in node?
+GPU.js uses [HeadlessGL](https://github.com/stackgl/headless-gl) in node for GPU acceleration.
+GPU.js is written in such a way, you can introduce your own backend. Have a suggestion? We'd love to hear it!
+
+## Terms Explained
+* Kernel - A function that is tightly coupled to program that runs on the Graphic Processor
+* Texture - A graphical artifact that is packed with data, in the case of GPU.js, bit shifted parts of a 32 bit floating point decimal
+
+## Testing
+Testing is done (right now) manually, (help wanted [here](https://github.com/gpujs/gpu.js/issues/515) if you can!), using the following:
+* For browser, setup a webserver on the root of the gpu.js project and visit http://url/test/all.html
+* For node, run either of the 3 commands:
+ * `yarn test test/features`
+ * `yarn test test/internal`
+ * `yarn test test/issues`
-## Automatically-built Documentation
+## Building
+Building isn't required on node, but is for browser. To build the browser's files, run: `yarn make`
-Documentation of the codebase is [automatically built](https://github.com/gpujs/gpu.js/wiki/Automatic-Documentation).
+# Get Involved!
-## Contributors
-
-* Fazli Sapuan
-* Eugene Cheah
-* Matthew Saw
-* Robert Plummer
-* Abhishek Soni
-* Juan Cazala
-* Daniel X Moore
-* Mark Theng
-* Varun Patro
-
## Contributing
-
+
Contributors are welcome! Create a merge request to the `develop` branch and we
will gladly review it. If you wish to get write access to the repository,
please email us and we will review your application and grant you access to
the `develop` branch.
-
+
We promise never to pass off your code as ours.
-## Terms Explained
-* Kernel - A function that is tightly coupled to program that runs on the Graphic Processor
-* Texture - A graphical artifact that is packed with data, in the case of GPU.js, bit shifted parts of a 32 bit floating point decimal
+### Issues
+
+If you have an issue, either a bug or a feature you think would benefit your project let us know and we will do our best.
+
+Create issues [here](https://github.com/gpujs/gpu.js/issues) and follow the template.
+
+### Contributors
+
+This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
+
+
+
+### Backers
+
+Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/gpujs#backer)]
+
+
+
+
+### Sponsors
+
+Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/gpujs#sponsor)]
+
+
+Sponsored NodeJS GPU environment from [LeaderGPU](https://www.leadergpu.com) - These guys rock!
+
+
+Sponsored Browser GPU environment's from [BrowserStack](https://browserstack.com) - Second to none!
+
+
+
+
+
+
+
+
+
+
+
-## License
-
-The MIT License
-
-Copyright (c) 2017 gpu.js Team
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
+## [License](LICENSE)
diff --git a/bin/gpu-core.js b/bin/gpu-core.js
deleted file mode 100644
index 5bd72930..00000000
--- a/bin/gpu-core.js
+++ /dev/null
@@ -1,209 +0,0 @@
-/**
- * gpu.js
- * http://gpu.rocks/
- *
- * GPU Accelerated JavaScript
- *
- * @version 1.0.0-rc.7
- * @date Sat Nov 11 2017 08:38:09 GMT-0500 (EST)
- *
- * @license MIT
- * The MIT License
- *
- * Copyright (c) 2017 gpu.js Team
- */
-"use strict";(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) {
- retArr.push(', ');
- }
-
- retArr.push(' ');
- retArr.push('user_');
- retArr.push(paramName);
- }
-
- retArr.push(') {\n');
- }
-
- for (var _i = 0; _i < ast.body.body.length; ++_i) {
- this.astGeneric(ast.body.body[_i], retArr, funcParam);
- retArr.push('\n');
- }
-
- if (!funcParam.isRootKernel) {
- retArr.push('}\n');
- }
- return retArr;
- }
-
-
- }, {
- key: 'astReturnStatement',
- value: function astReturnStatement(ast, retArr, funcParam) {
- if (funcParam.isRootKernel) {
- retArr.push('kernelResult = ');
- this.astGeneric(ast.argument, retArr, funcParam);
- retArr.push(';');
- } else if (funcParam.isSubKernel) {
- retArr.push(funcParam.functionName + 'Result = ');
- this.astGeneric(ast.argument, retArr, funcParam);
- retArr.push(';');
- retArr.push('return ' + funcParam.functionName + 'Result;');
- } else {
- retArr.push('return ');
- this.astGeneric(ast.argument, retArr, funcParam);
- retArr.push(';');
- }
-
-
- return retArr;
- }
-
-
- }, {
- key: 'astLiteral',
- value: function astLiteral(ast, retArr, funcParam) {
-
- if (isNaN(ast.value)) {
- throw this.astErrorOutput('Non-numeric literal not supported : ' + ast.value, ast, funcParam);
- }
-
- retArr.push(ast.value);
-
- return retArr;
- }
-
-
- }, {
- key: 'astBinaryExpression',
- value: function astBinaryExpression(ast, retArr, funcParam) {
- retArr.push('(');
- this.astGeneric(ast.left, retArr, funcParam);
- retArr.push(ast.operator);
- this.astGeneric(ast.right, retArr, funcParam);
- retArr.push(')');
- return retArr;
- }
-
-
- }, {
- key: 'astIdentifierExpression',
- value: function astIdentifierExpression(idtNode, retArr, funcParam) {
- if (idtNode.type !== 'Identifier') {
- throw this.astErrorOutput('IdentifierExpression - not an Identifier', ast, funcParam);
- }
-
- switch (idtNode.name) {
- case 'gpu_threadX':
- retArr.push('threadId.x');
- break;
- case 'gpu_threadY':
- retArr.push('threadId.y');
- break;
- case 'gpu_threadZ':
- retArr.push('threadId.z');
- break;
- case 'gpu_outputX':
- retArr.push('uOutputDim.x');
- break;
- case 'gpu_outputY':
- retArr.push('uOutputDim.y');
- break;
- case 'gpu_outputZ':
- retArr.push('uOutputDim.z');
- break;
- default:
- if (this.constants && this.constants.hasOwnProperty(idtNode.name)) {
- retArr.push('constants_' + idtNode.name);
- } else {
- var userParamName = funcParam.getUserParamName(idtNode.name);
- if (userParamName !== null) {
- retArr.push('user_' + userParamName);
- } else {
- retArr.push('user_' + idtNode.name);
- }
- }
- }
-
- return retArr;
- }
-
-
- }, {
- key: 'astForStatement',
- value: function astForStatement(forNode, retArr, funcParam) {
- if (forNode.type !== 'ForStatement') {
- throw this.astErrorOutput('Invalid for statment', ast, funcParam);
- }
-
- if (forNode.test && forNode.test.type === 'BinaryExpression') {
- if ((forNode.test.right.type === 'Identifier' || forNode.test.right.type === 'Literal') && forNode.test.operator === '<' && this.isIdentifierConstant(forNode.test.right.name) === false) {
-
- if (!this.loopMaxIterations) {
- console.warn('Warning: loopMaxIterations is not set! Using default of 1000 which may result in unintended behavior.');
- console.warn('Set loopMaxIterations or use a for loop of fixed length to silence this message.');
- }
-
- retArr.push('for (');
- this.astGeneric(forNode.init, retArr, funcParam);
- if (retArr[retArr.length - 1] !== ';') {
- retArr.push(';');
- }
- this.astGeneric(forNode.test.left, retArr, funcParam);
- retArr.push(forNode.test.operator);
- retArr.push('LOOP_MAX');
- retArr.push(';');
- this.astGeneric(forNode.update, retArr, funcParam);
- retArr.push(')');
-
- retArr.push('{\n');
- retArr.push('if (');
- this.astGeneric(forNode.test.left, retArr, funcParam);
- retArr.push(forNode.test.operator);
- this.astGeneric(forNode.test.right, retArr, funcParam);
- retArr.push(') {\n');
- if (forNode.body.type === 'BlockStatement') {
- for (var i = 0; i < forNode.body.body.length; i++) {
- this.astGeneric(forNode.body.body[i], retArr, funcParam);
- }
- } else {
- this.astGeneric(forNode.body, retArr, funcParam);
- }
- retArr.push('} else {\n');
- retArr.push('break;\n');
- retArr.push('}\n');
- retArr.push('}\n');
-
- return retArr;
- } else if (forNode.init.declarations) {
- var declarations = JSON.parse(JSON.stringify(forNode.init.declarations));
- var updateArgument = forNode.update.argument;
- if (!Array.isArray(declarations) || declarations.length < 1) {
- console.log(this.jsFunctionString);
- throw new Error('Error: Incompatible for loop declaration');
- }
-
- if (declarations.length > 1) {
- var initArgument = null;
- for (var _i2 = 0; _i2 < declarations.length; _i2++) {
- var declaration = declarations[_i2];
- if (declaration.id.name === updateArgument.name) {
- initArgument = declaration;
- declarations.splice(_i2, 1);
- } else {
- retArr.push('var ');
- this.astGeneric(declaration, retArr, funcParam);
- retArr.push(';');
- }
- }
-
- retArr.push('for (let ');
- this.astGeneric(initArgument, retArr, funcParam);
- retArr.push(';');
- } else {
- retArr.push('for (');
- this.astGeneric(forNode.init, retArr, funcParam);
- }
-
- this.astGeneric(forNode.test, retArr, funcParam);
- retArr.push(';');
- this.astGeneric(forNode.update, retArr, funcParam);
- retArr.push(')');
- this.astGeneric(forNode.body, retArr, funcParam);
- return retArr;
- }
- }
-
- throw this.astErrorOutput('Invalid for statement', forNode, funcParam);
- }
-
-
- }, {
- key: 'astWhileStatement',
- value: function astWhileStatement(whileNode, retArr, funcParam) {
- if (whileNode.type !== 'WhileStatement') {
- throw this.astErrorOutput('Invalid while statment', ast, funcParam);
- }
-
- retArr.push('for (let i = 0; i < LOOP_MAX; i++) {');
- retArr.push('if (');
- this.astGeneric(whileNode.test, retArr, funcParam);
- retArr.push(') {\n');
- this.astGeneric(whileNode.body, retArr, funcParam);
- retArr.push('} else {\n');
- retArr.push('break;\n');
- retArr.push('}\n');
- retArr.push('}\n');
-
- return retArr;
- }
-
-
- }, {
- key: 'astAssignmentExpression',
- value: function astAssignmentExpression(assNode, retArr, funcParam) {
- this.astGeneric(assNode.left, retArr, funcParam);
- retArr.push(assNode.operator);
- this.astGeneric(assNode.right, retArr, funcParam);
- return retArr;
- }
-
-
- }, {
- key: 'astEmptyStatement',
- value: function astEmptyStatement(eNode, retArr, funcParam) {
- return retArr;
- }
-
-
- }, {
- key: 'astBlockStatement',
- value: function astBlockStatement(bNode, retArr, funcParam) {
- retArr.push('{\n');
- for (var i = 0; i < bNode.body.length; i++) {
- this.astGeneric(bNode.body[i], retArr, funcParam);
- }
- retArr.push('}\n');
- return retArr;
- }
-
-
- }, {
- key: 'astExpressionStatement',
- value: function astExpressionStatement(esNode, retArr, funcParam) {
- this.astGeneric(esNode.expression, retArr, funcParam);
- retArr.push(';\n');
- return retArr;
- }
-
-
- }, {
- key: 'astVariableDeclaration',
- value: function astVariableDeclaration(vardecNode, retArr, funcParam) {
- retArr.push('var ');
- for (var i = 0; i < vardecNode.declarations.length; i++) {
- if (i > 0) {
- retArr.push(',');
- }
- this.astGeneric(vardecNode.declarations[i], retArr, funcParam);
- }
- retArr.push(';');
- return retArr;
- }
-
-
- }, {
- key: 'astVariableDeclarator',
- value: function astVariableDeclarator(ivardecNode, retArr, funcParam) {
- this.astGeneric(ivardecNode.id, retArr, funcParam);
- if (ivardecNode.init !== null) {
- retArr.push('=');
- this.astGeneric(ivardecNode.init, retArr, funcParam);
- }
- return retArr;
- }
-
-
- }, {
- key: 'astIfStatement',
- value: function astIfStatement(ifNode, retArr, funcParam) {
- retArr.push('if (');
- this.astGeneric(ifNode.test, retArr, funcParam);
- retArr.push(')');
- if (ifNode.consequent.type === 'BlockStatement') {
- this.astGeneric(ifNode.consequent, retArr, funcParam);
- } else {
- retArr.push(' {\n');
- this.astGeneric(ifNode.consequent, retArr, funcParam);
- retArr.push('\n}\n');
- }
-
- if (ifNode.alternate) {
- retArr.push('else ');
- if (ifNode.alternate.type === 'BlockStatement') {
- this.astGeneric(ifNode.alternate, retArr, funcParam);
- } else {
- retArr.push(' {\n');
- this.astGeneric(ifNode.alternate, retArr, funcParam);
- retArr.push('\n}\n');
- }
- }
- return retArr;
- }
-
-
- }, {
- key: 'astBreakStatement',
- value: function astBreakStatement(brNode, retArr, funcParam) {
- retArr.push('break;\n');
- return retArr;
- }
-
-
- }, {
- key: 'astContinueStatement',
- value: function astContinueStatement(crNode, retArr, funcParam) {
- retArr.push('continue;\n');
- return retArr;
- }
-
-
- }, {
- key: 'astLogicalExpression',
- value: function astLogicalExpression(logNode, retArr, funcParam) {
- retArr.push('(');
- this.astGeneric(logNode.left, retArr, funcParam);
- retArr.push(logNode.operator);
- this.astGeneric(logNode.right, retArr, funcParam);
- retArr.push(')');
- return retArr;
- }
-
-
- }, {
- key: 'astUpdateExpression',
- value: function astUpdateExpression(uNode, retArr, funcParam) {
- if (uNode.prefix) {
- retArr.push(uNode.operator);
- this.astGeneric(uNode.argument, retArr, funcParam);
- } else {
- this.astGeneric(uNode.argument, retArr, funcParam);
- retArr.push(uNode.operator);
- }
-
- return retArr;
- }
-
-
- }, {
- key: 'astUnaryExpression',
- value: function astUnaryExpression(uNode, retArr, funcParam) {
- if (uNode.prefix) {
- retArr.push(uNode.operator);
- this.astGeneric(uNode.argument, retArr, funcParam);
- } else {
- this.astGeneric(uNode.argument, retArr, funcParam);
- retArr.push(uNode.operator);
- }
-
- return retArr;
- }
-
-
- }, {
- key: 'astThisExpression',
- value: function astThisExpression(tNode, retArr, funcParam) {
- retArr.push('_this');
- return retArr;
- }
-
-
- }, {
- key: 'astMemberExpression',
- value: function astMemberExpression(mNode, retArr, funcParam) {
- if (mNode.computed) {
- if (mNode.object.type === 'Identifier') {
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push('[');
- this.astGeneric(mNode.property, retArr, funcParam);
- retArr.push(']');
- } else {
- this.astGeneric(mNode.object, retArr, funcParam);
- var last = retArr.pop();
- retArr.push('][');
- this.astGeneric(mNode.property, retArr, funcParam);
- retArr.push(last);
- }
- } else {
- var unrolled = this.astMemberExpressionUnroll(mNode);
- if (mNode.property.type === 'Identifier' && mNode.computed) {
- unrolled = 'user_' + unrolled;
- }
-
- if (unrolled.indexOf('this') === 0) {
- unrolled = '_' + unrolled;
- }
-
- switch (unrolled) {
- case '_this.output.x':
- retArr.push(this.output[0]);
- break;
- case '_this.output.y':
- retArr.push(this.output[1]);
- break;
- case '_this.output.z':
- retArr.push(this.output[2]);
- break;
- default:
- retArr.push(unrolled);
- }
- }
- return retArr;
- }
- }, {
- key: 'astSequenceExpression',
- value: function astSequenceExpression(sNode, retArr, funcParam) {
- for (var i = 0; i < sNode.expressions.length; i++) {
- if (i > 0) {
- retArr.push(',');
- }
- this.astGeneric(sNode.expressions, retArr, funcParam);
- }
- return retArr;
- }
-
-
- }, {
- key: 'astCallExpression',
- value: function astCallExpression(ast, retArr, funcParam) {
- if (ast.callee) {
- var funcName = this.astMemberExpressionUnroll(ast.callee);
-
- if (funcParam.calledFunctions.indexOf(funcName) < 0) {
- funcParam.calledFunctions.push(funcName);
- }
- if (!funcParam.hasOwnProperty('funcName')) {
- funcParam.calledFunctionsArguments[funcName] = [];
- }
-
- var functionArguments = [];
- funcParam.calledFunctionsArguments[funcName].push(functionArguments);
-
- retArr.push(funcName);
-
- retArr.push('(');
-
- for (var i = 0; i < ast.arguments.length; ++i) {
- var argument = ast.arguments[i];
- if (i > 0) {
- retArr.push(', ');
- }
- this.astGeneric(argument, retArr, funcParam);
- if (argument.type === 'Identifier') {
- var paramIndex = funcParam.paramNames.indexOf(argument.name);
- if (paramIndex === -1) {
- functionArguments.push(null);
- } else {
- functionArguments.push({
- name: argument.name,
- type: funcParam.paramTypes[paramIndex]
- });
- }
- } else {
- functionArguments.push(null);
- }
- }
-
- retArr.push(')');
-
- return retArr;
- }
-
- throw this.astErrorOutput('Unknown CallExpression', ast, funcParam);
-
- return retArr;
- }
-
-
- }, {
- key: 'astArrayExpression',
- value: function astArrayExpression(arrNode, retArr, funcParam) {
- var arrLen = arrNode.elements.length;
-
- retArr.push('new Float32Array(');
- for (var i = 0; i < arrLen; ++i) {
- if (i > 0) {
- retArr.push(', ');
- }
- var subNode = arrNode.elements[i];
- this.astGeneric(subNode, retArr, funcParam);
- }
- retArr.push(')');
-
- return retArr;
-
- }
- }, {
- key: 'astDebuggerStatement',
- value: function astDebuggerStatement(arrNode, retArr, funcParam) {
- retArr.push('debugger;');
- return retArr;
- }
- }], [{
- key: 'astFunctionPrototype',
- value: function astFunctionPrototype(ast, retArr, funcParam) {
- if (funcParam.isRootKernel || funcParam.isSubKernel) {
- return retArr;
- }
-
- retArr.push(funcParam.returnType);
- retArr.push(' ');
- retArr.push(funcParam.functionName);
- retArr.push('(');
-
- for (var i = 0; i < funcParam.paramNames.length; ++i) {
- if (i > 0) {
- retArr.push(', ');
- }
-
- retArr.push(funcParam.paramTypes[i]);
- retArr.push(' ');
- retArr.push('user_');
- retArr.push(funcParam.paramNames[i]);
- }
-
- retArr.push(');\n');
-
- return retArr;
- }
- }]);
-
- return CPUFunctionNode;
-}(BaseFunctionNode);
-},{"../../core/utils":25,"../function-node-base":7}],3:[function(require,module,exports){
-'use strict';
-
-var utils = require('../../core/utils');
-var kernelRunShortcut = require('../kernel-run-shortcut');
-
-module.exports = function (cpuKernel, name) {
- return '() => {\n ' + kernelRunShortcut.toString() + ';\n const utils = {\n allPropertiesOf: function ' + utils.allPropertiesOf.toString() + ',\n clone: function ' + utils.clone.toString() + ',\n /*splitArray: function ' + utils.splitArray.toString() + ',\n getArgumentType: function ' + utils.getArgumentType.toString() + ',\n getOutput: function ' + utils.getOutput.toString() + ',\n dimToTexSize: function ' + utils.dimToTexSize.toString() + ',\n copyFlatten: function ' + utils.copyFlatten.toString() + ',\n flatten: function ' + utils.flatten.toString() + ',\n systemEndianness: \'' + utils.systemEndianness() + '\',\n initWebGl: function ' + utils.initWebGl.toString() + ',\n isArray: function ' + utils.isArray.toString() + '*/\n };\n class ' + (name || 'Kernel') + ' {\n constructor() { \n this.argumentsLength = 0;\n this._canvas = null;\n this._webGl = null;\n this.built = false;\n this.program = null;\n this.paramNames = ' + JSON.stringify(cpuKernel.paramNames) + ';\n this.paramTypes = ' + JSON.stringify(cpuKernel.paramTypes) + ';\n this.texSize = ' + JSON.stringify(cpuKernel.texSize) + ';\n this.output = ' + JSON.stringify(cpuKernel.output) + ';\n this._kernelString = `' + cpuKernel._kernelString + '`;\n this.output = ' + JSON.stringify(cpuKernel.output) + ';\n\t\t this.run = function() {\n this.run = null;\n this.build();\n return this.run.apply(this, arguments);\n }.bind(this);\n this.thread = {\n x: 0,\n y: 0,\n z: 0\n };\n }\n setCanvas(canvas) { this._canvas = canvas; return this; }\n setWebGl(webGl) { this._webGl = webGl; return this; }\n ' + cpuKernel.build.toString() + '\n run () { ' + cpuKernel.kernelString + ' }\n getKernelString() { return this._kernelString; }\n };\n return kernelRunShortcut(new Kernel());\n };';
-};
-},{"../../core/utils":25,"../kernel-run-shortcut":9}],4:[function(require,module,exports){
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var KernelBase = require('../kernel-base');
-var utils = require('../../core/utils');
-var kernelString = require('./kernel-string');
-
-module.exports = function (_KernelBase) {
- _inherits(CPUKernel, _KernelBase);
-
- function CPUKernel(fnString, settings) {
- _classCallCheck(this, CPUKernel);
-
- var _this = _possibleConstructorReturn(this, (CPUKernel.__proto__ || Object.getPrototypeOf(CPUKernel)).call(this, fnString, settings));
-
- _this._fnBody = utils.getFunctionBodyFromString(fnString);
- _this._fn = null;
- _this.run = null;
- _this._canvasCtx = null;
- _this._imageData = null;
- _this._colorData = null;
- _this._kernelString = null;
- _this.thread = {
- x: 0,
- y: 0,
- z: 0
- };
-
- _this.run = function () {
- this.run = null;
- this.build.apply(this, arguments);
- return this.run.apply(this, arguments);
- }.bind(_this);
- return _this;
- }
-
-
-
- _createClass(CPUKernel, [{
- key: 'validateOptions',
- value: function validateOptions() {
- if (!this.output || this.output.length === 0) {
- if (arguments.length !== 1) {
- throw 'Auto dimensions only supported for kernels with only one input';
- }
-
- var argType = utils.getArgumentType(arguments[0]);
- if (argType === 'Array') {
- this.output = utils.getDimensions(argType);
- } else if (argType === 'Texture') {
- this.output = arguments[0].output;
- } else {
- throw 'Auto dimensions not supported for input type: ' + argType;
- }
- }
- }
-
-
- }, {
- key: 'build',
- value: function build() {
- this.setupParams(arguments);
- var threadDim = this.threadDim = utils.clone(this.output);
-
- while (threadDim.length < 3) {
- threadDim.push(1);
- }
-
- if (this.graphical) {
- var canvas = this.getCanvas();
- canvas.width = threadDim[0];
- canvas.height = threadDim[1];
- this._canvasCtx = canvas.getContext('2d');
- this._imageData = this._canvasCtx.createImageData(threadDim[0], threadDim[1]);
- this._colorData = new Uint8ClampedArray(threadDim[0] * threadDim[1] * 4);
- }
-
- var kernelString = this.getKernelString();
-
- if (this.debug) {
- console.log('Options:');
- console.dir(this);
- console.log('Function output:');
- console.log(kernelString);
- }
-
- this.kernelString = kernelString;
- this.run = new Function([], kernelString).bind(this)();
- }
- }, {
- key: 'color',
- value: function color(r, g, b, a) {
- if (typeof a === 'undefined') {
- a = 1;
- }
-
- r = Math.floor(r * 255);
- g = Math.floor(g * 255);
- b = Math.floor(b * 255);
- a = Math.floor(a * 255);
-
- var width = this.output[0];
- var height = this.output[1];
-
- var x = this.thread.x;
- var y = height - this.thread.y - 1;
-
- var index = x + y * width;
-
- this._colorData[index * 4 + 0] = r;
- this._colorData[index * 4 + 1] = g;
- this._colorData[index * 4 + 2] = b;
- this._colorData[index * 4 + 3] = a;
- }
-
-
- }, {
- key: 'getKernelString',
- value: function getKernelString() {
- var _this2 = this;
-
- if (this._kernelString !== null) return this._kernelString;
-
- var builder = this.functionBuilder;
-
- var threadDim = this.threadDim || (this.threadDim = utils.clone(this.output));
- while (threadDim.length < 3) {
- threadDim.push(1);
- }
-
- builder.addKernel(this.fnString, {
- prototypeOnly: false,
- constants: this.constants,
- output: this.output,
- debug: this.debug,
- loopMaxIterations: this.loopMaxIterations
- }, this.paramNames, this.paramTypes);
-
- builder.addFunctions(this.functions, {
- constants: this.constants,
- output: this.output
- });
-
- if (this.subKernels !== null) {
- this.subKernelOutputTextures = [];
- this.subKernelOutputVariableNames = [];
- for (var i = 0; i < this.subKernels.length; i++) {
- var subKernel = this.subKernels[i];
- builder.addSubKernel(subKernel, {
- prototypeOnly: false,
- constants: this.constants,
- output: this.output,
- debug: this.debug,
- loopMaxIterations: this.loopMaxIterations
- });
- this.subKernelOutputVariableNames.push(subKernel.name + 'Result');
- }
- } else if (this.subKernelProperties !== null) {
- this.subKernelOutputVariableNames = [];
- var _i = 0;
- for (var p in this.subKernelProperties) {
- if (!this.subKernelProperties.hasOwnProperty(p)) continue;
- var _subKernel = this.subKernelProperties[p];
- builder.addSubKernel(_subKernel);
- this.subKernelOutputVariableNames.push(_subKernel.name + 'Result');
- _i++;
- }
- }
-
- var prototypes = builder.getPrototypes();
- var kernel = prototypes.shift();
- var kernelString = this._kernelString = '\n\t\tvar LOOP_MAX = ' + this._getLoopMaxString() + ';\n\t\tvar _this = this;\n ' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) {
- return ' var ' + name + ' = null;\n';
- }).join('')) + '\n return function (' + this.paramNames.map(function (paramName) {
- return 'user_' + paramName;
- }).join(', ') + ') {\n var ret = new Array(' + threadDim[2] + ');\n ' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) {
- return ' ' + name + 'Z = new Array(' + threadDim[2] + ');\n';
- }).join('')) + '\n for (this.thread.z = 0; this.thread.z < ' + threadDim[2] + '; this.thread.z++) {\n ret[this.thread.z] = new Array(' + threadDim[1] + ');\n ' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) {
- return ' ' + name + 'Z[this.thread.z] = new Array(' + threadDim[1] + ');\n';
- }).join('')) + '\n for (this.thread.y = 0; this.thread.y < ' + threadDim[1] + '; this.thread.y++) {\n ret[this.thread.z][this.thread.y] = new Array(' + threadDim[0] + ');\n ' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) {
- return ' ' + name + 'Z[this.thread.z][this.thread.y] = new Array(' + threadDim[0] + ');\n';
- }).join('')) + '\n for (this.thread.x = 0; this.thread.x < ' + threadDim[0] + '; this.thread.x++) {\n var kernelResult;\n ' + kernel + '\n ret[this.thread.z][this.thread.y][this.thread.x] = kernelResult;\n' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) {
- return ' ' + name + 'Z[this.thread.z][this.thread.y][this.thread.x] = ' + name + ';\n';
- }).join('')) + '\n }\n }\n }\n \n if (this.graphical) {\n this._imageData.data.set(this._colorData);\n this._canvasCtx.putImageData(this._imageData, 0, 0);\n return;\n }\n \n if (this.output.length === 1) {\n ret = ret[0][0];\n' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) {
- return ' ' + name + ' = ' + name + 'Z[0][0];\n';
- }).join('')) + '\n \n } else if (this.output.length === 2) {\n ret = ret[0];\n ' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) {
- return ' ' + name + ' = ' + name + 'Z[0];\n';
- }).join('')) + '\n }\n \n ' + (this.subKernelOutputVariableNames === null ? 'return ret;\n' : this.subKernels !== null ? 'var result = [\n ' + this.subKernelOutputVariableNames.map(function (name) {
- return '' + name;
- }).join(',\n') + '\n ];\n result.result = ret;\n return result;\n' : 'return {\n result: ret,\n ' + Object.keys(this.subKernelProperties).map(function (name, i) {
- return name + ': ' + _this2.subKernelOutputVariableNames[i];
- }).join(',\n') + '\n };') + '\n ' + (prototypes.length > 0 ? prototypes.join('\n') : '') + '\n }.bind(this);';
- return kernelString;
- }
-
-
- }, {
- key: 'toString',
- value: function toString() {
- return kernelString(this);
- }
-
-
- }, {
- key: 'precompileKernelObj',
- value: function precompileKernelObj(argTypes) {
-
- var threadDim = this.threadDim || (this.threadDim = utils.clone(this.output));
-
- return {
- threadDim: threadDim
- };
- }
-
-
- }, {
- key: '_getLoopMaxString',
-
-
- value: function _getLoopMaxString() {
- return this.loopMaxIterations ? ' ' + parseInt(this.loopMaxIterations) + ';\n' : ' 1000;\n';
- }
- }], [{
- key: 'compileKernel',
- value: function compileKernel(precompileObj) {
-
- var threadDim = precompileObj.threadDim;
-
- while (threadDim.length < 3) {
- threadDim.push(1);
- }
- }
- }]);
-
- return CPUKernel;
-}(KernelBase);
-},{"../../core/utils":25,"../kernel-base":8,"./kernel-string":3}],5:[function(require,module,exports){
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var utils = require('../../core/utils');
-var RunnerBase = require('../runner-base');
-var CPUKernel = require('./kernel');
-var CPUFunctionBuilder = require('./function-builder');
-
-module.exports = function (_RunnerBase) {
- _inherits(CPURunner, _RunnerBase);
-
-
- function CPURunner(settings) {
- _classCallCheck(this, CPURunner);
-
- var _this = _possibleConstructorReturn(this, (CPURunner.__proto__ || Object.getPrototypeOf(CPURunner)).call(this, new CPUFunctionBuilder(), settings));
-
- _this.Kernel = CPUKernel;
- _this.kernel = null;
- return _this;
- }
-
-
-
- _createClass(CPURunner, [{
- key: 'getMode',
- value: function getMode() {
- return 'cpu';
- }
- }]);
-
- return CPURunner;
-}(RunnerBase);
-},{"../../core/utils":25,"../runner-base":10,"./function-builder":1,"./kernel":4}],6:[function(require,module,exports){
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-module.exports = function () {
-
- function FunctionBuilderBase(gpu) {
- _classCallCheck(this, FunctionBuilderBase);
-
- this.nodeMap = {};
- this.nativeFunctions = {};
- this.gpu = gpu;
- this.rootKernel = null;
- this.Node = null;
- }
-
- _createClass(FunctionBuilderBase, [{
- key: 'addNativeFunction',
- value: function addNativeFunction(functionName, glslFunctionString) {
- this.nativeFunctions[functionName] = glslFunctionString;
- }
-
-
- }, {
- key: 'addFunction',
- value: function addFunction(functionName, jsFunction, options, paramTypes, returnType) {
- this.addFunctionNode(new this.Node(functionName, jsFunction, options, paramTypes, returnType).setAddFunction(this.addFunction.bind(this)));
- }
- }, {
- key: 'addFunctions',
- value: function addFunctions(functions, options) {
- if (functions) {
- if (Array.isArray(functions)) {
- for (var i = 0; i < functions.length; i++) {
- this.addFunction(null, functions[i], options);
- }
- } else {
- for (var p in functions) {
- this.addFunction(p, functions[p], options);
- }
- }
- }
- }
- }, {
- key: 'addNativeFunctions',
- value: function addNativeFunctions(nativeFunctions) {
- for (var functionName in nativeFunctions) {
- if (!nativeFunctions.hasOwnProperty(functionName)) continue;
- this.addNativeFunction(functionName, nativeFunctions[functionName]);
- }
- }
-
-
- }, {
- key: 'addFunctionNode',
- value: function addFunctionNode(inNode) {
- this.nodeMap[inNode.functionName] = inNode;
- if (inNode.isRootKernel) {
- this.rootKernel = inNode;
- }
- }
-
-
- }, {
- key: 'traceFunctionCalls',
- value: function traceFunctionCalls(functionName, retList, parent) {
- functionName = functionName || 'kernel';
- retList = retList || [];
-
- var fNode = this.nodeMap[functionName];
- if (fNode) {
- var functionIndex = retList.indexOf(functionName);
- if (functionIndex === -1) {
- retList.push(functionName);
- if (parent) {
- fNode.parent = parent;
- }
- fNode.getFunctionString();
- for (var i = 0; i < fNode.calledFunctions.length; ++i) {
- this.traceFunctionCalls(fNode.calledFunctions[i], retList, fNode);
- }
- } else {
- var dependantFunctionName = retList.splice(functionIndex, 1)[0];
- retList.push(dependantFunctionName);
- }
- }
-
- if (this.nativeFunctions[functionName]) {
- if (retList.indexOf(functionName) >= 0) {
- } else {
- retList.push(functionName);
- }
- }
-
- return retList;
- }
-
-
- }, {
- key: 'addKernel',
- value: function addKernel(fnString, options, paramNames, paramTypes) {
- var kernelNode = new this.Node('kernel', fnString, options, paramTypes);
- kernelNode.setAddFunction(this.addFunction.bind(this));
- kernelNode.paramNames = paramNames;
- kernelNode.paramTypes = paramTypes;
- kernelNode.isRootKernel = true;
- this.addFunctionNode(kernelNode);
- return kernelNode;
- }
-
-
- }, {
- key: 'addSubKernel',
- value: function addSubKernel(jsFunction, options, paramTypes, returnType) {
- var kernelNode = new this.Node(null, jsFunction, options, paramTypes, returnType);
- kernelNode.setAddFunction(this.addFunction.bind(this));
- kernelNode.isSubKernel = true;
- this.addFunctionNode(kernelNode);
- return kernelNode;
- }
-
-
- }, {
- key: 'getPrototypeString',
- value: function getPrototypeString(functionName) {
- return this.getPrototypes(functionName).join('\n');
- }
-
-
- }, {
- key: 'getPrototypes',
- value: function getPrototypes(functionName) {
- this.rootKernel.generate();
- if (functionName) {
- return this.getPrototypesFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse());
- }
- return this.getPrototypesFromFunctionNames(Object.keys(this.nodeMap));
- }
-
-
- }, {
- key: 'getStringFromFunctionNames',
- value: function getStringFromFunctionNames(functionList) {
- var ret = [];
- for (var i = 0; i < functionList.length; ++i) {
- var node = this.nodeMap[functionList[i]];
- if (node) {
- ret.push(this.nodeMap[functionList[i]].getFunctionString());
- }
- }
- return ret.join('\n');
- }
-
-
- }, {
- key: 'getPrototypesFromFunctionNames',
- value: function getPrototypesFromFunctionNames(functionList, opt) {
- var ret = [];
- for (var i = 0; i < functionList.length; ++i) {
- var functionName = functionList[i];
- var node = this.nodeMap[functionName];
- if (node) {
- ret.push(node.getFunctionPrototypeString(opt));
- } else if (this.nativeFunctions[functionName]) {
- ret.push(this.nativeFunctions[functionName]);
- }
- }
- return ret;
- }
-
-
- }, {
- key: 'getPrototypeStringFromFunctionNames',
- value: function getPrototypeStringFromFunctionNames(functionList, opt) {
- return this.getPrototypesFromFunctionNames(functionList, opt).toString();
- }
-
-
- }, {
- key: 'getString',
- value: function getString(functionName, opt) {
- if (opt === undefined) {
- opt = {};
- }
-
- if (functionName) {
- return this.getStringFromFunctionNames(this.traceFunctionCalls(functionName, [], opt).reverse(), opt);
- }
- return this.getStringFromFunctionNames(Object.keys(this.nodeMap), opt);
- }
- }, {
- key: 'polyfillStandardFunctions',
- value: function polyfillStandardFunctions() {
- throw new Error('polyfillStandardFunctions not defined on base function builder');
- }
- }]);
-
- return FunctionBuilderBase;
-}();
-},{}],7:[function(require,module,exports){
-'use strict';
-
-var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var utils = require('../core/utils');
-var acorn = require('acorn');
-
-module.exports = function () {
-
- function BaseFunctionNode(functionName, jsFunction, options, paramTypes, returnType) {
- _classCallCheck(this, BaseFunctionNode);
-
- this.calledFunctions = [];
- this.calledFunctionsArguments = {};
- this.initVariables = [];
- this.readVariables = [];
- this.writeVariables = [];
- this.addFunction = null;
- this.isRootKernel = false;
- this.isSubKernel = false;
- this.parent = null;
- this.debug = null;
- this.prototypeOnly = null;
- this.constants = null;
- this.output = null;
-
- if (options) {
- if (options.hasOwnProperty('debug')) {
- this.debug = options.debug;
- }
- if (options.hasOwnProperty('prototypeOnly')) {
- this.prototypeOnly = options.prototypeOnly;
- }
- if (options.hasOwnProperty('constants')) {
- this.constants = options.constants;
- }
- if (options.hasOwnProperty('output')) {
- this.output = options.output;
- }
- if (options.hasOwnProperty('loopMaxIterations')) {
- this.loopMaxIterations = options.loopMaxIterations;
- }
- }
-
- if (!jsFunction) {
- throw 'jsFunction, parameter is missing';
- }
-
- this.jsFunctionString = jsFunction.toString();
- if (!utils.isFunctionString(this.jsFunctionString)) {
- console.error('jsFunction, to string conversion check failed: not a function?', this.jsFunctionString);
- throw 'jsFunction, to string conversion check failed: not a function?';
- }
-
- if (!utils.isFunction(jsFunction)) {
- this.jsFunction = null;
- } else {
- this.jsFunction = jsFunction;
- }
-
- this.functionName = functionName || jsFunction && jsFunction.name || utils.getFunctionNameFromString(this.jsFunctionString);
-
- if (!this.functionName) {
- throw 'jsFunction, missing name argument or value';
- }
-
- this.paramNames = utils.getParamNamesFromString(this.jsFunctionString);
- if (paramTypes) {
- if (Array.isArray(paramTypes)) {
- if (paramTypes.length !== this.paramNames.length) {
- throw 'Invalid argument type array length, against function length -> (' + paramTypes.length + ',' + this.paramNames.length + ')';
- }
- this.paramTypes = paramTypes;
- } else if ((typeof paramTypes === 'undefined' ? 'undefined' : _typeof(paramTypes)) === 'object') {
- var paramVariableNames = Object.keys(paramTypes);
- if (paramTypes.hasOwnProperty('returns')) {
- this.returnType = paramTypes.returns;
- paramVariableNames.splice(paramVariableNames.indexOf('returns'), 1);
- }
- if (paramVariableNames.length > 0 && paramVariableNames.length !== this.paramNames.length) {
- throw 'Invalid argument type array length, against function length -> (' + paramVariableNames.length + ',' + this.paramNames.length + ')';
- } else {
- this.paramTypes = this.paramNames.map(function (key) {
- if (paramTypes.hasOwnProperty(key)) {
- return paramTypes[key];
- } else {
- return 'float';
- }
- });
- }
- }
- } else {
- this.paramTypes = [];
- }
-
- if (!this.returnType) {
- this.returnType = returnType || 'float';
- }
- }
-
- _createClass(BaseFunctionNode, [{
- key: 'isIdentifierConstant',
- value: function isIdentifierConstant(paramName) {
- if (!this.constants) return false;
- return this.constants.hasOwnProperty(paramName);
- }
- }, {
- key: 'setAddFunction',
- value: function setAddFunction(fn) {
- this.addFunction = fn;
- return this;
- }
-
-
- }, {
- key: 'getJsFunction',
- value: function getJsFunction() {
- if (this.jsFunction) {
- return this.jsFunction;
- }
-
- if (this.jsFunctionString) {
- this.jsFunction = eval(this.jsFunctionString);
- return this.jsFunction;
- }
-
- throw 'Missing jsFunction, and jsFunctionString parameter';
- }
-
-
- }, {
- key: 'astMemberExpressionUnroll',
- value: function astMemberExpressionUnroll(ast, funcParam) {
- if (ast.type === 'Identifier') {
- return ast.name;
- } else if (ast.type === 'ThisExpression') {
- return 'this';
- }
-
- if (ast.type === 'MemberExpression') {
- if (ast.object && ast.property) {
- if (ast.object.hasOwnProperty('name') && ast.object.name[0] === '_') {
- return this.astMemberExpressionUnroll(ast.property, funcParam);
- }
-
- return this.astMemberExpressionUnroll(ast.object, funcParam) + '.' + this.astMemberExpressionUnroll(ast.property, funcParam);
- }
- }
-
- if (ast.hasOwnProperty('expressions')) {
- var firstExpression = ast.expressions[0];
- if (firstExpression.type === 'Literal' && firstExpression.value === 0 && ast.expressions.length === 2) {
- return this.astMemberExpressionUnroll(ast.expressions[1]);
- }
- }
-
- throw this.astErrorOutput('Unknown CallExpression_unroll', ast, funcParam);
- }
-
-
- }, {
- key: 'getJsAST',
- value: function getJsAST(inParser) {
- if (this.jsFunctionAST) {
- return this.jsFunctionAST;
- }
-
- inParser = inParser || acorn;
- if (inParser === null) {
- throw 'Missing JS to AST parser';
- }
-
- var ast = inParser.parse('var ' + this.functionName + ' = ' + this.jsFunctionString + ';', {
- locations: true
- });
- if (ast === null) {
- throw 'Failed to parse JS code';
- }
-
- var funcAST = ast.body[0].declarations[0].init;
- this.jsFunctionAST = funcAST;
-
- return funcAST;
- }
-
-
- }, {
- key: 'getFunctionString',
- value: function getFunctionString() {
- this.generate();
- return this.functionString;
- }
-
-
- }, {
- key: 'setFunctionString',
- value: function setFunctionString(functionString) {
- this.functionString = functionString;
- }
-
-
- }, {
- key: 'getParamType',
- value: function getParamType(paramName) {
- var paramIndex = this.paramNames.indexOf(paramName);
- if (paramIndex === -1) return null;
- if (!this.parent) return null;
- if (this.paramTypes[paramIndex]) return this.paramTypes[paramIndex];
- var calledFunctionArguments = this.parent.calledFunctionsArguments[this.functionName];
- for (var i = 0; i < calledFunctionArguments.length; i++) {
- var calledFunctionArgument = calledFunctionArguments[i];
- if (calledFunctionArgument[paramIndex] !== null) {
- return this.paramTypes[paramIndex] = calledFunctionArgument[paramIndex].type;
- }
- }
- return null;
- }
-
-
- }, {
- key: 'getUserParamName',
- value: function getUserParamName(paramName) {
- var paramIndex = this.paramNames.indexOf(paramName);
- if (paramIndex === -1) return null;
- if (!this.parent) return null;
- var calledFunctionArguments = this.parent.calledFunctionsArguments[this.functionName];
- for (var i = 0; i < calledFunctionArguments.length; i++) {
- var calledFunctionArgument = calledFunctionArguments[i];
- if (calledFunctionArgument[paramIndex] !== null) {
- return calledFunctionArgument[paramIndex].name;
- }
- }
- return null;
- }
- }, {
- key: 'generate',
- value: function generate(options) {
- throw new Error('generate not defined on BaseFunctionNode');
- }
-
-
- }, {
- key: 'astErrorOutput',
- value: function astErrorOutput(error, ast, funcParam) {
- console.error(utils.getAstString(this.jsFunctionString, ast));
- console.error(error, ast, funcParam);
- return error;
- }
- }, {
- key: 'astDebuggerStatement',
- value: function astDebuggerStatement(arrNode, retArr, funcParam) {
- return retArr;
- }
- }]);
-
- return BaseFunctionNode;
-}();
-},{"../core/utils":25,"acorn":27}],8:[function(require,module,exports){
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var utils = require('../core/utils');
-
-module.exports = function () {
-
- function BaseKernel(fnString, settings) {
- _classCallCheck(this, BaseKernel);
-
- this.paramNames = utils.getParamNamesFromString(fnString);
- this.fnString = fnString;
- this.output = null;
- this.debug = false;
- this.graphical = false;
- this.loopMaxIterations = 0;
- this.constants = null;
- this.wraparound = null;
- this.hardcodeConstants = null;
- this.outputToTexture = null;
- this.texSize = null;
- this._canvas = null;
- this._webGl = null;
- this.threadDim = null;
- this.floatTextures = null;
- this.floatOutput = null;
- this.floatOutputForce = null;
- this.addFunction = null;
- this.functions = null;
- this.nativeFunctions = null;
- this.copyData = true;
- this.subKernels = null;
- this.subKernelProperties = null;
- this.subKernelNames = null;
- this.subKernelOutputVariableNames = null;
- this.functionBuilder = null;
- this.paramTypes = null;
-
- for (var p in settings) {
- if (!settings.hasOwnProperty(p) || !this.hasOwnProperty(p)) continue;
- this[p] = settings[p];
- }
- if (settings.hasOwnProperty('canvas')) {
- this._canvas = settings.canvas;
- }
- if (settings.hasOwnProperty('output')) {
- this.setOutput(settings.output);
- }
-
- if (!this._canvas) this._canvas = utils.initCanvas();
- }
-
- _createClass(BaseKernel, [{
- key: 'build',
- value: function build() {
- throw new Error('"build" not defined on Base');
- }
-
-
- }, {
- key: 'setupParams',
- value: function setupParams(args) {
- var paramTypes = this.paramTypes = [];
- for (var i = 0; i < args.length; i++) {
- var param = args[i];
- var paramType = utils.getArgumentType(param);
- paramTypes.push(paramType);
- }
- }
- }, {
- key: 'setAddFunction',
- value: function setAddFunction(cb) {
- this.addFunction = cb;
- return this;
- }
- }, {
- key: 'setFunctions',
- value: function setFunctions(functions) {
- this.functions = functions;
- return this;
- }
-
-
- }, {
- key: 'setOutput',
- value: function setOutput(output) {
- if (output.hasOwnProperty('x')) {
- if (output.hasOwnProperty('y')) {
- if (output.hasOwnProperty('z')) {
- this.output = [output.x, output.y, output.z];
- } else {
- this.output = [output.x, output.y];
- }
- } else {
- this.output = [output.x];
- }
- } else {
- this.output = output;
- }
- return this;
- }
-
-
- }, {
- key: 'setDebug',
- value: function setDebug(flag) {
- this.debug = flag;
- return this;
- }
-
-
- }, {
- key: 'setGraphical',
- value: function setGraphical(flag) {
- this.graphical = flag;
- return this;
- }
-
-
- }, {
- key: 'setLoopMaxIterations',
- value: function setLoopMaxIterations(max) {
- this.loopMaxIterations = max;
- return this;
- }
-
-
- }, {
- key: 'setConstants',
- value: function setConstants(constants) {
- this.constants = constants;
- return this;
- }
- }, {
- key: 'setWraparound',
- value: function setWraparound(flag) {
- console.warn('Wraparound mode is not supported and undocumented.');
- this.wraparound = flag;
- return this;
- }
- }, {
- key: 'setHardcodeConstants',
- value: function setHardcodeConstants(flag) {
- this.hardcodeConstants = flag;
- return this;
- }
- }, {
- key: 'setOutputToTexture',
- value: function setOutputToTexture(flag) {
- this.outputToTexture = flag;
- return this;
- }
-
-
- }, {
- key: 'setFloatTextures',
- value: function setFloatTextures(flag) {
- this.floatTextures = flag;
- return this;
- }
-
-
- }, {
- key: 'setFloatOutput',
- value: function setFloatOutput(flag) {
- this.floatOutput = flag;
- return this;
- }
- }, {
- key: 'setFloatOutputForce',
- value: function setFloatOutputForce(flag) {
- this.floatOutputForce = flag;
- return this;
- }
-
-
- }, {
- key: 'setCanvas',
- value: function setCanvas(canvas) {
- this._canvas = canvas;
- return this;
- }
-
-
- }, {
- key: 'setWebGl',
- value: function setWebGl(webGl) {
- this._webGl = webGl;
- return this;
- }
- }, {
- key: 'setCopyData',
- value: function setCopyData(copyData) {
- this.copyData = copyData;
- return this;
- }
-
-
- }, {
- key: 'getCanvas',
- value: function getCanvas() {
- return this._canvas;
- }
-
-
- }, {
- key: 'getWebGl',
- value: function getWebGl() {
- return this._webGl;
- }
- }, {
- key: 'validateOptions',
- value: function validateOptions() {
- throw new Error('validateOptions not defined');
- }
- }, {
- key: 'exec',
- value: function exec() {
- return this.execute.apply(this, arguments);
- }
- }, {
- key: 'execute',
- value: function execute() {
- var _this = this;
-
- var args = arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments);
-
- return utils.newPromise(function (accept, reject) {
- try {
- accept(_this.run.apply(_this, args));
- } catch (e) {
- reject(e);
- }
- });
- }
-
-
- }, {
- key: 'addSubKernel',
- value: function addSubKernel(fnString) {
- if (this.subKernels === null) {
- this.subKernels = [];
- this.subKernelNames = [];
- }
- this.subKernels.push(fnString);
- this.subKernelNames.push(utils.getFunctionNameFromString(fnString));
- return this;
- }
-
-
- }, {
- key: 'addSubKernelProperty',
- value: function addSubKernelProperty(property, fnString) {
- if (this.subKernelProperties === null) {
- this.subKernelProperties = {};
- this.subKernelNames = [];
- }
- if (this.subKernelProperties.hasOwnProperty(property)) {
- throw new Error('cannot add sub kernel ' + property + ', already defined');
- }
- this.subKernelProperties[property] = fnString;
- this.subKernelNames.push(utils.getFunctionNameFromString(fnString));
- return this;
- }
- }, {
- key: 'addNativeFunction',
- value: function addNativeFunction(name, source) {
- this.functionBuilder.addNativeFunction(name, source);
- }
- }]);
-
- return BaseKernel;
-}();
-},{"../core/utils":25}],9:[function(require,module,exports){
-'use strict';
-
-var utils = require('../core/utils');
-
-module.exports = function kernelRunShortcut(kernel) {
- var shortcut = function shortcut() {
- return kernel.run.apply(kernel, arguments);
- };
-
- utils.allPropertiesOf(kernel).forEach(function (key) {
- if (key[0] === '_' && key[1] === '_') return;
- if (typeof kernel[key] === 'function') {
- if (key.substring(0, 3) === 'add' || key.substring(0, 3) === 'set') {
- shortcut[key] = function () {
- kernel[key].apply(kernel, arguments);
- return shortcut;
- };
- } else {
- shortcut[key] = kernel[key].bind(kernel);
- }
- } else {
- shortcut.__defineGetter__(key, function () {
- return kernel[key];
- });
- shortcut.__defineSetter__(key, function (value) {
- kernel[key] = value;
- });
- }
- });
-
- shortcut.kernel = kernel;
-
- return shortcut;
-};
-},{"../core/utils":25}],10:[function(require,module,exports){
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var utils = require('../core/utils');
-var kernelRunShortcut = require('./kernel-run-shortcut');
-
-module.exports = function () {
-
-
- function BaseRunner(functionBuilder, settings) {
- _classCallCheck(this, BaseRunner);
-
- settings = settings || {};
- this.kernel = settings.kernel;
- this.canvas = settings.canvas;
- this.webGl = settings.webGl;
- this.fn = null;
- this.functionBuilder = functionBuilder;
- this.fnString = null;
- this.endianness = utils.systemEndianness();
- this.functionBuilder.polyfillStandardFunctions();
- }
-
-
-
- _createClass(BaseRunner, [{
- key: 'textureToArray',
- value: function textureToArray(texture) {
- var copy = this.createKernel(function (x) {
- return x[this.thread.z][this.thread.y][this.thread.x];
- });
-
- return copy(texture);
- }
-
-
- }, {
- key: 'deleteTexture',
- value: function deleteTexture(texture) {
- this.webGl.deleteTexture(texture.texture);
- }
-
-
- }, {
- key: 'buildPromiseKernel',
- value: function buildPromiseKernel() {
- throw new Error('not yet implemented');
- }
- }, {
- key: 'getMode',
- value: function getMode() {
- throw new Error('"mode" not implemented on BaseRunner');
- }
-
-
- }, {
- key: 'buildKernel',
- value: function buildKernel(fn, settings) {
- settings = Object.assign({}, settings || {});
- var fnString = fn.toString();
- if (!settings.functionBuilder) {
- settings.functionBuilder = this.functionBuilder;
- }
-
- if (!settings.canvas) {
- settings.canvas = this.canvas;
- }
-
- if (!settings.webGl) {
- settings.webGl = this.webgl;
- }
-
- return kernelRunShortcut(new this.Kernel(fnString, settings));
- }
- }]);
-
- return BaseRunner;
-}();
-},{"../core/utils":25,"./kernel-run-shortcut":9}],11:[function(require,module,exports){
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var FunctionBuilderBase = require('../function-builder-base');
-var WebGLFunctionNode = require('./function-node');
-
-module.exports = function (_FunctionBuilderBase) {
- _inherits(WebGLFunctionBuilder, _FunctionBuilderBase);
-
- function WebGLFunctionBuilder() {
- _classCallCheck(this, WebGLFunctionBuilder);
-
- var _this = _possibleConstructorReturn(this, (WebGLFunctionBuilder.__proto__ || Object.getPrototypeOf(WebGLFunctionBuilder)).call(this));
-
- _this.Node = WebGLFunctionNode;
- return _this;
- }
-
-
-
-
- _createClass(WebGLFunctionBuilder, [{
- key: 'polyfillStandardFunctions',
-
-
- value: function polyfillStandardFunctions() {
- this.addFunction('round', _round);
- }
- }], [{
- key: 'round',
- value: function round(a) {
- return _round(a);
- }
- }]);
-
- return WebGLFunctionBuilder;
-}(FunctionBuilderBase);
-
-function _round(a) {
- return Math.floor(a + 0.5);
-}
-},{"../function-builder-base":6,"./function-node":12}],12:[function(require,module,exports){
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var FunctionNodeBase = require('../function-node-base');
-var utils = require('../../core/utils');
-var jsMathPrefix = 'Math.';
-var localPrefix = 'this.';
-var constantsPrefix = 'this.constants.';
-
-var DECODE32_ENCODE32 = /decode32\(\s+encode32\(/g;
-var ENCODE32_DECODE32 = /encode32\(\s+decode32\(/g;
-
-module.exports = function (_FunctionNodeBase) {
- _inherits(WebGLFunctionNode, _FunctionNodeBase);
-
- function WebGLFunctionNode() {
- _classCallCheck(this, WebGLFunctionNode);
-
- return _possibleConstructorReturn(this, (WebGLFunctionNode.__proto__ || Object.getPrototypeOf(WebGLFunctionNode)).apply(this, arguments));
- }
-
- _createClass(WebGLFunctionNode, [{
- key: 'generate',
- value: function generate() {
- if (this.debug) {
- console.log(this);
- }
- if (this.prototypeOnly) {
- return WebGLFunctionNode.astFunctionPrototype(this.getJsAST(), [], this).join('').trim();
- } else {
- this.functionStringArray = this.astGeneric(this.getJsAST(), [], this);
- }
- this.functionString = webGlRegexOptimize(this.functionStringArray.join('').trim());
- return this.functionString;
- }
-
-
- }, {
- key: 'astGeneric',
- value: function astGeneric(ast, retArr, funcParam) {
- if (ast === null) {
- throw this.astErrorOutput('NULL ast', ast, funcParam);
- } else {
- if (Array.isArray(ast)) {
- for (var i = 0; i < ast.length; i++) {
- this.astGeneric(ast[i], retArr, funcParam);
- }
- return retArr;
- }
-
- switch (ast.type) {
- case 'FunctionDeclaration':
- return this.astFunctionDeclaration(ast, retArr, funcParam);
- case 'FunctionExpression':
- return this.astFunctionExpression(ast, retArr, funcParam);
- case 'ReturnStatement':
- return this.astReturnStatement(ast, retArr, funcParam);
- case 'Literal':
- return this.astLiteral(ast, retArr, funcParam);
- case 'BinaryExpression':
- return this.astBinaryExpression(ast, retArr, funcParam);
- case 'Identifier':
- return this.astIdentifierExpression(ast, retArr, funcParam);
- case 'AssignmentExpression':
- return this.astAssignmentExpression(ast, retArr, funcParam);
- case 'ExpressionStatement':
- return this.astExpressionStatement(ast, retArr, funcParam);
- case 'EmptyStatement':
- return this.astEmptyStatement(ast, retArr, funcParam);
- case 'BlockStatement':
- return this.astBlockStatement(ast, retArr, funcParam);
- case 'IfStatement':
- return this.astIfStatement(ast, retArr, funcParam);
- case 'BreakStatement':
- return this.astBreakStatement(ast, retArr, funcParam);
- case 'ContinueStatement':
- return this.astContinueStatement(ast, retArr, funcParam);
- case 'ForStatement':
- return this.astForStatement(ast, retArr, funcParam);
- case 'WhileStatement':
- return this.astWhileStatement(ast, retArr, funcParam);
- case 'VariableDeclaration':
- return this.astVariableDeclaration(ast, retArr, funcParam);
- case 'VariableDeclarator':
- return this.astVariableDeclarator(ast, retArr, funcParam);
- case 'ThisExpression':
- return this.astThisExpression(ast, retArr, funcParam);
- case 'SequenceExpression':
- return this.astSequenceExpression(ast, retArr, funcParam);
- case 'UnaryExpression':
- return this.astUnaryExpression(ast, retArr, funcParam);
- case 'UpdateExpression':
- return this.astUpdateExpression(ast, retArr, funcParam);
- case 'LogicalExpression':
- return this.astLogicalExpression(ast, retArr, funcParam);
- case 'MemberExpression':
- return this.astMemberExpression(ast, retArr, funcParam);
- case 'CallExpression':
- return this.astCallExpression(ast, retArr, funcParam);
- case 'ArrayExpression':
- return this.astArrayExpression(ast, retArr, funcParam);
- case 'DebuggerStatement':
- return this.astDebuggerStatement(ast, retArr, funcParam);
- }
-
- throw this.astErrorOutput('Unknown ast type : ' + ast.type, ast, funcParam);
- }
- }
-
-
- }, {
- key: 'astFunctionDeclaration',
- value: function astFunctionDeclaration(ast, retArr, funcParam) {
- if (this.addFunction) {
- this.addFunction(null, utils.getAstString(this.jsFunctionString, ast));
- }
- return retArr;
- }
-
-
- }, {
- key: 'astFunctionExpression',
-
-
- value: function astFunctionExpression(ast, retArr, funcParam) {
-
- if (funcParam.isRootKernel) {
- retArr.push('void');
- funcParam.kernalAst = ast;
- } else {
- retArr.push(funcParam.returnType);
- }
- retArr.push(' ');
- retArr.push(funcParam.functionName);
- retArr.push('(');
-
- if (!funcParam.isRootKernel) {
- for (var i = 0; i < funcParam.paramNames.length; ++i) {
- var paramName = funcParam.paramNames[i];
-
- if (i > 0) {
- retArr.push(', ');
- }
- var type = funcParam.getParamType(paramName);
- switch (type) {
- case 'Texture':
- case 'Input':
- case 'Array':
- retArr.push('sampler2D');
- break;
- default:
- retArr.push('float');
- }
-
- retArr.push(' ');
- retArr.push('user_');
- retArr.push(paramName);
- }
- }
-
- retArr.push(') {\n');
-
- for (var _i = 0; _i < ast.body.body.length; ++_i) {
- this.astGeneric(ast.body.body[_i], retArr, funcParam);
- retArr.push('\n');
- }
-
- retArr.push('}\n');
- return retArr;
- }
-
-
- }, {
- key: 'astReturnStatement',
- value: function astReturnStatement(ast, retArr, funcParam) {
- if (funcParam.isRootKernel) {
- retArr.push('kernelResult = ');
- this.astGeneric(ast.argument, retArr, funcParam);
- retArr.push(';');
- retArr.push('return;');
- } else if (funcParam.isSubKernel) {
- retArr.push(funcParam.functionName + 'Result = ');
- this.astGeneric(ast.argument, retArr, funcParam);
- retArr.push(';');
- retArr.push('return ' + funcParam.functionName + 'Result;');
- } else {
- retArr.push('return ');
- this.astGeneric(ast.argument, retArr, funcParam);
- retArr.push(';');
- }
-
-
- return retArr;
- }
-
-
- }, {
- key: 'astLiteral',
- value: function astLiteral(ast, retArr, funcParam) {
-
- if (isNaN(ast.value)) {
- throw this.astErrorOutput('Non-numeric literal not supported : ' + ast.value, ast, funcParam);
- }
-
- retArr.push(ast.value);
-
- if (Number.isInteger(ast.value)) {
- retArr.push('.0');
- }
-
- return retArr;
- }
-
-
- }, {
- key: 'astBinaryExpression',
- value: function astBinaryExpression(ast, retArr, funcParam) {
- retArr.push('(');
-
- if (ast.operator === '%') {
- retArr.push('mod(');
- this.astGeneric(ast.left, retArr, funcParam);
- retArr.push(',');
- this.astGeneric(ast.right, retArr, funcParam);
- retArr.push(')');
- } else if (ast.operator === '===') {
- this.astGeneric(ast.left, retArr, funcParam);
- retArr.push('==');
- this.astGeneric(ast.right, retArr, funcParam);
- } else if (ast.operator === '!==') {
- this.astGeneric(ast.left, retArr, funcParam);
- retArr.push('!=');
- this.astGeneric(ast.right, retArr, funcParam);
- } else {
- this.astGeneric(ast.left, retArr, funcParam);
- retArr.push(ast.operator);
- this.astGeneric(ast.right, retArr, funcParam);
- }
-
- retArr.push(')');
-
- return retArr;
- }
-
-
- }, {
- key: 'astIdentifierExpression',
- value: function astIdentifierExpression(idtNode, retArr, funcParam) {
- if (idtNode.type !== 'Identifier') {
- throw this.astErrorOutput('IdentifierExpression - not an Identifier', ast, funcParam);
- }
-
- switch (idtNode.name) {
- case 'gpu_threadX':
- retArr.push('threadId.x');
- break;
- case 'gpu_threadY':
- retArr.push('threadId.y');
- break;
- case 'gpu_threadZ':
- retArr.push('threadId.z');
- break;
- case 'gpu_outputX':
- retArr.push('uOutputDim.x');
- break;
- case 'gpu_outputY':
- retArr.push('uOutputDim.y');
- break;
- case 'gpu_outputZ':
- retArr.push('uOutputDim.z');
- break;
- default:
- if (this.constants && this.constants.hasOwnProperty(idtNode.name)) {
- retArr.push('constants_' + idtNode.name);
- } else {
- var userParamName = funcParam.getUserParamName(idtNode.name);
- if (userParamName !== null) {
- retArr.push('user_' + userParamName);
- } else {
- retArr.push('user_' + idtNode.name);
- }
- }
- }
-
- return retArr;
- }
-
-
- }, {
- key: 'astForStatement',
- value: function astForStatement(forNode, retArr, funcParam) {
- if (forNode.type !== 'ForStatement') {
- throw this.astErrorOutput('Invalid for statment', ast, funcParam);
- }
-
- if (forNode.test && forNode.test.type === 'BinaryExpression') {
- if (forNode.test.right.type === 'Identifier' && forNode.test.operator === '<' && this.isIdentifierConstant(forNode.test.right.name) === false) {
-
- if (!this.loopMaxIterations) {
- console.warn('Warning: loopMaxIterations is not set! Using default of 1000 which may result in unintended behavior.');
- console.warn('Set loopMaxIterations or use a for loop of fixed length to silence this message.');
- }
-
- retArr.push('for (');
- this.astGeneric(forNode.init, retArr, funcParam);
- this.astGeneric(forNode.test.left, retArr, funcParam);
- retArr.push(forNode.test.operator);
- retArr.push('LOOP_MAX');
- retArr.push(';');
- this.astGeneric(forNode.update, retArr, funcParam);
- retArr.push(')');
-
- retArr.push('{\n');
- retArr.push('if (');
- this.astGeneric(forNode.test.left, retArr, funcParam);
- retArr.push(forNode.test.operator);
- this.astGeneric(forNode.test.right, retArr, funcParam);
- retArr.push(') {\n');
- if (forNode.body.type === 'BlockStatement') {
- for (var i = 0; i < forNode.body.body.length; i++) {
- this.astGeneric(forNode.body.body[i], retArr, funcParam);
- }
- } else {
- this.astGeneric(forNode.body, retArr, funcParam);
- }
- retArr.push('} else {\n');
- retArr.push('break;\n');
- retArr.push('}\n');
- retArr.push('}\n');
-
- return retArr;
- } else {
- var declarations = JSON.parse(JSON.stringify(forNode.init.declarations));
- var updateArgument = forNode.update.argument;
- if (!Array.isArray(declarations) || declarations.length < 1) {
- console.log(this.jsFunctionString);
- throw new Error('Error: Incompatible for loop declaration');
- }
-
- if (declarations.length > 1) {
- var initArgument = null;
- for (var _i2 = 0; _i2 < declarations.length; _i2++) {
- var declaration = declarations[_i2];
- if (declaration.id.name === updateArgument.name) {
- initArgument = declaration;
- declarations.splice(_i2, 1);
- } else {
- retArr.push('float ');
- this.astGeneric(declaration, retArr, funcParam);
- retArr.push(';');
- }
- }
-
- retArr.push('for (float ');
- this.astGeneric(initArgument, retArr, funcParam);
- retArr.push(';');
- } else {
- retArr.push('for (');
- this.astGeneric(forNode.init, retArr, funcParam);
- }
-
- this.astGeneric(forNode.test, retArr, funcParam);
- retArr.push(';');
- this.astGeneric(forNode.update, retArr, funcParam);
- retArr.push(')');
- this.astGeneric(forNode.body, retArr, funcParam);
- return retArr;
- }
- }
-
- throw this.astErrorOutput('Invalid for statement', ast, funcParam);
- }
-
-
- }, {
- key: 'astWhileStatement',
- value: function astWhileStatement(whileNode, retArr, funcParam) {
- if (whileNode.type !== 'WhileStatement') {
- throw this.astErrorOutput('Invalid while statment', ast, funcParam);
- }
-
- retArr.push('for (float i = 0.0; i < LOOP_MAX; i++) {');
- retArr.push('if (');
- this.astGeneric(whileNode.test, retArr, funcParam);
- retArr.push(') {\n');
- this.astGeneric(whileNode.body, retArr, funcParam);
- retArr.push('} else {\n');
- retArr.push('break;\n');
- retArr.push('}\n');
- retArr.push('}\n');
-
- return retArr;
- }
-
-
- }, {
- key: 'astAssignmentExpression',
- value: function astAssignmentExpression(assNode, retArr, funcParam) {
- if (assNode.operator === '%=') {
- this.astGeneric(assNode.left, retArr, funcParam);
- retArr.push('=');
- retArr.push('mod(');
- this.astGeneric(assNode.left, retArr, funcParam);
- retArr.push(',');
- this.astGeneric(assNode.right, retArr, funcParam);
- retArr.push(')');
- } else {
- this.astGeneric(assNode.left, retArr, funcParam);
- retArr.push(assNode.operator);
- this.astGeneric(assNode.right, retArr, funcParam);
- return retArr;
- }
- }
-
-
- }, {
- key: 'astEmptyStatement',
- value: function astEmptyStatement(eNode, retArr, funcParam) {
- return retArr;
- }
-
-
- }, {
- key: 'astBlockStatement',
- value: function astBlockStatement(bNode, retArr, funcParam) {
- retArr.push('{\n');
- for (var i = 0; i < bNode.body.length; i++) {
- this.astGeneric(bNode.body[i], retArr, funcParam);
- }
- retArr.push('}\n');
- return retArr;
- }
-
-
- }, {
- key: 'astExpressionStatement',
- value: function astExpressionStatement(esNode, retArr, funcParam) {
- this.astGeneric(esNode.expression, retArr, funcParam);
- retArr.push(';\n');
- return retArr;
- }
-
-
- }, {
- key: 'astVariableDeclaration',
- value: function astVariableDeclaration(vardecNode, retArr, funcParam) {
- retArr.push('float ');
- for (var i = 0; i < vardecNode.declarations.length; i++) {
- if (i > 0) {
- retArr.push(',');
- }
- this.astGeneric(vardecNode.declarations[i], retArr, funcParam);
- }
- retArr.push(';');
- return retArr;
- }
-
-
- }, {
- key: 'astVariableDeclarator',
- value: function astVariableDeclarator(ivardecNode, retArr, funcParam) {
- this.astGeneric(ivardecNode.id, retArr, funcParam);
- if (ivardecNode.init !== null) {
- retArr.push('=');
- this.astGeneric(ivardecNode.init, retArr, funcParam);
- }
- return retArr;
- }
-
-
- }, {
- key: 'astIfStatement',
- value: function astIfStatement(ifNode, retArr, funcParam) {
- retArr.push('if (');
- this.astGeneric(ifNode.test, retArr, funcParam);
- retArr.push(')');
- if (ifNode.consequent.type === 'BlockStatement') {
- this.astGeneric(ifNode.consequent, retArr, funcParam);
- } else {
- retArr.push(' {\n');
- this.astGeneric(ifNode.consequent, retArr, funcParam);
- retArr.push('\n}\n');
- }
-
- if (ifNode.alternate) {
- retArr.push('else ');
- if (ifNode.alternate.type === 'BlockStatement') {
- this.astGeneric(ifNode.alternate, retArr, funcParam);
- } else {
- retArr.push(' {\n');
- this.astGeneric(ifNode.alternate, retArr, funcParam);
- retArr.push('\n}\n');
- }
- }
- return retArr;
- }
-
-
- }, {
- key: 'astBreakStatement',
- value: function astBreakStatement(brNode, retArr, funcParam) {
- retArr.push('break;\n');
- return retArr;
- }
-
-
- }, {
- key: 'astContinueStatement',
- value: function astContinueStatement(crNode, retArr, funcParam) {
- retArr.push('continue;\n');
- return retArr;
- }
-
-
- }, {
- key: 'astLogicalExpression',
- value: function astLogicalExpression(logNode, retArr, funcParam) {
- retArr.push('(');
- this.astGeneric(logNode.left, retArr, funcParam);
- retArr.push(logNode.operator);
- this.astGeneric(logNode.right, retArr, funcParam);
- retArr.push(')');
- return retArr;
- }
-
-
- }, {
- key: 'astUpdateExpression',
- value: function astUpdateExpression(uNode, retArr, funcParam) {
- if (uNode.prefix) {
- retArr.push(uNode.operator);
- this.astGeneric(uNode.argument, retArr, funcParam);
- } else {
- this.astGeneric(uNode.argument, retArr, funcParam);
- retArr.push(uNode.operator);
- }
-
- return retArr;
- }
-
-
- }, {
- key: 'astUnaryExpression',
- value: function astUnaryExpression(uNode, retArr, funcParam) {
- if (uNode.prefix) {
- retArr.push(uNode.operator);
- this.astGeneric(uNode.argument, retArr, funcParam);
- } else {
- this.astGeneric(uNode.argument, retArr, funcParam);
- retArr.push(uNode.operator);
- }
-
- return retArr;
- }
-
-
- }, {
- key: 'astThisExpression',
- value: function astThisExpression(tNode, retArr, funcParam) {
- retArr.push('this');
- return retArr;
- }
-
-
- }, {
- key: 'astMemberExpression',
- value: function astMemberExpression(mNode, retArr, funcParam) {
- if (mNode.computed) {
- if (mNode.object.type === 'Identifier') {
- var reqName = mNode.object.name;
- var funcName = funcParam.functionName || 'kernel';
- var assumeNotTexture = false;
-
- if (funcParam.paramNames) {
- var idx = funcParam.paramNames.indexOf(reqName);
- if (idx >= 0 && funcParam.paramTypes[idx] === 'float') {
- assumeNotTexture = true;
- }
- }
-
- if (assumeNotTexture) {
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push('[int(');
- this.astGeneric(mNode.property, retArr, funcParam);
- retArr.push(')]');
- } else {
- retArr.push('get(');
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push(', vec2(');
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push('Size[0],');
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push('Size[1]), vec3(');
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push('Dim[0],');
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push('Dim[1],');
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push('Dim[2]');
- retArr.push('), ');
- this.astGeneric(mNode.property, retArr, funcParam);
- retArr.push(')');
- }
- } else {
- this.astGeneric(mNode.object, retArr, funcParam);
- var last = retArr.pop();
- retArr.push(',');
- this.astGeneric(mNode.property, retArr, funcParam);
- retArr.push(last);
- }
- } else {
-
- var unrolled = this.astMemberExpressionUnroll(mNode);
- var unrolled_lc = unrolled.toLowerCase();
-
- if (unrolled.indexOf(constantsPrefix) === 0) {
- unrolled = 'constants_' + unrolled.slice(constantsPrefix.length);
- }
-
- switch (unrolled_lc) {
- case 'this.thread.x':
- retArr.push('threadId.x');
- break;
- case 'this.thread.y':
- retArr.push('threadId.y');
- break;
- case 'this.thread.z':
- retArr.push('threadId.z');
- break;
- case 'this.output.x':
- retArr.push(this.output[0] + '.0');
- break;
- case 'this.output.y':
- retArr.push(this.output[1] + '.0');
- break;
- case 'this.output.z':
- retArr.push(this.output[2] + '.0');
- break;
- default:
- retArr.push(unrolled);
- }
- }
- return retArr;
- }
- }, {
- key: 'astSequenceExpression',
- value: function astSequenceExpression(sNode, retArr, funcParam) {
- for (var i = 0; i < sNode.expressions.length; i++) {
- if (i > 0) {
- retArr.push(',');
- }
- this.astGeneric(sNode.expressions, retArr, funcParam);
- }
- return retArr;
- }
-
-
- }, {
- key: 'astCallExpression',
- value: function astCallExpression(ast, retArr, funcParam) {
- if (ast.callee) {
- var funcName = this.astMemberExpressionUnroll(ast.callee);
-
- if (funcName.indexOf(jsMathPrefix) === 0) {
- funcName = funcName.slice(jsMathPrefix.length);
- }
-
- if (funcName.indexOf(localPrefix) === 0) {
- funcName = funcName.slice(localPrefix.length);
- }
-
- if (funcParam.calledFunctions.indexOf(funcName) < 0) {
- funcParam.calledFunctions.push(funcName);
- }
- if (!funcParam.hasOwnProperty('funcName')) {
- funcParam.calledFunctionsArguments[funcName] = [];
- }
-
- var functionArguments = [];
- funcParam.calledFunctionsArguments[funcName].push(functionArguments);
-
- retArr.push(funcName);
-
- retArr.push('(');
-
- for (var i = 0; i < ast.arguments.length; ++i) {
- var argument = ast.arguments[i];
- if (i > 0) {
- retArr.push(', ');
- }
- this.astGeneric(argument, retArr, funcParam);
- if (argument.type === 'Identifier') {
- var paramIndex = funcParam.paramNames.indexOf(argument.name);
- if (paramIndex === -1) {
- functionArguments.push(null);
- } else {
- functionArguments.push({
- name: argument.name,
- type: funcParam.paramTypes[paramIndex]
- });
- }
- } else {
- functionArguments.push(null);
- }
- }
-
- retArr.push(')');
-
- return retArr;
- }
-
- throw this.astErrorOutput('Unknown CallExpression', ast, funcParam);
-
- return retArr;
- }
-
-
- }, {
- key: 'astArrayExpression',
- value: function astArrayExpression(arrNode, retArr, funcParam) {
- var arrLen = arrNode.elements.length;
-
- retArr.push('float[' + arrLen + '](');
- for (var i = 0; i < arrLen; ++i) {
- if (i > 0) {
- retArr.push(', ');
- }
- var subNode = arrNode.elements[i];
- this.astGeneric(subNode, retArr, funcParam);
- }
- retArr.push(')');
-
- return retArr;
-
- }
-
-
- }, {
- key: 'getFunctionPrototypeString',
- value: function getFunctionPrototypeString() {
- if (this.webGlFunctionPrototypeString) {
- return this.webGlFunctionPrototypeString;
- }
- return this.webGlFunctionPrototypeString = this.generate();
- }
- }, {
- key: 'build',
- value: function build() {
- return this.getFunctionPrototypeString().length > 0;
- }
- }], [{
- key: 'astFunctionPrototype',
- value: function astFunctionPrototype(ast, retArr, funcParam) {
- if (funcParam.isRootKernel || funcParam.isSubKernel) {
- return retArr;
- }
-
- retArr.push(funcParam.returnType);
- retArr.push(' ');
- retArr.push(funcParam.functionName);
- retArr.push('(');
-
- for (var i = 0; i < funcParam.paramNames.length; ++i) {
- if (i > 0) {
- retArr.push(', ');
- }
-
- retArr.push(funcParam.paramTypes[i]);
- retArr.push(' ');
- retArr.push('user_');
- retArr.push(funcParam.paramNames[i]);
- }
-
- retArr.push(');\n');
-
- return retArr;
- }
- }]);
-
- return WebGLFunctionNode;
-}(FunctionNodeBase);
-
-function isIdentifierKernelParam(paramName, ast, funcParam) {
- return funcParam.paramNames.indexOf(paramName) !== -1;
-}
-
-function ensureIndentifierType(paramName, expectedType, ast, funcParam) {
- var start = ast.loc.start;
-
- if (!isIdentifierKernelParam(paramName, funcParam) && expectedType !== 'float') {
- throw 'Error unexpected identifier ' + paramName + ' on line ' + start.line;
- } else {
- var actualType = funcParam.paramTypes[funcParam.paramNames.indexOf(paramName)];
- if (actualType !== expectedType) {
- throw 'Error unexpected identifier ' + paramName + ' on line ' + start.line;
- }
- }
-}
-
-function webGlRegexOptimize(inStr) {
- return inStr.replace(DECODE32_ENCODE32, '((').replace(ENCODE32_DECODE32, '((');
-}
-},{"../../core/utils":25,"../function-node-base":7}],13:[function(require,module,exports){
-'use strict';
-
-var utils = require('../../core/utils');
-var kernelRunShortcut = require('../kernel-run-shortcut');
-
-module.exports = function (gpuKernel, name) {
- return '() => {\n ' + kernelRunShortcut.toString() + ';\n const utils = {\n allPropertiesOf: function ' + utils.allPropertiesOf.toString() + ',\n clone: function ' + utils.clone.toString() + ',\n splitArray: function ' + utils.splitArray.toString() + ',\n getArgumentType: function ' + utils.getArgumentType.toString() + ',\n getDimensions: function ' + utils.getDimensions.toString() + ',\n dimToTexSize: function ' + utils.dimToTexSize.toString() + ',\n copyFlatten: function ' + utils.copyFlatten.toString() + ',\n flatten: function ' + utils.flatten.toString() + ',\n systemEndianness: \'' + utils.systemEndianness() + '\',\n initWebGl: function ' + utils.initWebGl.toString() + ',\n isArray: function ' + utils.isArray.toString() + '\n };\n class ' + (name || 'Kernel') + ' {\n constructor() {\n this.argumentsLength = 0;\n this._canvas = null;\n this._webGl = null;\n this.built = false;\n this.program = null;\n this.paramNames = ' + JSON.stringify(gpuKernel.paramNames) + ';\n this.paramTypes = ' + JSON.stringify(gpuKernel.paramTypes) + ';\n this.texSize = ' + JSON.stringify(gpuKernel.texSize) + ';\n this.output = ' + JSON.stringify(gpuKernel.output) + ';\n this.compiledFragShaderString = `' + gpuKernel.compiledFragShaderString + '`;\n\t\t this.compiledVertShaderString = `' + gpuKernel.compiledVertShaderString + '`;\n\t\t this.programUniformLocationCache = {};\n\t\t this.textureCache = {};\n\t\t this.subKernelOutputTextures = null;\n }\n ' + gpuKernel._getFragShaderString.toString() + '\n ' + gpuKernel._getVertShaderString.toString() + '\n validateOptions() {}\n setupParams() {}\n setCanvas(canvas) { this._canvas = canvas; return this; }\n setWebGl(webGl) { this._webGl = webGl; return this; }\n ' + gpuKernel.getUniformLocation.toString() + '\n ' + gpuKernel.setupParams.toString() + '\n ' + gpuKernel.build.toString() + '\n\t\t ' + gpuKernel.run.toString() + '\n\t\t ' + gpuKernel._addArgument.toString() + '\n\t\t ' + gpuKernel.getArgumentTexture.toString() + '\n\t\t ' + gpuKernel.getTextureCache.toString() + '\n\t\t ' + gpuKernel.getOutputTexture.toString() + '\n\t\t ' + gpuKernel.renderOutput.toString() + '\n };\n return kernelRunShortcut(new Kernel());\n };';
-};
-},{"../../core/utils":25,"../kernel-run-shortcut":9}],14:[function(require,module,exports){
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var fs = require('fs');
-var KernelBase = require('../kernel-base');
-var utils = require('../../core/utils');
-var Texture = require('../../core/texture');
-var fragShaderString = require('./shader-frag');
-var vertShaderString = require('./shader-vert');
-var kernelString = require('./kernel-string');
-var canvases = [];
-var maxTexSizes = {};
-module.exports = function (_KernelBase) {
- _inherits(WebGLKernel, _KernelBase);
-
- function WebGLKernel(fnString, settings) {
- _classCallCheck(this, WebGLKernel);
-
- var _this = _possibleConstructorReturn(this, (WebGLKernel.__proto__ || Object.getPrototypeOf(WebGLKernel)).call(this, fnString, settings));
-
- _this.textureCache = {};
- _this.threadDim = {};
- _this.programUniformLocationCache = {};
- _this.framebuffer = null;
-
- _this.buffer = null;
- _this.program = null;
- _this.outputToTexture = settings.outputToTexture;
- _this.endianness = utils.systemEndianness();
- _this.subKernelOutputTextures = null;
- _this.subKernelOutputVariableNames = null;
- _this.argumentsLength = 0;
- _this.ext = null;
- _this.compiledFragShaderString = null;
- _this.compiledVertShaderString = null;
- _this.extDrawBuffersMap = null;
- _this.outputTexture = null;
- _this.maxTexSize = null;
- if (!_this._webGl) _this._webGl = utils.initWebGl(_this.getCanvas());
- return _this;
- }
-
-
-
- _createClass(WebGLKernel, [{
- key: 'validateOptions',
- value: function validateOptions() {
- var isReadPixel = utils.isFloatReadPixelsSupported();
- if (this.floatTextures === true && !utils.OES_texture_float) {
- throw 'Float textures are not supported on this browser';
- } else if (this.floatOutput === true && this.floatOutputForce !== true && !isReadPixel) {
- throw 'Float texture outputs are not supported on this browser';
- } else if (this.floatTextures === null && !isReadPixel && !this.graphical) {
- this.floatTextures = true;
- this.floatOutput = false;
- }
-
- if (!this.output || this.output.length === 0) {
- if (arguments.length !== 1) {
- throw 'Auto output only supported for kernels with only one input';
- }
-
- var argType = utils.getArgumentType(arguments[0]);
- if (argType === 'Array') {
- this.output = utils.getDimensions(argType);
- } else if (argType === 'Texture') {
- this.output = arguments[0].output;
- } else {
- throw 'Auto output not supported for input type: ' + argType;
- }
- }
-
- this.texSize = utils.dimToTexSize({
- floatTextures: this.floatTextures,
- floatOutput: this.floatOutput
- }, this.output, true);
-
- if (this.graphical) {
- if (this.output.length !== 2) {
- throw 'Output must have 2 dimensions on graphical mode';
- }
-
- if (this.floatOutput) {
- throw 'Cannot use graphical mode and float output at the same time';
- }
-
- this.texSize = utils.clone(this.output);
- } else if (this.floatOutput === undefined && utils.OES_texture_float) {
- this.floatOutput = true;
- }
- }
- }, {
- key: 'updateMaxTexSize',
- value: function updateMaxTexSize() {
- var texSize = this.texSize;
- var canvas = this._canvas;
- if (this.maxTexSize === null) {
- var canvasIndex = canvases.indexOf(canvas);
- if (canvasIndex === -1) {
- canvasIndex = canvases.length;
- canvases.push(canvas);
- maxTexSizes[canvasIndex] = [texSize[0], texSize[1]];
- }
- this.maxTexSize = maxTexSizes[canvasIndex];
- }
- if (this.maxTexSize[0] < texSize[0]) {
- this.maxTexSize[0] = texSize[0];
- }
- if (this.maxTexSize[1] < texSize[1]) {
- this.maxTexSize[1] = texSize[1];
- }
- }
-
-
- }, {
- key: 'build',
- value: function build() {
- this.validateOptions();
- this.setupParams(arguments);
- this.updateMaxTexSize();
- var texSize = this.texSize;
- var gl = this._webGl;
- var canvas = this._canvas;
- gl.enable(gl.SCISSOR_TEST);
- gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);
- canvas.width = this.maxTexSize[0];
- canvas.height = this.maxTexSize[1];
- var threadDim = this.threadDim = utils.clone(this.output);
- while (threadDim.length < 3) {
- threadDim.push(1);
- }
-
- if (this.functionBuilder) this._addKernels();
-
- var compiledVertShaderString = this._getVertShaderString(arguments);
- var vertShader = gl.createShader(gl.VERTEX_SHADER);
- gl.shaderSource(vertShader, compiledVertShaderString);
- gl.compileShader(vertShader);
-
- var compiledFragShaderString = this._getFragShaderString(arguments);
- var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
- gl.shaderSource(fragShader, compiledFragShaderString);
- gl.compileShader(fragShader);
-
- if (!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) {
- console.log(compiledVertShaderString);
- console.error('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(vertShader));
- throw 'Error compiling vertex shader';
- }
- if (!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) {
- console.log(compiledFragShaderString);
- console.error('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(fragShader));
- throw 'Error compiling fragment shader';
- }
-
- if (this.debug) {
- console.log('Options:');
- console.dir(this);
- console.log('GLSL Shader Output:');
- console.log(compiledFragShaderString);
- }
-
- var program = this.program = gl.createProgram();
- gl.attachShader(program, vertShader);
- gl.attachShader(program, fragShader);
- gl.linkProgram(program);
- this.framebuffer = gl.createFramebuffer();
- this.framebuffer.width = texSize[0];
- this.framebuffer.height = texSize[1];
-
- var vertices = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
- var texCoords = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);
-
- var texCoordOffset = vertices.byteLength;
-
- var buffer = this.buffer;
- if (!buffer) {
- buffer = this.buffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
- gl.bufferData(gl.ARRAY_BUFFER, vertices.byteLength + texCoords.byteLength, gl.STATIC_DRAW);
- } else {
- gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
- }
-
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices);
- gl.bufferSubData(gl.ARRAY_BUFFER, texCoordOffset, texCoords);
-
- var aPosLoc = gl.getAttribLocation(this.program, 'aPos');
- gl.enableVertexAttribArray(aPosLoc);
- gl.vertexAttribPointer(aPosLoc, 2, gl.FLOAT, gl.FALSE, 0, 0);
- var aTexCoordLoc = gl.getAttribLocation(this.program, 'aTexCoord');
- gl.enableVertexAttribArray(aTexCoordLoc);
- gl.vertexAttribPointer(aTexCoordLoc, 2, gl.FLOAT, gl.FALSE, 0, texCoordOffset);
-
- this.setupOutputTexture();
-
- if (this.subKernelOutputTextures !== null) {
- var extDrawBuffersMap = this.extDrawBuffersMap = [gl.COLOR_ATTACHMENT0];
- for (var i = 0; i < this.subKernelOutputTextures.length; i++) {
- var subKernelOutputTexture = this.subKernelOutputTextures[i];
- extDrawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1);
- gl.activeTexture(gl.TEXTURE0 + arguments.length + i);
- gl.bindTexture(gl.TEXTURE_2D, subKernelOutputTexture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
- if (this.floatOutput) {
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);
- } else {
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
- }
- }
- }
- }
-
-
- }, {
- key: 'run',
- value: function run() {
- if (this.program === null) {
- this.build.apply(this, arguments);
- }
- var paramNames = this.paramNames;
- var paramTypes = this.paramTypes;
- var texSize = this.texSize;
- var gl = this._webGl;
-
- gl.useProgram(this.program);
- gl.scissor(0, 0, texSize[0], texSize[1]);
-
- if (!this.hardcodeConstants) {
- var uOutputDimLoc = this.getUniformLocation('uOutputDim');
- gl.uniform3fv(uOutputDimLoc, this.threadDim);
- var uTexSizeLoc = this.getUniformLocation('uTexSize');
- gl.uniform2fv(uTexSizeLoc, texSize);
- }
-
- var ratioLoc = this.getUniformLocation('ratio');
- gl.uniform2f(ratioLoc, texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]);
-
- this.argumentsLength = 0;
- for (var texIndex = 0; texIndex < paramNames.length; texIndex++) {
- this._addArgument(arguments[texIndex], paramTypes[texIndex], paramNames[texIndex]);
- }
-
- if (this.graphical) {
- gl.bindRenderbuffer(gl.RENDERBUFFER, null);
- gl.bindFramebuffer(gl.FRAMEBUFFER, null);
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
- return;
- }
-
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
- var outputTexture = this.outputTexture;
- gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, outputTexture, 0);
-
- if (this.subKernelOutputTextures !== null) {
- for (var i = 0; i < this.subKernelOutputTextures.length; i++) {
- var subKernelOutputTexture = this.subKernelOutputTextures[i];
- gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, subKernelOutputTexture, 0);
- }
- this.ext.drawBuffersWEBGL(this.extDrawBuffersMap);
- }
-
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
-
- if (this.subKernelOutputTextures !== null) {
- if (this.subKernels !== null) {
- var output = [];
- output.result = this.renderOutput(outputTexture);
- for (var _i = 0; _i < this.subKernels.length; _i++) {
- output.push(new Texture(this.subKernelOutputTextures[_i], texSize, this.output, this._webGl));
- }
- return output;
- } else if (this.subKernelProperties !== null) {
- var _output = {
- result: this.renderOutput(outputTexture)
- };
- var _i2 = 0;
- for (var p in this.subKernelProperties) {
- if (!this.subKernelProperties.hasOwnProperty(p)) continue;
- _output[p] = new Texture(this.subKernelOutputTextures[_i2], texSize, this.output, this._webGl);
- _i2++;
- }
- return _output;
- }
- }
-
- return this.renderOutput(outputTexture);
- }
-
-
- }, {
- key: 'renderOutput',
- value: function renderOutput(outputTexture) {
- var texSize = this.texSize;
- var gl = this._webGl;
- var threadDim = this.threadDim;
- var output = this.output;
- if (this.outputToTexture) {
- return new Texture(outputTexture, texSize, output, this._webGl);
- } else {
- var result = void 0;
- if (this.floatOutput) {
- result = new Float32Array(texSize[0] * texSize[1] * 4);
- gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.FLOAT, result);
- } else {
- var bytes = new Uint8Array(texSize[0] * texSize[1] * 4);
- gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, bytes);
- result = new Float32Array(bytes.buffer);
- }
-
- result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]);
-
- if (output.length === 1) {
- return result;
- } else if (output.length === 2) {
- return utils.splitArray(result, output[0]);
- } else if (output.length === 3) {
- var cube = utils.splitArray(result, output[0] * output[1]);
- return cube.map(function (x) {
- return utils.splitArray(x, output[0]);
- });
- }
- }
- }
-
-
- }, {
- key: 'getOutputTexture',
- value: function getOutputTexture() {
- return this.getTextureCache('OUTPUT');
- }
-
-
- }, {
- key: 'detachOutputTexture',
- value: function detachOutputTexture() {
- this.detachTextureCache('OUTPUT');
- }
-
-
- }, {
- key: 'setupOutputTexture',
- value: function setupOutputTexture() {
- var gl = this._webGl;
- var texSize = this.texSize;
- this.detachOutputTexture();
- this.outputTexture = this.getOutputTexture();
- gl.activeTexture(gl.TEXTURE0 + this.paramNames.length);
- gl.bindTexture(gl.TEXTURE_2D, this.outputTexture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
- if (this.floatOutput) {
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);
- } else {
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
- }
- }
-
-
- }, {
- key: 'getArgumentTexture',
- value: function getArgumentTexture(name) {
- return this.getTextureCache('ARGUMENT_' + name);
- }
-
-
- }, {
- key: 'getSubKernelTexture',
- value: function getSubKernelTexture(name) {
- return this.getTextureCache('SUB_KERNEL_' + name);
- }
-
-
- }, {
- key: 'getTextureCache',
- value: function getTextureCache(name) {
- if (this.outputToTexture) {
- return this._webGl.createTexture();
- }
- if (this.textureCache.hasOwnProperty(name)) {
- return this.textureCache[name];
- }
- return this.textureCache[name] = this._webGl.createTexture();
- }
-
-
- }, {
- key: 'detachTextureCache',
- value: function detachTextureCache(name) {
- delete this.textureCache[name];
- }
-
-
- }, {
- key: 'getUniformLocation',
- value: function getUniformLocation(name) {
- var location = this.programUniformLocationCache[name];
- if (!location) {
- location = this._webGl.getUniformLocation(this.program, name);
- this.programUniformLocationCache[name] = location;
- }
- return location;
- }
-
-
- }, {
- key: '_getFragShaderArtifactMap',
- value: function _getFragShaderArtifactMap(args) {
- return {
- HEADER: this._getHeaderString(),
- LOOP_MAX: this._getLoopMaxString(),
- CONSTANTS: this._getConstantsString(),
- DECODE32_ENDIANNESS: this._getDecode32EndiannessString(),
- ENCODE32_ENDIANNESS: this._getEncode32EndiannessString(),
- GET_WRAPAROUND: this._getGetWraparoundString(),
- GET_TEXTURE_CHANNEL: this._getGetTextureChannelString(),
- GET_TEXTURE_INDEX: this._getGetTextureIndexString(),
- GET_RESULT: this._getGetResultString(),
- MAIN_PARAMS: this._getMainParamsString(args),
- MAIN_CONSTANTS: this._getMainConstantsString(),
- KERNEL: this._getKernelString(),
- MAIN_RESULT: this._getMainResultString()
- };
- }
-
-
- }, {
- key: '_addArgument',
- value: function _addArgument(value, type, name) {
- var gl = this._webGl;
- var argumentTexture = this.getArgumentTexture(name);
- if (value instanceof Texture) {
- type = 'Texture';
- }
- switch (type) {
- case 'Array':
- {
- var dim = utils.getDimensions(value, true);
- var size = utils.dimToTexSize({
- floatTextures: this.floatTextures,
- floatOutput: this.floatOutput
- }, dim);
- gl.activeTexture(gl.TEXTURE0 + this.argumentsLength);
- gl.bindTexture(gl.TEXTURE_2D, argumentTexture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
-
- var length = size[0] * size[1];
- if (this.floatTextures) {
- length *= 4;
- }
-
- var valuesFlat = new Float32Array(length);
- utils.flattenTo(value, valuesFlat);
-
- var buffer = void 0;
- if (this.floatTextures) {
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size[0], size[1], 0, gl.RGBA, gl.FLOAT, valuesFlat);
- } else {
- buffer = new Uint8Array(valuesFlat.buffer);
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size[0], size[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, buffer);
- }
-
- var loc = this.getUniformLocation('user_' + name);
- var locSize = this.getUniformLocation('user_' + name + 'Size');
- var dimLoc = this.getUniformLocation('user_' + name + 'Dim');
-
- if (!this.hardcodeConstants) {
- gl.uniform3fv(dimLoc, dim);
- gl.uniform2fv(locSize, size);
- }
- gl.uniform1i(loc, this.argumentsLength);
- break;
- }
- case 'Number':
- {
- var _loc = this.getUniformLocation('user_' + name);
- gl.uniform1f(_loc, value);
- break;
- }
- case 'Input':
- {
- var input = value;
- var _dim = input.size;
- var _size = utils.dimToTexSize({
- floatTextures: this.floatTextures,
- floatOutput: this.floatOutput
- }, _dim);
- gl.activeTexture(gl.TEXTURE0 + this.argumentsLength);
- gl.bindTexture(gl.TEXTURE_2D, argumentTexture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
-
- var _length = _size[0] * _size[1];
- var inputArray = void 0;
- if (this.floatTextures) {
- _length *= 4;
- inputArray = new Float32Array(_length);
- inputArray.set(input.value);
- } else {
- inputArray = input.value;
- }
-
- if (this.floatTextures) {
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, _size[0], _size[1], 0, gl.RGBA, gl.FLOAT, inputArray);
- } else {
- var _buffer = new Uint8Array(inputArray.buffer);
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, _size[0], _size[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, _buffer);
- }
-
- var _loc2 = this.getUniformLocation('user_' + name);
- var _locSize = this.getUniformLocation('user_' + name + 'Size');
- var _dimLoc = this.getUniformLocation('user_' + name + 'Dim');
-
- if (!this.hardcodeConstants) {
- gl.uniform3fv(_dimLoc, _dim);
- gl.uniform2fv(_locSize, _size);
- }
- gl.uniform1i(_loc2, this.argumentsLength);
- break;
- }
- case 'Texture':
- {
- var inputTexture = value;
- var _dim2 = utils.getDimensions(inputTexture, true);
-
- var _size2 = inputTexture.size;
-
- if (inputTexture.texture === this.outputTexture) {
- this.setupOutputTexture();
- }
-
- gl.activeTexture(gl.TEXTURE0 + this.argumentsLength);
- gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture);
-
- var _loc3 = this.getUniformLocation('user_' + name);
- var _locSize2 = this.getUniformLocation('user_' + name + 'Size');
- var _dimLoc2 = this.getUniformLocation('user_' + name + 'Dim');
-
- gl.uniform3fv(_dimLoc2, _dim2);
- gl.uniform2fv(_locSize2, _size2);
- gl.uniform1i(_loc3, this.argumentsLength);
- break;
- }
- default:
- throw 'Input type not supported (WebGL): ' + value;
- }
- this.argumentsLength++;
- }
-
-
- }, {
- key: '_getHeaderString',
- value: function _getHeaderString() {
- return this.subKernels !== null || this.subKernelProperties !== null ?
- '#extension GL_EXT_draw_buffers : require\n' : '';
- }
-
-
- }, {
- key: '_getLoopMaxString',
- value: function _getLoopMaxString() {
- return this.loopMaxIterations ? ' ' + parseInt(this.loopMaxIterations) + '.0;\n' : ' 1000.0;\n';
- }
-
-
- }, {
- key: '_getConstantsString',
- value: function _getConstantsString() {
- var result = [];
- var threadDim = this.threadDim;
- var texSize = this.texSize;
- if (this.hardcodeConstants) {
- result.push('highp vec3 uOutputDim = vec3(' + threadDim[0] + ',' + threadDim[1] + ', ' + threadDim[2] + ')', 'highp vec2 uTexSize = vec2(' + texSize[0] + ', ' + texSize[1] + ')');
- } else {
- result.push('uniform highp vec3 uOutputDim', 'uniform highp vec2 uTexSize');
- }
-
- return this._linesToString(result);
- }
-
-
- }, {
- key: '_getTextureCoordinate',
- value: function _getTextureCoordinate() {
- var names = this.subKernelOutputVariableNames;
- if (names === null || names.length < 1) {
- return 'varying highp vec2 vTexCoord;\n';
- } else {
- return 'out highp vec2 vTexCoord;\n';
- }
- }
-
-
- }, {
- key: '_getDecode32EndiannessString',
- value: function _getDecode32EndiannessString() {
- return this.endianness === 'LE' ? '' : ' rgba.rgba = rgba.abgr;\n';
- }
-
-
- }, {
- key: '_getEncode32EndiannessString',
- value: function _getEncode32EndiannessString() {
- return this.endianness === 'LE' ? '' : ' rgba.rgba = rgba.abgr;\n';
- }
-
-
- }, {
- key: '_getGetWraparoundString',
- value: function _getGetWraparoundString() {
- return this.wraparound ? ' xyz = mod(xyz, texDim);\n' : '';
- }
-
-
- }, {
- key: '_getGetTextureChannelString',
- value: function _getGetTextureChannelString() {
- if (!this.floatTextures) return '';
-
- return this._linesToString([' int channel = int(integerMod(index, 4.0))', ' index = float(int(index) / 4)']);
- }
-
-
- }, {
- key: '_getGetTextureIndexString',
- value: function _getGetTextureIndexString() {
- return this.floatTextures ? ' index = float(int(index)/4);\n' : '';
- }
-
-
- }, {
- key: '_getGetResultString',
- value: function _getGetResultString() {
- if (!this.floatTextures) return ' return decode32(texel);\n';
- return this._linesToString([' if (channel == 0) return texel.r', ' if (channel == 1) return texel.g', ' if (channel == 2) return texel.b', ' if (channel == 3) return texel.a']);
- }
-
-
- }, {
- key: '_getMainParamsString',
- value: function _getMainParamsString(args) {
- var result = [];
- var paramTypes = this.paramTypes;
- var paramNames = this.paramNames;
- for (var i = 0; i < paramNames.length; i++) {
- var param = args[i];
- var paramName = paramNames[i];
- var paramType = paramTypes[i];
- if (this.hardcodeConstants) {
- if (paramType === 'Array' || paramType === 'Texture') {
- var paramDim = utils.getDimensions(param, true);
- var paramSize = utils.dimToTexSize({
- floatTextures: this.floatTextures,
- floatOutput: this.floatOutput
- }, paramDim);
-
- result.push('uniform highp sampler2D user_' + paramName, 'highp vec2 user_' + paramName + 'Size = vec2(' + paramSize[0] + '.0, ' + paramSize[1] + '.0)', 'highp vec3 user_' + paramName + 'Dim = vec3(' + paramDim[0] + '.0, ' + paramDim[1] + '.0, ' + paramDim[2] + '.0)');
- } else if (paramType === 'Number' && Number.isInteger(param)) {
- result.push('highp float user_' + paramName + ' = ' + param + '.0');
- } else if (paramType === 'Number') {
- result.push('highp float user_' + paramName + ' = ' + param);
- }
- } else {
- if (paramType === 'Array' || paramType === 'Texture' || paramType === 'Input') {
- result.push('uniform highp sampler2D user_' + paramName, 'uniform highp vec2 user_' + paramName + 'Size', 'uniform highp vec3 user_' + paramName + 'Dim');
- } else if (paramType === 'Number') {
- result.push('uniform highp float user_' + paramName);
- }
- }
- }
- return this._linesToString(result);
- }
-
-
- }, {
- key: '_getMainConstantsString',
- value: function _getMainConstantsString() {
- var result = [];
- if (this.constants) {
- for (var name in this.constants) {
- if (!this.constants.hasOwnProperty(name)) continue;
- var value = parseFloat(this.constants[name]);
-
- if (Number.isInteger(value)) {
- result.push('const float constants_' + name + ' = ' + parseInt(value) + '.0');
- } else {
- result.push('const float constants_' + name + ' = ' + parseFloat(value));
- }
- }
- }
- return this._linesToString(result);
- }
-
-
- }, {
- key: '_getKernelString',
- value: function _getKernelString() {
- var result = [];
- var names = this.subKernelOutputVariableNames;
- if (names !== null) {
- result.push('highp float kernelResult = 0.0');
- for (var i = 0; i < names.length; i++) {
- result.push('highp float ' + names[i] + ' = 0.0');
- }
-
- } else {
- result.push('highp float kernelResult = 0.0');
- }
-
- return this._linesToString(result) + this.functionBuilder.getPrototypeString('kernel');
- }
-
-
- }, {
- key: '_getMainResultString',
- value: function _getMainResultString() {
- var names = this.subKernelOutputVariableNames;
- var result = [];
- if (this.floatOutput) {
- result.push(' index *= 4.0');
- }
-
- if (this.graphical) {
- result.push(' threadId = indexTo3D(index, uOutputDim)', ' kernel()', ' gl_FragColor = actualColor');
- } else if (this.floatOutput) {
- result.push(' threadId = indexTo3D(index, uOutputDim)', ' kernel()', ' gl_FragColor.r = kernelResult', ' index += 1.0', ' threadId = indexTo3D(index, uOutputDim)', ' kernel()', ' gl_FragColor.g = kernelResult', ' index += 1.0', ' threadId = indexTo3D(index, uOutputDim)', ' kernel()', ' gl_FragColor.b = kernelResult', ' index += 1.0', ' threadId = indexTo3D(index, uOutputDim)', ' kernel()', ' gl_FragColor.a = kernelResult');
- } else if (names !== null) {
- result.push(' threadId = indexTo3D(index, uOutputDim)');
- result.push(' kernel()');
- result.push(' gl_FragData[0] = encode32(kernelResult)');
- for (var i = 0; i < names.length; i++) {
- result.push(' gl_FragData[' + (i + 1) + '] = encode32(' + names[i] + ')');
- }
- } else {
- result.push(' threadId = indexTo3D(index, uOutputDim)', ' kernel()', ' gl_FragColor = encode32(kernelResult)');
- }
-
- return this._linesToString(result);
- }
-
-
- }, {
- key: '_linesToString',
- value: function _linesToString(lines) {
- if (lines.length > 0) {
- return lines.join(';\n') + ';\n';
- } else {
- return '\n';
- }
- }
-
-
- }, {
- key: '_replaceArtifacts',
- value: function _replaceArtifacts(src, map) {
- return src.replace(/[ ]*__([A-Z]+[0-9]*([_]?[A-Z])*)__;\n/g, function (match, artifact) {
- if (map.hasOwnProperty(artifact)) {
- return map[artifact];
- }
- throw 'unhandled artifact ' + artifact;
- });
- }
-
-
- }, {
- key: '_addKernels',
- value: function _addKernels() {
- var builder = this.functionBuilder;
- var gl = this._webGl;
-
- builder.addFunctions(this.functions, {
- constants: this.constants,
- output: this.output
- });
- builder.addNativeFunctions(this.nativeFunctions);
-
- builder.addKernel(this.fnString, {
- prototypeOnly: false,
- constants: this.constants,
- output: this.output,
- debug: this.debug,
- loopMaxIterations: this.loopMaxIterations
- }, this.paramNames, this.paramTypes);
-
- if (this.subKernels !== null) {
- var ext = this.ext = gl.getExtension('WEBGL_draw_buffers');
- if (!ext) throw new Error('could not instantiate draw buffers extension');
- this.subKernelOutputTextures = [];
- this.subKernelOutputVariableNames = [];
- for (var i = 0; i < this.subKernels.length; i++) {
- var subKernel = this.subKernels[i];
- builder.addSubKernel(subKernel, {
- prototypeOnly: false,
- constants: this.constants,
- output: this.output,
- debug: this.debug,
- loopMaxIterations: this.loopMaxIterations
- });
- this.subKernelOutputTextures.push(this.getSubKernelTexture(i));
- this.subKernelOutputVariableNames.push(subKernel.name + 'Result');
- }
- } else if (this.subKernelProperties !== null) {
- var _ext = this.ext = gl.getExtension('WEBGL_draw_buffers');
- if (!_ext) throw new Error('could not instantiate draw buffers extension');
- this.subKernelOutputTextures = [];
- this.subKernelOutputVariableNames = [];
- var _i3 = 0;
- for (var p in this.subKernelProperties) {
- if (!this.subKernelProperties.hasOwnProperty(p)) continue;
- var _subKernel = this.subKernelProperties[p];
- builder.addSubKernel(_subKernel, {
- prototypeOnly: false,
- constants: this.constants,
- output: this.output,
- debug: this.debug,
- loopMaxIterations: this.loopMaxIterations
- });
- this.subKernelOutputTextures.push(this.getSubKernelTexture(p));
- this.subKernelOutputVariableNames.push(_subKernel.name + 'Result');
- _i3++;
- }
- }
- }
-
-
- }, {
- key: '_getFragShaderString',
- value: function _getFragShaderString(args) {
- if (this.compiledFragShaderString !== null) {
- return this.compiledFragShaderString;
- }
- return this.compiledFragShaderString = this._replaceArtifacts(fragShaderString, this._getFragShaderArtifactMap(args));
- }
-
-
- }, {
- key: '_getVertShaderString',
- value: function _getVertShaderString(args) {
- if (this.compiledVertShaderString !== null) {
- return this.compiledVertShaderString;
- }
- return this.compiledVertShaderString = vertShaderString;
- }
-
-
- }, {
- key: 'toString',
- value: function toString() {
- return kernelString(this);
- }
- }, {
- key: 'addFunction',
- value: function addFunction(fn) {
- this.functionBuilder.addFunction(null, fn);
- }
- }]);
-
- return WebGLKernel;
-}(KernelBase);
-},{"../../core/texture":23,"../../core/utils":25,"../kernel-base":8,"./kernel-string":13,"./shader-frag":16,"./shader-vert":17,"fs":28}],15:[function(require,module,exports){
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var RunnerBase = require('../runner-base');
-var WebGLKernel = require('./kernel');
-var utils = require('../../core/utils');
-var WebGLFunctionBuilder = require('./function-builder');
-
-module.exports = function (_RunnerBase) {
- _inherits(WebGLRunner, _RunnerBase);
-
- function WebGLRunner(settings) {
- _classCallCheck(this, WebGLRunner);
-
- var _this = _possibleConstructorReturn(this, (WebGLRunner.__proto__ || Object.getPrototypeOf(WebGLRunner)).call(this, new WebGLFunctionBuilder(), settings));
-
- _this.Kernel = WebGLKernel;
- _this.kernel = null;
- return _this;
- }
-
-
-
- _createClass(WebGLRunner, [{
- key: 'getMode',
- value: function getMode() {
- return 'gpu';
- }
- }]);
-
- return WebGLRunner;
-}(RunnerBase);
-},{"../../core/utils":25,"../runner-base":10,"./function-builder":11,"./kernel":14}],16:[function(require,module,exports){
-"use strict";
-
-module.exports = "__HEADER__;\nprecision highp float;\nprecision highp int;\nprecision highp sampler2D;\n\nconst float LOOP_MAX = __LOOP_MAX__;\n#define EPSILON 0.0000001;\n\n__CONSTANTS__;\n\nvarying highp vec2 vTexCoord;\n\nvec4 round(vec4 x) {\n return floor(x + 0.5);\n}\n\nhighp float round(highp float x) {\n return floor(x + 0.5);\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\nhighp float integerMod(highp float x, highp float y) {\n highp float res = floor(mod(x, y));\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nhighp int integerMod(highp int x, highp int y) {\n return int(integerMod(float(x), float(y)));\n}\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\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\nhighp float decode32(highp vec4 rgba) {\n __DECODE32_ENDIANNESS__;\n rgba *= 255.0;\n vec2 gte128;\n gte128.x = rgba.b >= 128.0 ? 1.0 : 0.0;\n gte128.y = rgba.a >= 128.0 ? 1.0 : 0.0;\n float exponent = 2.0 * rgba.a - 127.0 + dot(gte128, MAGIC_VEC);\n float res = exp2(round(exponent));\n rgba.b = rgba.b - 128.0 * gte128.x;\n res = dot(rgba, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;\n res *= gte128.y * -2.0 + 1.0;\n return res;\n}\n\nhighp vec4 encode32(highp float f) {\n highp float F = abs(f);\n highp float sign = f < 0.0 ? 1.0 : 0.0;\n highp float exponent = floor(log2(F));\n highp float mantissa = (exp2(-exponent) * F);\n // exponent += floor(log2(mantissa));\n vec4 rgba = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n rgba.rg = integerMod(rgba.rg, 256.0);\n rgba.b = integerMod(rgba.b, 128.0);\n rgba.a = exponent*0.5 + 63.5;\n rgba.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n rgba = floor(rgba);\n rgba *= 0.003921569; // 1/255\n __ENCODE32_ENDIANNESS__;\n return rgba;\n}\n// Dragons end here\n\nhighp float index;\nhighp vec3 threadId;\n\nhighp vec3 indexTo3D(highp float idx, highp vec3 texDim) {\n highp float z = floor(idx / (texDim.x * texDim.y));\n idx -= z * texDim.x * texDim.y;\n highp float y = floor(idx / texDim.x);\n highp float x = integerMod(idx, texDim.x);\n return vec3(x, y, z);\n}\n\nhighp float get(highp sampler2D tex, highp vec2 texSize, highp vec3 texDim, highp float z, highp float y, highp float x) {\n highp vec3 xyz = vec3(x, y, z);\n xyz = floor(xyz + 0.5);\n __GET_WRAPAROUND__;\n highp float index = round(xyz.x + texDim.x * (xyz.y + texDim.y * xyz.z));\n __GET_TEXTURE_CHANNEL__;\n highp float w = round(texSize.x);\n vec2 st = vec2(integerMod(index, w), float(int(index) / int(w))) + 0.5;\n __GET_TEXTURE_INDEX__;\n highp vec4 texel = texture2D(tex, st / texSize);\n __GET_RESULT__;\n}\n\nhighp float get(highp sampler2D tex, highp vec2 texSize, highp vec3 texDim, highp float y, highp float x) {\n return get(tex, texSize, texDim, 0.0, y, x);\n}\n\nhighp float get(highp sampler2D tex, highp vec2 texSize, highp vec3 texDim, highp float x) {\n return get(tex, texSize, texDim, 0.0, 0.0, x);\n}\n\nhighp vec4 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\n__MAIN_PARAMS__;\n__MAIN_CONSTANTS__;\n__KERNEL__;\n\nvoid main(void) {\n index = floor(vTexCoord.s * float(uTexSize.x)) + floor(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n __MAIN_RESULT__;\n}";
-},{}],17:[function(require,module,exports){
-"use strict";
-
-module.exports = "precision highp float;\nprecision highp int;\nprecision highp sampler2D;\n\nattribute highp vec2 aPos;\nattribute highp vec2 aTexCoord;\n\nvarying highp 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}";
-},{}],18:[function(require,module,exports){
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var WebGLKernel = require('./kernel');
-var utils = require('../../core/utils');
-
-module.exports = function (_WebGLKernel) {
- _inherits(WebGLValidatorKernel, _WebGLKernel);
-
- function WebGLValidatorKernel() {
- _classCallCheck(this, WebGLValidatorKernel);
-
- return _possibleConstructorReturn(this, (WebGLValidatorKernel.__proto__ || Object.getPrototypeOf(WebGLValidatorKernel)).apply(this, arguments));
- }
-
- _createClass(WebGLValidatorKernel, [{
- key: 'validateOptions',
-
-
- value: function validateOptions() {
- this.texSize = utils.dimToTexSize({
- floatTextures: this.floatTextures,
- floatOutput: this.floatOutput
- }, this.output, true);
- }
- }]);
-
- return WebGLValidatorKernel;
-}(WebGLKernel);
-},{"../../core/utils":25,"./kernel":14}],19:[function(require,module,exports){
-'use strict';
-
-var utils = require('./utils');
-module.exports = function alias(name, fn) {
- var fnString = fn.toString();
- return new Function('return function ' + name + ' (' + utils.getParamNamesFromString(fnString).join(', ') + ') {' + utils.getFunctionBodyFromString(fnString) + '}')();
-};
-},{"./utils":25}],20:[function(require,module,exports){
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var UtilsCore = require("./utils-core");
-
-module.exports = function () {
- function GPUCore() {
- _classCallCheck(this, GPUCore);
- }
-
- _createClass(GPUCore, null, [{
- key: "validateKernelObj",
-
-
- value: function validateKernelObj(kernelObj) {
-
- if (kernelObj === null) {
- throw "KernelObj being validated is NULL";
- }
-
- if (typeof kernelObj === "string") {
- try {
- kernelObj = JSON.parse(kernelObj);
- } catch (e) {
- console.error(e);
- throw "Failed to convert KernelObj from JSON string";
- }
-
- if (kernelObj === null) {
- throw "Invalid (NULL) KernelObj JSON string representation";
- }
- }
-
- if (kernelObj.isKernelObj !== true) {
- throw "Failed missing isKernelObj flag check";
- }
-
- return kernelObj;
- }
-
-
- }, {
- key: "loadKernelObj",
- value: function loadKernelObj(kernelObj, inOpt) {
-
- kernelObj = validateKernelObj(kernelObj);
- }
- }]);
-
- return GPUCore;
-}();
-},{"./utils-core":24}],21:[function(require,module,exports){
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var utils = require('./utils');
-var WebGLRunner = require('../backend/web-gl/runner');
-var CPURunner = require('../backend/cpu/runner');
-var WebGLValidatorKernel = require('../backend/web-gl/validator-kernel');
-var GPUCore = require("./gpu-core");
-
-
-var GPU = function (_GPUCore) {
- _inherits(GPU, _GPUCore);
-
- function GPU(settings) {
- _classCallCheck(this, GPU);
-
- var _this = _possibleConstructorReturn(this, (GPU.__proto__ || Object.getPrototypeOf(GPU)).call(this, settings));
-
- settings = settings || {};
- _this._canvas = settings.canvas || null;
- _this._webGl = settings.webGl || null;
- var mode = settings.mode || 'webgl';
- if (!utils.isWebGlSupported()) {
- console.warn('Warning: gpu not supported, falling back to cpu support');
- mode = 'cpu';
- }
-
- _this.kernels = [];
-
- var runnerSettings = {
- canvas: _this._canvas,
- webGl: _this._webGl
- };
-
- if (mode) {
- switch (mode.toLowerCase()) {
- case 'cpu':
- _this._runner = new CPURunner(runnerSettings);
- break;
- case 'gpu':
- case 'webgl':
- _this._runner = new WebGLRunner(runnerSettings);
- break;
- case 'webgl-validator':
- _this._runner = new WebGLRunner(runnerSettings);
- _this._runner.Kernel = WebGLValidatorKernel;
- break;
- default:
- throw new Error('"' + mode + '" mode is not defined');
- }
- }
- return _this;
- }
-
-
- _createClass(GPU, [{
- key: 'createKernel',
- value: function createKernel(fn, settings) {
- if (typeof fn === 'undefined') {
- throw 'Missing fn parameter';
- }
- if (!utils.isFunction(fn) && typeof fn !== 'string') {
- throw 'fn parameter not a function';
- }
-
- var kernel = this._runner.buildKernel(fn, settings || {});
-
- if (!this._canvas) {
- this._canvas = kernel.getCanvas();
- }
- if (!this._runner.canvas) {
- this._runner.canvas = kernel.getCanvas();
- }
-
- this.kernels.push(kernel);
-
- return kernel;
- }
-
-
- }, {
- key: 'createKernelMap',
- value: function createKernelMap() {
- var fn = void 0;
- var settings = void 0;
- if (typeof arguments[arguments.length - 2] === 'function') {
- fn = arguments[arguments.length - 2];
- settings = arguments[arguments.length - 1];
- } else {
- fn = arguments[arguments.length - 1];
- }
-
- if (!utils.isWebGlDrawBuffersSupported()) {
- this._runner = new CPURunner(settings);
- }
-
- var kernel = this.createKernel(fn, settings);
- if (Array.isArray(arguments[0])) {
- var functions = arguments[0];
- for (var i = 0; i < functions.length; i++) {
- kernel.addSubKernel(functions[i]);
- }
- } else {
- var _functions = arguments[0];
- for (var p in _functions) {
- if (!_functions.hasOwnProperty(p)) continue;
- kernel.addSubKernelProperty(p, _functions[p]);
- }
- }
-
- return kernel;
- }
-
-
- }, {
- key: 'combineKernels',
- value: function combineKernels() {
- var lastKernel = arguments[arguments.length - 2];
- var combinedKernel = arguments[arguments.length - 1];
- if (this.getMode() === 'cpu') return combinedKernel;
-
- var canvas = arguments[0].getCanvas();
- var webGl = arguments[0].getWebGl();
-
- for (var i = 0; i < arguments.length - 1; i++) {
- arguments[i].setCanvas(canvas).setWebGl(webGl).setOutputToTexture(true);
- }
-
- return function () {
- combinedKernel.apply(null, arguments);
- var texSize = lastKernel.texSize;
- var gl = lastKernel.getWebGl();
- var threadDim = lastKernel.threadDim;
- var result = void 0;
- if (lastKernel.floatOutput) {
- result = new Float32Array(texSize[0] * texSize[1] * 4);
- gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.FLOAT, result);
- } else {
- var bytes = new Uint8Array(texSize[0] * texSize[1] * 4);
- gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, bytes);
- result = new Float32Array(bytes.buffer);
- }
-
- result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]);
-
- if (lastKernel.output.length === 1) {
- return result;
- } else if (lastKernel.output.length === 2) {
- return utils.splitArray(result, lastKernel.output[0]);
- } else if (lastKernel.output.length === 3) {
- var cube = utils.splitArray(result, lastKernel.output[0] * lastKernel.output[1]);
- return cube.map(function (x) {
- return utils.splitArray(x, lastKernel.output[0]);
- });
- }
- };
- }
-
-
- }, {
- key: 'addFunction',
- value: function addFunction(fn, paramTypes, returnType) {
- this._runner.functionBuilder.addFunction(null, fn, paramTypes, returnType);
- return this;
- }
-
-
- }, {
- key: 'addNativeFunction',
- value: function addNativeFunction(name, nativeFunction) {
- this._runner.functionBuilder.addNativeFunction(name, nativeFunction);
- return this;
- }
-
-
- }, {
- key: 'getMode',
- value: function getMode() {
- return this._runner.getMode();
- }
-
-
- }, {
- key: 'isWebGlSupported',
- value: function isWebGlSupported() {
- return utils.isWebGlSupported();
- }
-
-
- }, {
- key: 'getCanvas',
- value: function getCanvas() {
- return this._canvas;
- }
-
-
- }, {
- key: 'getWebGl',
- value: function getWebGl() {
- return this._webGl;
- }
- }]);
-
- return GPU;
-}(GPUCore);
-
-;
-
-Object.assign(GPU, GPUCore);
-
-module.exports = GPU;
-},{"../backend/cpu/runner":5,"../backend/web-gl/runner":15,"../backend/web-gl/validator-kernel":18,"./gpu-core":20,"./utils":25}],22:[function(require,module,exports){
-"use strict";
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-module.exports = function Input(value, size) {
- _classCallCheck(this, Input);
-
- this.value = value;
- if (Array.isArray(size)) {
- this.size = [];
- for (var i = 0; i < size.length; i++) {
- this.size[i] = size[i];
- }
- while (this.size.length < 3) {
- this.size.push(1);
- }
- } else {
- if (size.z) {
- this.size = [size.x, size.y, size.z];
- } else if (size.y) {
- this.size = [size.x, size.y, 1];
- } else {
- this.size = [size.x, 1, 1];
- }
- }
-};
-},{}],23:[function(require,module,exports){
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var gpu = null;
-
-module.exports = function () {
-
- function Texture(texture, size, output, webGl) {
- _classCallCheck(this, Texture);
-
- this.texture = texture;
- this.size = size;
- this.output = output;
- this.webGl = webGl;
- this.kernel = null;
- }
-
-
-
- _createClass(Texture, [{
- key: 'toArray',
- value: function toArray(gpu) {
- if (!gpu) throw new Error('You need to pass the GPU object for toArray to work.');
- if (this.kernel) return this.kernel(this);
-
- this.kernel = gpu.createKernel(function (x) {
- return x[this.thread.z][this.thread.y][this.thread.x];
- }).setOutput(this.output);
-
- return this.kernel(this);
- }
-
-
- }, {
- key: 'delete',
- value: function _delete() {
- return this.webGl.deleteTexture(this.texture);
- }
- }]);
-
- return Texture;
-}();
-},{}],24:[function(require,module,exports){
-'use strict';
-
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var UtilsCore = function () {
- function UtilsCore() {
- _classCallCheck(this, UtilsCore);
- }
-
- _createClass(UtilsCore, null, [{
- key: 'isCanvas',
-
-
-
-
-
- value: function isCanvas(canvasObj) {
- return canvasObj !== null && canvasObj.nodeName && canvasObj.getContext && canvasObj.nodeName.toUpperCase() === 'CANVAS';
- }
-
-
- }, {
- key: 'isCanvasSupported',
- value: function isCanvasSupported() {
- return _isCanvasSupported;
- }
-
-
- }, {
- key: 'initCanvas',
- value: function initCanvas() {
- if (!_isCanvasSupported) {
- return null;
- }
-
- var canvas = document.createElement('canvas');
-
- canvas.width = 2;
- canvas.height = 2;
-
- return canvas;
- }
-
-
-
-
- }, {
- key: 'isWebGl',
- value: function isWebGl(webGlObj) {
- return webGlObj && typeof webGlObj.getExtension === 'function';
- }
-
-
- }, {
- key: 'isWebGlSupported',
- value: function isWebGlSupported() {
- return _isWebGlSupported;
- }
- }, {
- key: 'isWebGlDrawBuffersSupported',
- value: function isWebGlDrawBuffersSupported() {
- return _isWebGlDrawBuffersSupported;
- }
-
-
- }, {
- key: 'initWebGlDefaultOptions',
- value: function initWebGlDefaultOptions() {
- return {
- alpha: false,
- depth: false,
- antialias: false
- };
- }
-
-
- }, {
- key: 'initWebGl',
- value: function initWebGl(canvasObj) {
-
- if (typeof _isCanvasSupported !== 'undefined' || canvasObj === null) {
- if (!_isCanvasSupported) {
- return null;
- }
- }
-
- if (!UtilsCore.isCanvas(canvasObj)) {
- throw new Error('Invalid canvas object - ' + canvasObj);
- }
-
- var webGl = canvasObj.getContext('experimental-webgl', UtilsCore.initWebGlDefaultOptions()) || canvasObj.getContext('webgl', UtilsCore.initWebGlDefaultOptions());
-
- if (webGl) {
- webGl.OES_texture_float = webGl.getExtension('OES_texture_float');
- webGl.OES_texture_float_linear = webGl.getExtension('OES_texture_float_linear');
- webGl.OES_element_index_uint = webGl.getExtension('OES_element_index_uint');
- }
-
- return webGl;
- }
- }]);
-
- return UtilsCore;
-}();
-
-
-var _isCanvasSupported = typeof document !== 'undefined' ? UtilsCore.isCanvas(document.createElement('canvas')) : false;
-var _testingWebGl = UtilsCore.initWebGl(UtilsCore.initCanvas());
-var _isWebGlSupported = UtilsCore.isWebGl(_testingWebGl);
-var _isWebGlDrawBuffersSupported = _isWebGlSupported && Boolean(_testingWebGl.getExtension('WEBGL_draw_buffers'));
-
-if (_isWebGlSupported) {
- UtilsCore.OES_texture_float = _testingWebGl.OES_texture_float;
- UtilsCore.OES_texture_float_linear = _testingWebGl.OES_texture_float_linear;
- UtilsCore.OES_element_index_uint = _testingWebGl.OES_element_index_uint;
-} else {
- UtilsCore.OES_texture_float = false;
- UtilsCore.OES_texture_float_linear = false;
- UtilsCore.OES_element_index_uint = false;
-}
-
-module.exports = UtilsCore;
-},{}],25:[function(require,module,exports){
-'use strict';
-
-
-var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var UtilsCore = require("./utils-core");
-var Input = require('./input');
-var Texture = require('./texture');
-var FUNCTION_NAME = /function ([^(]*)/;
-
-var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
-
-var ARGUMENT_NAMES = /([^\s,]+)/g;
-
-var _systemEndianness = function () {
- var b = new ArrayBuffer(4);
- var a = new Uint32Array(b);
- var c = new Uint8Array(b);
- a[0] = 0xdeadbeef;
- if (c[0] === 0xef) return 'LE';
- if (c[0] === 0xde) return 'BE';
- throw new Error('unknown endianness');
-}();
-
-var _isFloatReadPixelsSupported = null;
-
-var Utils = function (_UtilsCore) {
- _inherits(Utils, _UtilsCore);
-
- function Utils() {
- _classCallCheck(this, Utils);
-
- return _possibleConstructorReturn(this, (Utils.__proto__ || Object.getPrototypeOf(Utils)).apply(this, arguments));
- }
-
- _createClass(Utils, null, [{
- key: 'systemEndianness',
-
-
-
- value: function systemEndianness() {
- return _systemEndianness;
- }
-
-
-
- }, {
- key: 'isFunction',
- value: function isFunction(funcObj) {
- return typeof funcObj === 'function';
- }
-
-
- }, {
- key: 'isFunctionString',
- value: function isFunctionString(funcStr) {
- if (funcStr !== null) {
- return funcStr.toString().slice(0, 'function'.length).toLowerCase() === 'function';
- }
- return false;
- }
-
-
- }, {
- key: 'getFunctionNameFromString',
- value: function getFunctionNameFromString(funcStr) {
- return FUNCTION_NAME.exec(funcStr)[1];
- }
- }, {
- key: 'getFunctionBodyFromString',
- value: function getFunctionBodyFromString(funcStr) {
- return funcStr.substring(funcStr.indexOf('{') + 1, funcStr.lastIndexOf('}'));
- }
-
-
- }, {
- key: 'getParamNamesFromString',
- value: function getParamNamesFromString(func) {
- var fnStr = func.toString().replace(STRIP_COMMENTS, '');
- var result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
- if (result === null) result = [];
- return result;
- }
-
-
-
- }, {
- key: 'clone',
- value: function clone(obj) {
- if (obj === null || (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) !== 'object' || obj.hasOwnProperty('isActiveClone')) return obj;
-
- var temp = obj.constructor();
-
- for (var key in obj) {
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
- obj.isActiveClone = null;
- temp[key] = Utils.clone(obj[key]);
- delete obj.isActiveClone;
- }
- }
-
- return temp;
- }
-
-
- }, {
- key: 'newPromise',
- value: function newPromise(executor) {
- var simple = Promise || small_promise;
- if (simple === null) {
- throw TypeError('Browser is missing Promise implementation. Consider adding small_promise.js polyfill');
- }
- return new simple(executor);
- }
-
-
- }, {
- key: 'functionBinder',
- value: function functionBinder(inFunc, thisObj) {
- if (inFunc.bind) {
- return inFunc.bind(thisObj);
- }
-
- return function () {
- var args = arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments);
- return inFunc.apply(thisObj, args);
- };
- }
-
-
- }, {
- key: 'isArray',
- value: function isArray(array) {
- if (isNaN(array.length)) {
- return false;
- }
-
- return true;
- }
-
-
- }, {
- key: 'getArgumentType',
- value: function getArgumentType(arg) {
- if (Utils.isArray(arg)) {
- return 'Array';
- } else if (typeof arg === 'number') {
- return 'Number';
- } else if (arg instanceof Texture) {
- return 'Texture';
- } else if (arg instanceof Input) {
- return 'Input';
- } else {
- return 'Unknown';
- }
- }
-
-
- }, {
- key: 'isFloatReadPixelsSupported',
- value: function isFloatReadPixelsSupported() {
- if (_isFloatReadPixelsSupported !== null) {
- return _isFloatReadPixelsSupported;
- }
-
- var GPU = require('../index');
- var x = new GPU({
- mode: 'webgl-validator'
- }).createKernel(function () {
- return 1;
- }, {
- output: [2],
- floatTextures: true,
- floatOutput: true,
- floatOutputForce: true
- })();
-
- _isFloatReadPixelsSupported = x[0] === 1;
-
- return _isFloatReadPixelsSupported;
- }
- }, {
- key: 'dimToTexSize',
- value: function dimToTexSize(opt, dimensions, output) {
- var numTexels = dimensions[0];
- for (var i = 1; i < dimensions.length; i++) {
- numTexels *= dimensions[i];
- }
-
- if (opt.floatTextures && (!output || opt.floatOutput)) {
- numTexels = Math.ceil(numTexels / 4);
- }
-
- var w = Math.ceil(Math.sqrt(numTexels));
- return [w, w];
- }
-
-
- }, {
- key: 'getDimensions',
- value: function getDimensions(x, pad) {
- var ret = void 0;
- if (Utils.isArray(x)) {
- var dim = [];
- var temp = x;
- while (Utils.isArray(temp)) {
- dim.push(temp.length);
- temp = temp[0];
- }
- ret = dim.reverse();
- } else if (x instanceof Texture) {
- ret = x.output;
- } else if (x instanceof Input) {
- ret = x.size;
- } else {
- throw 'Unknown dimensions of ' + x;
- }
-
- if (pad) {
- ret = Utils.clone(ret);
- while (ret.length < 3) {
- ret.push(1);
- }
- }
-
- return ret;
- }
-
-
- }, {
- key: 'pad',
- value: function pad(arr, padding) {
- function zeros(n) {
- return Array.apply(null, new Array(n)).map(Number.prototype.valueOf, 0);
- }
-
- var len = arr.length + padding * 2;
-
- var ret = arr.map(function (x) {
- return [].concat(zeros(padding), x, zeros(padding));
- });
-
- for (var i = 0; i < padding; i++) {
- ret = [].concat([zeros(len)], ret, [zeros(len)]);
- }
-
- return ret;
- }
-
-
- }, {
- key: 'flatten2dArrayTo',
- value: function flatten2dArrayTo(array, target) {
- var offset = 0;
- for (var y = 0; y < array.length; y++) {
- target.set(array[y], offset);
- offset += array[y].length;
- }
- }
-
-
- }, {
- key: 'flatten3dArrayTo',
- value: function flatten3dArrayTo(array, target) {
- var offset = 0;
- for (var z = 0; z < array.length; z++) {
- for (var y = 0; y < array[z].length; y++) {
- target.set(array[z][y], offset);
- offset += array[z][y].length;
- }
- }
- }
-
-
- }, {
- key: 'flattenTo',
- value: function flattenTo(array, target) {
- if (Utils.isArray(array[0])) {
- if (Utils.isArray(array[0][0])) {
- Utils.flatten3dArrayTo(array, target);
- } else {
- Utils.flatten2dArrayTo(array, target);
- }
- } else {
- target.set(array);
- }
- }
-
-
- }, {
- key: 'splitArray',
- value: function splitArray(array, part) {
- var result = [];
- for (var i = 0; i < array.length; i += part) {
- result.push(Array.prototype.slice.call(array, i, i + part));
- }
- return result;
- }
- }, {
- key: 'getAstString',
- value: function getAstString(source, ast) {
- var lines = Array.isArray(source) ? source : source.split(/\r?\n/g);
- var start = ast.loc.start;
- var end = ast.loc.end;
- var result = [];
- result.push(lines[start.line - 1].slice(start.column));
- for (var i = start.line; i < end.line - 1; i++) {
- result.push(lines[i]);
- }
- result.push(lines[end.line - 1].slice(0, end.column));
- return result.join('\n');
- }
- }, {
- key: 'allPropertiesOf',
- value: function allPropertiesOf(obj) {
- var props = [];
-
- do {
- props.push.apply(props, Object.getOwnPropertyNames(obj));
- } while (obj = Object.getPrototypeOf(obj));
-
- return props;
- }
- }]);
-
- return Utils;
-}(UtilsCore);
-
-
-
-Object.assign(Utils, UtilsCore);
-
-module.exports = Utils;
-},{"../index":26,"./input":22,"./texture":23,"./utils-core":24}],26:[function(require,module,exports){
-'use strict';
-
-var GPU = require('./core/gpu');
-var alias = require('./core/alias');
-var utils = require('./core/utils');
-var Input = require('./core/input');
-var Texture = require('./core/texture');
-
-var CPUFunctionBuilder = require('./backend/cpu/function-builder');
-var CPUFunctionNode = require('./backend/cpu/function-node');
-var CPUKernel = require('./backend/cpu/kernel');
-var CPURunner = require('./backend/cpu/runner');
-
-var WebGLFunctionBuilder = require('./backend/web-gl/function-builder');
-var WebGLFunctionNode = require('./backend/web-gl/function-node');
-var WebGLKernel = require('./backend/web-gl/kernel');
-var WebGLRunner = require('./backend/web-gl/runner');
-
-GPU.alias = alias;
-GPU.utils = utils;
-GPU.Texture = Texture;
-GPU.Input = Input;
-GPU.input = function (value, size) {
- return new Input(value, size);
-};
-
-GPU.CPUFunctionBuilder = CPUFunctionBuilder;
-GPU.CPUFunctionNode = CPUFunctionNode;
-GPU.CPUKernel = CPUKernel;
-GPU.CPURunner = CPURunner;
-
-GPU.WebGLFunctionBuilder = WebGLFunctionBuilder;
-GPU.WebGLFunctionNode = WebGLFunctionNode;
-GPU.WebGLKernel = WebGLKernel;
-GPU.WebGLRunner = WebGLRunner;
-
-if (typeof module !== 'undefined') {
- module.exports = GPU;
-}
-if (typeof window !== 'undefined') {
- window.GPU = GPU;
-}
-},{"./backend/cpu/function-builder":1,"./backend/cpu/function-node":2,"./backend/cpu/kernel":4,"./backend/cpu/runner":5,"./backend/web-gl/function-builder":11,"./backend/web-gl/function-node":12,"./backend/web-gl/kernel":14,"./backend/web-gl/runner":15,"./core/alias":19,"./core/gpu":21,"./core/input":22,"./core/texture":23,"./core/utils":25}],27:[function(require,module,exports){
-(function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
- (factory((global.acorn = global.acorn || {})));
-}(this, (function (exports) { 'use strict';
-
-
-var reservedWords = {
- 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"
-};
-
-
-var ecma5AndLessKeywords = "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";
-
-var keywords = {
- 5: ecma5AndLessKeywords,
- 6: ecma5AndLessKeywords + " const class extends export import super"
-};
-
-
-
-var nonASCIIidentifierStartChars = "\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\u0561-\u0587\u05d0-\u05ea\u05f0-\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\u08a0-\u08b4\u08b6-\u08bd\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\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\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\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\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\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-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\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-\u2c2e\u2c30-\u2c5e\u2c60-\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-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fd5\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ae\ua7b0-\ua7b7\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\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-\uab65\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";
-var nonASCIIidentifierChars = "\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\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d4-\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\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\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c03\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\u0d01-\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\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-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\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\u1cf2-\u1cf4\u1cf8\u1cf9\u1dc0-\u1df5\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\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";
-
-var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
-var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
-
-nonASCIIidentifierStartChars = nonASCIIidentifierChars = null;
-
-
-var astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,17,26,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,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,26,45,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,785,52,76,44,33,24,27,35,42,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,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,159,52,19,3,54,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,86,25,391,63,32,0,449,56,264,8,2,36,18,0,50,29,881,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,881,68,12,0,67,12,65,0,32,6124,20,754,9486,1,3071,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,4149,196,60,67,1213,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,42710,42,4148,12,221,3,5761,10591,541];
-
-var astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,1306,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,52,0,13,2,49,13,10,2,4,9,83,11,7,0,161,11,6,9,7,3,57,0,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,87,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,423,9,838,7,2,7,17,9,57,21,2,13,19882,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,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,2214,6,110,6,6,9,792487,239];
-
-function isInAstralSet(code, set) {
- var pos = 0x10000;
- for (var i = 0; i < set.length; i += 2) {
- pos += set[i];
- if (pos > code) { return false }
- pos += set[i + 1];
- if (pos >= code) { return true }
- }
-}
-
-
-function isIdentifierStart(code, astral) {
- if (code < 65) { return code === 36 }
- if (code < 91) { return true }
- if (code < 97) { return code === 95 }
- if (code < 123) { return true }
- if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) }
- if (astral === false) { return false }
- return isInAstralSet(code, astralIdentifierStartCodes)
-}
-
-
-function isIdentifierChar(code, astral) {
- if (code < 48) { return code === 36 }
- if (code < 58) { return true }
- if (code < 65) { return false }
- if (code < 91) { return true }
- if (code < 97) { return code === 95 }
- if (code < 123) { return true }
- if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) }
- if (astral === false) { return false }
- return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes)
-}
-
-
-
-
-
-var TokenType = function TokenType(label, conf) {
- if ( conf === void 0 ) conf = {};
-
- this.label = label;
- this.keyword = conf.keyword;
- this.beforeExpr = !!conf.beforeExpr;
- this.startsExpr = !!conf.startsExpr;
- this.isLoop = !!conf.isLoop;
- this.isAssign = !!conf.isAssign;
- this.prefix = !!conf.prefix;
- this.postfix = !!conf.postfix;
- this.binop = conf.binop || null;
- this.updateContext = null;
-};
-
-function binop(name, prec) {
- return new TokenType(name, {beforeExpr: true, binop: prec})
-}
-var beforeExpr = {beforeExpr: true};
-var startsExpr = {startsExpr: true};
-
-
-var keywords$1 = {};
-
-function kw(name, options) {
- if ( options === void 0 ) options = {};
-
- options.keyword = name;
- return keywords$1[name] = new TokenType(name, options)
-}
-
-var types = {
- num: new TokenType("num", startsExpr),
- regexp: new TokenType("regexp", startsExpr),
- string: new TokenType("string", startsExpr),
- name: new TokenType("name", startsExpr),
- eof: new TokenType("eof"),
-
- bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}),
- bracketR: new TokenType("]"),
- braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}),
- braceR: new TokenType("}"),
- parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}),
- parenR: new TokenType(")"),
- comma: new TokenType(",", beforeExpr),
- semi: new TokenType(";", beforeExpr),
- colon: new TokenType(":", beforeExpr),
- dot: new TokenType("."),
- question: new TokenType("?", beforeExpr),
- arrow: new TokenType("=>", beforeExpr),
- template: new TokenType("template"),
- invalidTemplate: new TokenType("invalidTemplate"),
- ellipsis: new TokenType("...", beforeExpr),
- backQuote: new TokenType("`", startsExpr),
- dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}),
-
-
- eq: new TokenType("=", {beforeExpr: true, isAssign: true}),
- assign: new TokenType("_=", {beforeExpr: true, isAssign: true}),
- incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}),
- prefix: new TokenType("prefix", {beforeExpr: true, prefix: true, startsExpr: true}),
- logicalOR: binop("||", 1),
- logicalAND: binop("&&", 2),
- bitwiseOR: binop("|", 3),
- bitwiseXOR: binop("^", 4),
- bitwiseAND: binop("&", 5),
- equality: binop("==/!=", 6),
- relational: binop(">", 7),
- bitShift: binop("<>>", 8),
- plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}),
- modulo: binop("%", 10),
- star: binop("*", 10),
- slash: binop("/", 10),
- starstar: new TokenType("**", {beforeExpr: true}),
-
- _break: kw("break"),
- _case: kw("case", beforeExpr),
- _catch: kw("catch"),
- _continue: kw("continue"),
- _debugger: kw("debugger"),
- _default: kw("default", beforeExpr),
- _do: kw("do", {isLoop: true, beforeExpr: true}),
- _else: kw("else", beforeExpr),
- _finally: kw("finally"),
- _for: kw("for", {isLoop: true}),
- _function: kw("function", startsExpr),
- _if: kw("if"),
- _return: kw("return", beforeExpr),
- _switch: kw("switch"),
- _throw: kw("throw", beforeExpr),
- _try: kw("try"),
- _var: kw("var"),
- _const: kw("const"),
- _while: kw("while", {isLoop: true}),
- _with: kw("with"),
- _new: kw("new", {beforeExpr: true, startsExpr: true}),
- _this: kw("this", startsExpr),
- _super: kw("super", startsExpr),
- _class: kw("class", startsExpr),
- _extends: kw("extends", beforeExpr),
- _export: kw("export"),
- _import: kw("import"),
- _null: kw("null", startsExpr),
- _true: kw("true", startsExpr),
- _false: kw("false", startsExpr),
- _in: kw("in", {beforeExpr: true, binop: 7}),
- _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}),
- _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}),
- _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}),
- _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true})
-};
-
-
-var lineBreak = /\r\n?|\n|\u2028|\u2029/;
-var lineBreakG = new RegExp(lineBreak.source, "g");
-
-function isNewLine(code) {
- return code === 10 || code === 13 || code === 0x2028 || code === 0x2029
-}
-
-var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
-
-var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g;
-
-var ref = Object.prototype;
-var hasOwnProperty = ref.hasOwnProperty;
-var toString = ref.toString;
-
-
-function has(obj, propName) {
- return hasOwnProperty.call(obj, propName)
-}
-
-var isArray = Array.isArray || (function (obj) { return (
- toString.call(obj) === "[object Array]"
-); });
-
-
-var Position = function Position(line, col) {
- this.line = line;
- this.column = col;
-};
-
-Position.prototype.offset = function offset (n) {
- return new Position(this.line, this.column + n)
-};
-
-var SourceLocation = function SourceLocation(p, start, end) {
- this.start = start;
- this.end = end;
- if (p.sourceFile !== null) { this.source = p.sourceFile; }
-};
-
-
-function getLineInfo(input, offset) {
- for (var line = 1, cur = 0;;) {
- lineBreakG.lastIndex = cur;
- var match = lineBreakG.exec(input);
- if (match && match.index < offset) {
- ++line;
- cur = match.index + match[0].length;
- } else {
- return new Position(line, offset - cur)
- }
- }
-}
-
-
-var defaultOptions = {
- ecmaVersion: 7,
- sourceType: "script",
- onInsertedSemicolon: null,
- onTrailingComma: null,
- allowReserved: null,
- allowReturnOutsideFunction: false,
- allowImportExportEverywhere: false,
- allowHashBang: false,
- locations: false,
- onToken: null,
- onComment: null,
- ranges: false,
- program: null,
- sourceFile: null,
- directSourceFile: null,
- preserveParens: false,
- plugins: {}
-};
-
-
-function getOptions(opts) {
- var options = {};
-
- for (var opt in defaultOptions)
- { options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]; }
-
- if (options.ecmaVersion >= 2015)
- { options.ecmaVersion -= 2009; }
-
- if (options.allowReserved == null)
- { options.allowReserved = options.ecmaVersion < 5; }
-
- if (isArray(options.onToken)) {
- var tokens = options.onToken;
- options.onToken = function (token) { return tokens.push(token); };
- }
- if (isArray(options.onComment))
- { options.onComment = pushComment(options, options.onComment); }
-
- return options
-}
-
-function pushComment(options, array) {
- return function(block, text, start, end, startLoc, endLoc) {
- var comment = {
- type: block ? "Block" : "Line",
- value: text,
- start: start,
- end: end
- };
- if (options.locations)
- { comment.loc = new SourceLocation(this, startLoc, endLoc); }
- if (options.ranges)
- { comment.range = [start, end]; }
- array.push(comment);
- }
-}
-
-var plugins = {};
-
-function keywordRegexp(words) {
- return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$")
-}
-
-var Parser = function Parser(options, input, startPos) {
- this.options = options = getOptions(options);
- this.sourceFile = options.sourceFile;
- this.keywords = keywordRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]);
- var reserved = "";
- if (!options.allowReserved) {
- for (var v = options.ecmaVersion;; v--)
- { if (reserved = reservedWords[v]) { break } }
- if (options.sourceType == "module") { reserved += " await"; }
- }
- this.reservedWords = keywordRegexp(reserved);
- var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict;
- this.reservedWordsStrict = keywordRegexp(reservedStrict);
- this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + reservedWords.strictBind);
- this.input = String(input);
-
- this.containsEsc = false;
-
- this.loadPlugins(options.plugins);
-
-
- if (startPos) {
- this.pos = startPos;
- this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1;
- this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length;
- } else {
- this.pos = this.lineStart = 0;
- this.curLine = 1;
- }
-
- this.type = types.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 = true;
-
- this.inModule = options.sourceType === "module";
- this.strict = this.inModule || this.strictDirective(this.pos);
-
- this.potentialArrowAt = -1;
-
- this.inFunction = this.inGenerator = this.inAsync = false;
- this.yieldPos = this.awaitPos = 0;
- this.labels = [];
-
- if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!")
- { this.skipLineComment(2); }
-
- this.scopeStack = [];
- this.enterFunctionScope();
-};
-
-Parser.prototype.isKeyword = function isKeyword (word) { return this.keywords.test(word) };
-Parser.prototype.isReservedWord = function isReservedWord (word) { return this.reservedWords.test(word) };
-
-Parser.prototype.extend = function extend (name, f) {
- this[name] = f(this[name]);
-};
-
-Parser.prototype.loadPlugins = function loadPlugins (pluginConfigs) {
- var this$1 = this;
-
- for (var name in pluginConfigs) {
- var plugin = plugins[name];
- if (!plugin) { throw new Error("Plugin '" + name + "' not found") }
- plugin(this$1, pluginConfigs[name]);
- }
-};
-
-Parser.prototype.parse = function parse () {
- var node = this.options.program || this.startNode();
- this.nextToken();
- return this.parseTopLevel(node)
-};
-
-var pp = Parser.prototype;
-
-
-var literal = /^(?:'((?:[^']|\.)*)'|"((?:[^"]|\.)*)"|;)/;
-pp.strictDirective = function(start) {
- var this$1 = this;
-
- for (;;) {
- skipWhiteSpace.lastIndex = start;
- start += skipWhiteSpace.exec(this$1.input)[0].length;
- var match = literal.exec(this$1.input.slice(start));
- if (!match) { return false }
- if ((match[1] || match[2]) == "use strict") { return true }
- start += match[0].length;
- }
-};
-
-
-pp.eat = function(type) {
- if (this.type === type) {
- this.next();
- return true
- } else {
- return false
- }
-};
-
-
-pp.isContextual = function(name) {
- return this.type === types.name && this.value === name
-};
-
-
-pp.eatContextual = function(name) {
- return this.value === name && this.eat(types.name)
-};
-
-
-pp.expectContextual = function(name) {
- if (!this.eatContextual(name)) { this.unexpected(); }
-};
-
-
-pp.canInsertSemicolon = function() {
- return this.type === types.eof ||
- this.type === types.braceR ||
- lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
-};
-
-pp.insertSemicolon = function() {
- if (this.canInsertSemicolon()) {
- if (this.options.onInsertedSemicolon)
- { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); }
- return true
- }
-};
-
-
-pp.semicolon = function() {
- if (!this.eat(types.semi) && !this.insertSemicolon()) { this.unexpected(); }
-};
-
-pp.afterTrailingComma = function(tokType, notNext) {
- if (this.type == tokType) {
- if (this.options.onTrailingComma)
- { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); }
- if (!notNext)
- { this.next(); }
- return true
- }
-};
-
-
-pp.expect = function(type) {
- this.eat(type) || this.unexpected();
-};
-
-
-pp.unexpected = function(pos) {
- this.raise(pos != null ? pos : this.start, "Unexpected token");
-};
-
-function DestructuringErrors() {
- this.shorthandAssign =
- this.trailingComma =
- this.parenthesizedAssign =
- this.parenthesizedBind =
- -1;
-}
-
-pp.checkPatternErrors = function(refDestructuringErrors, isAssign) {
- if (!refDestructuringErrors) { return }
- if (refDestructuringErrors.trailingComma > -1)
- { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); }
- var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind;
- if (parens > -1) { this.raiseRecoverable(parens, "Parenthesized pattern"); }
-};
-
-pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) {
- var pos = refDestructuringErrors ? refDestructuringErrors.shorthandAssign : -1;
- if (!andThrow) { return pos >= 0 }
- if (pos > -1) { this.raise(pos, "Shorthand property assignments are valid only in destructuring patterns"); }
-};
-
-pp.checkYieldAwaitInDefaultParams = function() {
- if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos))
- { this.raise(this.yieldPos, "Yield expression cannot be a default value"); }
- if (this.awaitPos)
- { this.raise(this.awaitPos, "Await expression cannot be a default value"); }
-};
-
-pp.isSimpleAssignTarget = function(expr) {
- if (expr.type === "ParenthesizedExpression")
- { return this.isSimpleAssignTarget(expr.expression) }
- return expr.type === "Identifier" || expr.type === "MemberExpression"
-};
-
-var pp$1 = Parser.prototype;
-
-
-
-pp$1.parseTopLevel = function(node) {
- var this$1 = this;
-
- var exports = {};
- if (!node.body) { node.body = []; }
- while (this.type !== types.eof) {
- var stmt = this$1.parseStatement(true, true, exports);
- node.body.push(stmt);
- }
- this.next();
- if (this.options.ecmaVersion >= 6) {
- node.sourceType = this.options.sourceType;
- }
- return this.finishNode(node, "Program")
-};
-
-var loopLabel = {kind: "loop"};
-var switchLabel = {kind: "switch"};
-
-pp$1.isLet = function() {
- if (this.type !== types.name || this.options.ecmaVersion < 6 || this.value != "let") { return false }
- skipWhiteSpace.lastIndex = this.pos;
- var skip = skipWhiteSpace.exec(this.input);
- var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);
- if (nextCh === 91 || nextCh == 123) { return true }
- if (isIdentifierStart(nextCh, true)) {
- var pos = next + 1;
- while (isIdentifierChar(this.input.charCodeAt(pos), true)) { ++pos; }
- var ident = this.input.slice(next, pos);
- if (!this.isKeyword(ident)) { return true }
- }
- return false
-};
-
-pp$1.isAsyncFunction = function() {
- if (this.type !== types.name || this.options.ecmaVersion < 8 || this.value != "async")
- { return false }
-
- skipWhiteSpace.lastIndex = this.pos;
- var skip = skipWhiteSpace.exec(this.input);
- var next = this.pos + skip[0].length;
- return !lineBreak.test(this.input.slice(this.pos, next)) &&
- this.input.slice(next, next + 8) === "function" &&
- (next + 8 == this.input.length || !isIdentifierChar(this.input.charAt(next + 8)))
-};
-
-
-pp$1.parseStatement = function(declaration, topLevel, exports) {
- var starttype = this.type, node = this.startNode(), kind;
-
- if (this.isLet()) {
- starttype = types._var;
- kind = "let";
- }
-
-
- switch (starttype) {
- case types._break: case types._continue: return this.parseBreakContinueStatement(node, starttype.keyword)
- case types._debugger: return this.parseDebuggerStatement(node)
- case types._do: return this.parseDoStatement(node)
- case types._for: return this.parseForStatement(node)
- case types._function:
- if (!declaration && this.options.ecmaVersion >= 6) { this.unexpected(); }
- return this.parseFunctionStatement(node, false)
- case types._class:
- if (!declaration) { this.unexpected(); }
- return this.parseClass(node, true)
- case types._if: return this.parseIfStatement(node)
- case types._return: return this.parseReturnStatement(node)
- case types._switch: return this.parseSwitchStatement(node)
- case types._throw: return this.parseThrowStatement(node)
- case types._try: return this.parseTryStatement(node)
- case types._const: case types._var:
- kind = kind || this.value;
- if (!declaration && kind != "var") { this.unexpected(); }
- return this.parseVarStatement(node, kind)
- case types._while: return this.parseWhileStatement(node)
- case types._with: return this.parseWithStatement(node)
- case types.braceL: return this.parseBlock()
- case types.semi: return this.parseEmptyStatement(node)
- case types._export:
- case types._import:
- if (!this.options.allowImportExportEverywhere) {
- if (!topLevel)
- { this.raise(this.start, "'import' and 'export' may only appear at the top level"); }
- if (!this.inModule)
- { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); }
- }
- return starttype === types._import ? this.parseImport(node) : this.parseExport(node, exports)
-
- default:
- if (this.isAsyncFunction() && declaration) {
- this.next();
- return this.parseFunctionStatement(node, true)
- }
-
- var maybeName = this.value, expr = this.parseExpression();
- if (starttype === types.name && expr.type === "Identifier" && this.eat(types.colon))
- { return this.parseLabeledStatement(node, maybeName, expr) }
- else { return this.parseExpressionStatement(node, expr) }
- }
-};
-
-pp$1.parseBreakContinueStatement = function(node, keyword) {
- var this$1 = this;
-
- var isBreak = keyword == "break";
- this.next();
- if (this.eat(types.semi) || this.insertSemicolon()) { node.label = null; }
- else if (this.type !== types.name) { this.unexpected(); }
- else {
- node.label = this.parseIdent();
- this.semicolon();
- }
-
- var i = 0;
- for (; i < this.labels.length; ++i) {
- var lab = this$1.labels[i];
- if (node.label == null || lab.name === node.label.name) {
- if (lab.kind != null && (isBreak || lab.kind === "loop")) { break }
- if (node.label && isBreak) { break }
- }
- }
- if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); }
- return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement")
-};
-
-pp$1.parseDebuggerStatement = function(node) {
- this.next();
- this.semicolon();
- return this.finishNode(node, "DebuggerStatement")
-};
-
-pp$1.parseDoStatement = function(node) {
- this.next();
- this.labels.push(loopLabel);
- node.body = this.parseStatement(false);
- this.labels.pop();
- this.expect(types._while);
- node.test = this.parseParenExpression();
- if (this.options.ecmaVersion >= 6)
- { this.eat(types.semi); }
- else
- { this.semicolon(); }
- return this.finishNode(node, "DoWhileStatement")
-};
-
-
-pp$1.parseForStatement = function(node) {
- this.next();
- this.labels.push(loopLabel);
- this.enterLexicalScope();
- this.expect(types.parenL);
- if (this.type === types.semi) { return this.parseFor(node, null) }
- var isLet = this.isLet();
- if (this.type === types._var || this.type === types._const || isLet) {
- var init$1 = this.startNode(), kind = isLet ? "let" : this.value;
- this.next();
- this.parseVar(init$1, true, kind);
- this.finishNode(init$1, "VariableDeclaration");
- if ((this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1 &&
- !(kind !== "var" && init$1.declarations[0].init))
- { return this.parseForIn(node, init$1) }
- return this.parseFor(node, init$1)
- }
- var refDestructuringErrors = new DestructuringErrors;
- var init = this.parseExpression(true, refDestructuringErrors);
- if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
- this.toAssignable(init);
- this.checkLVal(init);
- this.checkPatternErrors(refDestructuringErrors, true);
- return this.parseForIn(node, init)
- } else {
- this.checkExpressionErrors(refDestructuringErrors, true);
- }
- return this.parseFor(node, init)
-};
-
-pp$1.parseFunctionStatement = function(node, isAsync) {
- this.next();
- return this.parseFunction(node, true, false, isAsync)
-};
-
-pp$1.isFunction = function() {
- return this.type === types._function || this.isAsyncFunction()
-};
-
-pp$1.parseIfStatement = function(node) {
- this.next();
- node.test = this.parseParenExpression();
- node.consequent = this.parseStatement(!this.strict && this.isFunction());
- node.alternate = this.eat(types._else) ? this.parseStatement(!this.strict && this.isFunction()) : null;
- return this.finishNode(node, "IfStatement")
-};
-
-pp$1.parseReturnStatement = function(node) {
- if (!this.inFunction && !this.options.allowReturnOutsideFunction)
- { this.raise(this.start, "'return' outside of function"); }
- this.next();
-
-
- if (this.eat(types.semi) || this.insertSemicolon()) { node.argument = null; }
- else { node.argument = this.parseExpression(); this.semicolon(); }
- return this.finishNode(node, "ReturnStatement")
-};
-
-pp$1.parseSwitchStatement = function(node) {
- var this$1 = this;
-
- this.next();
- node.discriminant = this.parseParenExpression();
- node.cases = [];
- this.expect(types.braceL);
- this.labels.push(switchLabel);
- this.enterLexicalScope();
-
-
- var cur;
- for (var sawDefault = false; this.type != types.braceR;) {
- if (this$1.type === types._case || this$1.type === types._default) {
- var isCase = this$1.type === types._case;
- if (cur) { this$1.finishNode(cur, "SwitchCase"); }
- node.cases.push(cur = this$1.startNode());
- cur.consequent = [];
- this$1.next();
- if (isCase) {
- cur.test = this$1.parseExpression();
- } else {
- if (sawDefault) { this$1.raiseRecoverable(this$1.lastTokStart, "Multiple default clauses"); }
- sawDefault = true;
- cur.test = null;
- }
- this$1.expect(types.colon);
- } else {
- if (!cur) { this$1.unexpected(); }
- cur.consequent.push(this$1.parseStatement(true));
- }
- }
- this.exitLexicalScope();
- if (cur) { this.finishNode(cur, "SwitchCase"); }
- this.next();
- this.labels.pop();
- return this.finishNode(node, "SwitchStatement")
-};
-
-pp$1.parseThrowStatement = function(node) {
- this.next();
- if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start)))
- { this.raise(this.lastTokEnd, "Illegal newline after throw"); }
- node.argument = this.parseExpression();
- this.semicolon();
- return this.finishNode(node, "ThrowStatement")
-};
-
-
-var empty = [];
-
-pp$1.parseTryStatement = function(node) {
- this.next();
- node.block = this.parseBlock();
- node.handler = null;
- if (this.type === types._catch) {
- var clause = this.startNode();
- this.next();
- this.expect(types.parenL);
- clause.param = this.parseBindingAtom();
- this.enterLexicalScope();
- this.checkLVal(clause.param, "let");
- this.expect(types.parenR);
- clause.body = this.parseBlock(false);
- this.exitLexicalScope();
- node.handler = this.finishNode(clause, "CatchClause");
- }
- node.finalizer = this.eat(types._finally) ? this.parseBlock() : null;
- if (!node.handler && !node.finalizer)
- { this.raise(node.start, "Missing catch or finally clause"); }
- return this.finishNode(node, "TryStatement")
-};
-
-pp$1.parseVarStatement = function(node, kind) {
- this.next();
- this.parseVar(node, false, kind);
- this.semicolon();
- return this.finishNode(node, "VariableDeclaration")
-};
-
-pp$1.parseWhileStatement = function(node) {
- this.next();
- node.test = this.parseParenExpression();
- this.labels.push(loopLabel);
- node.body = this.parseStatement(false);
- this.labels.pop();
- return this.finishNode(node, "WhileStatement")
-};
-
-pp$1.parseWithStatement = function(node) {
- if (this.strict) { this.raise(this.start, "'with' in strict mode"); }
- this.next();
- node.object = this.parseParenExpression();
- node.body = this.parseStatement(false);
- return this.finishNode(node, "WithStatement")
-};
-
-pp$1.parseEmptyStatement = function(node) {
- this.next();
- return this.finishNode(node, "EmptyStatement")
-};
-
-pp$1.parseLabeledStatement = function(node, maybeName, expr) {
- var this$1 = this;
-
- for (var i$1 = 0, list = this$1.labels; i$1 < list.length; i$1 += 1)
- {
- var label = list[i$1];
-
- if (label.name === maybeName)
- { this$1.raise(expr.start, "Label '" + maybeName + "' is already declared");
- } }
- var kind = this.type.isLoop ? "loop" : this.type === types._switch ? "switch" : null;
- for (var i = this.labels.length - 1; i >= 0; i--) {
- var label$1 = this$1.labels[i];
- if (label$1.statementStart == node.start) {
- label$1.statementStart = this$1.start;
- label$1.kind = kind;
- } else { break }
- }
- this.labels.push({name: maybeName, kind: kind, statementStart: this.start});
- node.body = this.parseStatement(true);
- if (node.body.type == "ClassDeclaration" ||
- node.body.type == "VariableDeclaration" && node.body.kind != "var" ||
- node.body.type == "FunctionDeclaration" && (this.strict || node.body.generator))
- { this.raiseRecoverable(node.body.start, "Invalid labeled declaration"); }
- this.labels.pop();
- node.label = expr;
- return this.finishNode(node, "LabeledStatement")
-};
-
-pp$1.parseExpressionStatement = function(node, expr) {
- node.expression = expr;
- this.semicolon();
- return this.finishNode(node, "ExpressionStatement")
-};
-
-
-pp$1.parseBlock = function(createNewLexicalScope) {
- var this$1 = this;
- if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true;
-
- var node = this.startNode();
- node.body = [];
- this.expect(types.braceL);
- if (createNewLexicalScope) {
- this.enterLexicalScope();
- }
- while (!this.eat(types.braceR)) {
- var stmt = this$1.parseStatement(true);
- node.body.push(stmt);
- }
- if (createNewLexicalScope) {
- this.exitLexicalScope();
- }
- return this.finishNode(node, "BlockStatement")
-};
-
-
-pp$1.parseFor = function(node, init) {
- node.init = init;
- this.expect(types.semi);
- node.test = this.type === types.semi ? null : this.parseExpression();
- this.expect(types.semi);
- node.update = this.type === types.parenR ? null : this.parseExpression();
- this.expect(types.parenR);
- this.exitLexicalScope();
- node.body = this.parseStatement(false);
- this.labels.pop();
- return this.finishNode(node, "ForStatement")
-};
-
-
-pp$1.parseForIn = function(node, init) {
- var type = this.type === types._in ? "ForInStatement" : "ForOfStatement";
- this.next();
- node.left = init;
- node.right = this.parseExpression();
- this.expect(types.parenR);
- this.exitLexicalScope();
- node.body = this.parseStatement(false);
- this.labels.pop();
- return this.finishNode(node, type)
-};
-
-
-pp$1.parseVar = function(node, isFor, kind) {
- var this$1 = this;
-
- node.declarations = [];
- node.kind = kind;
- for (;;) {
- var decl = this$1.startNode();
- this$1.parseVarId(decl, kind);
- if (this$1.eat(types.eq)) {
- decl.init = this$1.parseMaybeAssign(isFor);
- } else if (kind === "const" && !(this$1.type === types._in || (this$1.options.ecmaVersion >= 6 && this$1.isContextual("of")))) {
- this$1.unexpected();
- } else if (decl.id.type != "Identifier" && !(isFor && (this$1.type === types._in || this$1.isContextual("of")))) {
- this$1.raise(this$1.lastTokEnd, "Complex binding patterns require an initialization value");
- } else {
- decl.init = null;
- }
- node.declarations.push(this$1.finishNode(decl, "VariableDeclarator"));
- if (!this$1.eat(types.comma)) { break }
- }
- return node
-};
-
-pp$1.parseVarId = function(decl, kind) {
- decl.id = this.parseBindingAtom(kind);
- this.checkLVal(decl.id, kind, false);
-};
-
-
-pp$1.parseFunction = function(node, isStatement, allowExpressionBody, isAsync) {
- this.initFunction(node);
- if (this.options.ecmaVersion >= 6 && !isAsync)
- { node.generator = this.eat(types.star); }
- if (this.options.ecmaVersion >= 8)
- { node.async = !!isAsync; }
-
- if (isStatement) {
- node.id = isStatement === "nullableID" && this.type != types.name ? null : this.parseIdent();
- if (node.id) {
- this.checkLVal(node.id, "var");
- }
- }
-
- var oldInGen = this.inGenerator, oldInAsync = this.inAsync,
- oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction;
- this.inGenerator = node.generator;
- this.inAsync = node.async;
- this.yieldPos = 0;
- this.awaitPos = 0;
- this.inFunction = true;
- this.enterFunctionScope();
-
- if (!isStatement)
- { node.id = this.type == types.name ? this.parseIdent() : null; }
-
- this.parseFunctionParams(node);
- this.parseFunctionBody(node, allowExpressionBody);
-
- this.inGenerator = oldInGen;
- this.inAsync = oldInAsync;
- this.yieldPos = oldYieldPos;
- this.awaitPos = oldAwaitPos;
- this.inFunction = oldInFunc;
- return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression")
-};
-
-pp$1.parseFunctionParams = function(node) {
- this.expect(types.parenL);
- node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8);
- this.checkYieldAwaitInDefaultParams();
-};
-
-
-pp$1.parseClass = function(node, isStatement) {
- var this$1 = this;
-
- this.next();
-
- this.parseClassId(node, isStatement);
- this.parseClassSuper(node);
- var classBody = this.startNode();
- var hadConstructor = false;
- classBody.body = [];
- this.expect(types.braceL);
- while (!this.eat(types.braceR)) {
- if (this$1.eat(types.semi)) { continue }
- var method = this$1.startNode();
- var isGenerator = this$1.eat(types.star);
- var isAsync = false;
- var isMaybeStatic = this$1.type === types.name && this$1.value === "static";
- this$1.parsePropertyName(method);
- method.static = isMaybeStatic && this$1.type !== types.parenL;
- if (method.static) {
- if (isGenerator) { this$1.unexpected(); }
- isGenerator = this$1.eat(types.star);
- this$1.parsePropertyName(method);
- }
- if (this$1.options.ecmaVersion >= 8 && !isGenerator && !method.computed &&
- method.key.type === "Identifier" && method.key.name === "async" && this$1.type !== types.parenL &&
- !this$1.canInsertSemicolon()) {
- isAsync = true;
- this$1.parsePropertyName(method);
- }
- method.kind = "method";
- var isGetSet = false;
- if (!method.computed) {
- var key = method.key;
- if (!isGenerator && !isAsync && key.type === "Identifier" && this$1.type !== types.parenL && (key.name === "get" || key.name === "set")) {
- isGetSet = true;
- method.kind = key.name;
- key = this$1.parsePropertyName(method);
- }
- if (!method.static && (key.type === "Identifier" && key.name === "constructor" ||
- key.type === "Literal" && key.value === "constructor")) {
- if (hadConstructor) { this$1.raise(key.start, "Duplicate constructor in the same class"); }
- if (isGetSet) { this$1.raise(key.start, "Constructor can't have get/set modifier"); }
- if (isGenerator) { this$1.raise(key.start, "Constructor can't be a generator"); }
- if (isAsync) { this$1.raise(key.start, "Constructor can't be an async method"); }
- method.kind = "constructor";
- hadConstructor = true;
- }
- }
- this$1.parseClassMethod(classBody, method, isGenerator, isAsync);
- if (isGetSet) {
- var paramCount = method.kind === "get" ? 0 : 1;
- if (method.value.params.length !== paramCount) {
- var start = method.value.start;
- if (method.kind === "get")
- { this$1.raiseRecoverable(start, "getter should have no params"); }
- else
- { this$1.raiseRecoverable(start, "setter should have exactly one param"); }
- } else {
- if (method.kind === "set" && method.value.params[0].type === "RestElement")
- { this$1.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); }
- }
- }
- }
- node.body = this.finishNode(classBody, "ClassBody");
- return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression")
-};
-
-pp$1.parseClassMethod = function(classBody, method, isGenerator, isAsync) {
- method.value = this.parseMethod(isGenerator, isAsync);
- classBody.body.push(this.finishNode(method, "MethodDefinition"));
-};
-
-pp$1.parseClassId = function(node, isStatement) {
- node.id = this.type === types.name ? this.parseIdent() : isStatement === true ? this.unexpected() : null;
-};
-
-pp$1.parseClassSuper = function(node) {
- node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null;
-};
-
-
-pp$1.parseExport = function(node, exports) {
- var this$1 = this;
-
- this.next();
- if (this.eat(types.star)) {
- this.expectContextual("from");
- node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected();
- this.semicolon();
- return this.finishNode(node, "ExportAllDeclaration")
- }
- if (this.eat(types._default)) {
- this.checkExport(exports, "default", this.lastTokStart);
- var isAsync;
- if (this.type === types._function || (isAsync = this.isAsyncFunction())) {
- var fNode = this.startNode();
- this.next();
- if (isAsync) { this.next(); }
- node.declaration = this.parseFunction(fNode, "nullableID", false, isAsync);
- } else if (this.type === types._class) {
- var cNode = this.startNode();
- node.declaration = this.parseClass(cNode, "nullableID");
- } else {
- node.declaration = this.parseMaybeAssign();
- this.semicolon();
- }
- return this.finishNode(node, "ExportDefaultDeclaration")
- }
- if (this.shouldParseExportStatement()) {
- node.declaration = this.parseStatement(true);
- if (node.declaration.type === "VariableDeclaration")
- { this.checkVariableExport(exports, node.declaration.declarations); }
- else
- { this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); }
- node.specifiers = [];
- node.source = null;
- } else {
- node.declaration = null;
- node.specifiers = this.parseExportSpecifiers(exports);
- if (this.eatContextual("from")) {
- node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected();
- } else {
- for (var i = 0, list = node.specifiers; i < list.length; i += 1) {
- var spec = list[i];
-
- this$1.checkUnreserved(spec.local);
- }
-
- node.source = null;
- }
- this.semicolon();
- }
- return this.finishNode(node, "ExportNamedDeclaration")
-};
-
-pp$1.checkExport = function(exports, name, pos) {
- if (!exports) { return }
- if (has(exports, name))
- { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); }
- exports[name] = true;
-};
-
-pp$1.checkPatternExport = function(exports, pat) {
- var this$1 = this;
-
- var type = pat.type;
- if (type == "Identifier")
- { this.checkExport(exports, pat.name, pat.start); }
- else if (type == "ObjectPattern")
- { for (var i = 0, list = pat.properties; i < list.length; i += 1)
- {
- var prop = list[i];
-
- this$1.checkPatternExport(exports, prop.value);
- } }
- else if (type == "ArrayPattern")
- { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) {
- var elt = list$1[i$1];
-
- if (elt) { this$1.checkPatternExport(exports, elt); }
- } }
- else if (type == "AssignmentPattern")
- { this.checkPatternExport(exports, pat.left); }
- else if (type == "ParenthesizedExpression")
- { this.checkPatternExport(exports, pat.expression); }
-};
-
-pp$1.checkVariableExport = function(exports, decls) {
- var this$1 = this;
-
- if (!exports) { return }
- for (var i = 0, list = decls; i < list.length; i += 1)
- {
- var decl = list[i];
-
- this$1.checkPatternExport(exports, decl.id);
- }
-};
-
-pp$1.shouldParseExportStatement = function() {
- return this.type.keyword === "var" ||
- this.type.keyword === "const" ||
- this.type.keyword === "class" ||
- this.type.keyword === "function" ||
- this.isLet() ||
- this.isAsyncFunction()
-};
-
-
-pp$1.parseExportSpecifiers = function(exports) {
- var this$1 = this;
-
- var nodes = [], first = true;
- this.expect(types.braceL);
- while (!this.eat(types.braceR)) {
- if (!first) {
- this$1.expect(types.comma);
- if (this$1.afterTrailingComma(types.braceR)) { break }
- } else { first = false; }
-
- var node = this$1.startNode();
- node.local = this$1.parseIdent(true);
- node.exported = this$1.eatContextual("as") ? this$1.parseIdent(true) : node.local;
- this$1.checkExport(exports, node.exported.name, node.exported.start);
- nodes.push(this$1.finishNode(node, "ExportSpecifier"));
- }
- return nodes
-};
-
-
-pp$1.parseImport = function(node) {
- this.next();
- if (this.type === types.string) {
- node.specifiers = empty;
- node.source = this.parseExprAtom();
- } else {
- node.specifiers = this.parseImportSpecifiers();
- this.expectContextual("from");
- node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected();
- }
- this.semicolon();
- return this.finishNode(node, "ImportDeclaration")
-};
-
-
-pp$1.parseImportSpecifiers = function() {
- var this$1 = this;
-
- var nodes = [], first = true;
- if (this.type === types.name) {
- var node = this.startNode();
- node.local = this.parseIdent();
- this.checkLVal(node.local, "let");
- nodes.push(this.finishNode(node, "ImportDefaultSpecifier"));
- if (!this.eat(types.comma)) { return nodes }
- }
- if (this.type === types.star) {
- var node$1 = this.startNode();
- this.next();
- this.expectContextual("as");
- node$1.local = this.parseIdent();
- this.checkLVal(node$1.local, "let");
- nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier"));
- return nodes
- }
- this.expect(types.braceL);
- while (!this.eat(types.braceR)) {
- if (!first) {
- this$1.expect(types.comma);
- if (this$1.afterTrailingComma(types.braceR)) { break }
- } else { first = false; }
-
- var node$2 = this$1.startNode();
- node$2.imported = this$1.parseIdent(true);
- if (this$1.eatContextual("as")) {
- node$2.local = this$1.parseIdent();
- } else {
- this$1.checkUnreserved(node$2.imported);
- node$2.local = node$2.imported;
- }
- this$1.checkLVal(node$2.local, "let");
- nodes.push(this$1.finishNode(node$2, "ImportSpecifier"));
- }
- return nodes
-};
-
-var pp$2 = Parser.prototype;
-
-
-pp$2.toAssignable = function(node, isBinding) {
- var this$1 = this;
-
- if (this.options.ecmaVersion >= 6 && node) {
- switch (node.type) {
- case "Identifier":
- if (this.inAsync && node.name === "await")
- { this.raise(node.start, "Can not use 'await' as identifier inside an async function"); }
- break
-
- case "ObjectPattern":
- case "ArrayPattern":
- break
-
- case "ObjectExpression":
- node.type = "ObjectPattern";
- for (var i = 0, list = node.properties; i < list.length; i += 1) {
- var prop = list[i];
-
- if (prop.kind !== "init") { this$1.raise(prop.key.start, "Object pattern can't contain getter or setter"); }
- this$1.toAssignable(prop.value, isBinding);
- }
- break
-
- case "ArrayExpression":
- node.type = "ArrayPattern";
- this.toAssignableList(node.elements, isBinding);
- break
-
- case "AssignmentExpression":
- if (node.operator === "=") {
- node.type = "AssignmentPattern";
- delete node.operator;
- this.toAssignable(node.left, isBinding);
- } else {
- this.raise(node.left.end, "Only '=' operator can be used for specifying default value.");
- break
- }
-
- case "AssignmentPattern":
- break
-
- case "ParenthesizedExpression":
- this.toAssignable(node.expression, isBinding);
- break
-
- case "MemberExpression":
- if (!isBinding) { break }
-
- default:
- this.raise(node.start, "Assigning to rvalue");
- }
- }
- return node
-};
-
-
-pp$2.toAssignableList = function(exprList, isBinding) {
- var this$1 = this;
-
- var end = exprList.length;
- if (end) {
- var last = exprList[end - 1];
- if (last && last.type == "RestElement") {
- --end;
- } else if (last && last.type == "SpreadElement") {
- last.type = "RestElement";
- var arg = last.argument;
- this.toAssignable(arg, isBinding);
- --end;
- }
-
- if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier")
- { this.unexpected(last.argument.start); }
- }
- for (var i = 0; i < end; i++) {
- var elt = exprList[i];
- if (elt) { this$1.toAssignable(elt, isBinding); }
- }
- return exprList
-};
-
-
-pp$2.parseSpread = function(refDestructuringErrors) {
- var node = this.startNode();
- this.next();
- node.argument = this.parseMaybeAssign(false, refDestructuringErrors);
- return this.finishNode(node, "SpreadElement")
-};
-
-pp$2.parseRestBinding = function() {
- var node = this.startNode();
- this.next();
-
- if (this.options.ecmaVersion === 6 && this.type !== types.name)
- { this.unexpected(); }
-
- node.argument = this.parseBindingAtom();
-
- return this.finishNode(node, "RestElement")
-};
-
-
-pp$2.parseBindingAtom = function() {
- if (this.options.ecmaVersion < 6) { return this.parseIdent() }
- switch (this.type) {
- case types.name:
- return this.parseIdent()
-
- case types.bracketL:
- var node = this.startNode();
- this.next();
- node.elements = this.parseBindingList(types.bracketR, true, true);
- return this.finishNode(node, "ArrayPattern")
-
- case types.braceL:
- return this.parseObj(true)
-
- default:
- this.unexpected();
- }
-};
-
-pp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma) {
- var this$1 = this;
-
- var elts = [], first = true;
- while (!this.eat(close)) {
- if (first) { first = false; }
- else { this$1.expect(types.comma); }
- if (allowEmpty && this$1.type === types.comma) {
- elts.push(null);
- } else if (allowTrailingComma && this$1.afterTrailingComma(close)) {
- break
- } else if (this$1.type === types.ellipsis) {
- var rest = this$1.parseRestBinding();
- this$1.parseBindingListItem(rest);
- elts.push(rest);
- if (this$1.type === types.comma) { this$1.raise(this$1.start, "Comma is not permitted after the rest element"); }
- this$1.expect(close);
- break
- } else {
- var elem = this$1.parseMaybeDefault(this$1.start, this$1.startLoc);
- this$1.parseBindingListItem(elem);
- elts.push(elem);
- }
- }
- return elts
-};
-
-pp$2.parseBindingListItem = function(param) {
- return param
-};
-
-
-pp$2.parseMaybeDefault = function(startPos, startLoc, left) {
- left = left || this.parseBindingAtom();
- if (this.options.ecmaVersion < 6 || !this.eat(types.eq)) { return left }
- var node = this.startNodeAt(startPos, startLoc);
- node.left = left;
- node.right = this.parseMaybeAssign();
- return this.finishNode(node, "AssignmentPattern")
-};
-
-
-pp$2.checkLVal = function(expr, bindingType, checkClashes) {
- var this$1 = this;
-
- switch (expr.type) {
- case "Identifier":
- if (this.strict && this.reservedWordsStrictBind.test(expr.name))
- { this.raiseRecoverable(expr.start, (bindingType ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); }
- if (checkClashes) {
- if (has(checkClashes, expr.name))
- { this.raiseRecoverable(expr.start, "Argument name clash"); }
- checkClashes[expr.name] = true;
- }
- if (bindingType && bindingType !== "none") {
- if (
- bindingType === "var" && !this.canDeclareVarName(expr.name) ||
- bindingType !== "var" && !this.canDeclareLexicalName(expr.name)
- ) {
- this.raiseRecoverable(expr.start, ("Identifier '" + (expr.name) + "' has already been declared"));
- }
- if (bindingType === "var") {
- this.declareVarName(expr.name);
- } else {
- this.declareLexicalName(expr.name);
- }
- }
- break
-
- case "MemberExpression":
- if (bindingType) { this.raiseRecoverable(expr.start, (bindingType ? "Binding" : "Assigning to") + " member expression"); }
- break
-
- case "ObjectPattern":
- for (var i = 0, list = expr.properties; i < list.length; i += 1)
- {
- var prop = list[i];
-
- this$1.checkLVal(prop.value, bindingType, checkClashes);
- }
- break
-
- case "ArrayPattern":
- for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) {
- var elem = list$1[i$1];
-
- if (elem) { this$1.checkLVal(elem, bindingType, checkClashes); }
- }
- break
-
- case "AssignmentPattern":
- this.checkLVal(expr.left, bindingType, checkClashes);
- break
-
- case "RestElement":
- this.checkLVal(expr.argument, bindingType, checkClashes);
- break
-
- case "ParenthesizedExpression":
- this.checkLVal(expr.expression, bindingType, checkClashes);
- break
-
- default:
- this.raise(expr.start, (bindingType ? "Binding" : "Assigning to") + " rvalue");
- }
-};
-
-
-var pp$3 = Parser.prototype;
-
-
-pp$3.checkPropClash = function(prop, propHash) {
- if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand))
- { return }
- var key = prop.key;
- var name;
- switch (key.type) {
- case "Identifier": name = key.name; break
- case "Literal": name = String(key.value); break
- default: return
- }
- var kind = prop.kind;
- if (this.options.ecmaVersion >= 6) {
- if (name === "__proto__" && kind === "init") {
- if (propHash.proto) { this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); }
- propHash.proto = true;
- }
- return
- }
- name = "$" + name;
- var other = propHash[name];
- if (other) {
- var redefinition;
- if (kind === "init") {
- redefinition = this.strict && other.init || other.get || other.set;
- } else {
- redefinition = other.init || other[kind];
- }
- if (redefinition)
- { this.raiseRecoverable(key.start, "Redefinition of property"); }
- } else {
- other = propHash[name] = {
- init: false,
- get: false,
- set: false
- };
- }
- other[kind] = true;
-};
-
-
-
-
-pp$3.parseExpression = function(noIn, refDestructuringErrors) {
- var this$1 = this;
-
- var startPos = this.start, startLoc = this.startLoc;
- var expr = this.parseMaybeAssign(noIn, refDestructuringErrors);
- if (this.type === types.comma) {
- var node = this.startNodeAt(startPos, startLoc);
- node.expressions = [expr];
- while (this.eat(types.comma)) { node.expressions.push(this$1.parseMaybeAssign(noIn, refDestructuringErrors)); }
- return this.finishNode(node, "SequenceExpression")
- }
- return expr
-};
-
-
-pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) {
- if (this.inGenerator && this.isContextual("yield")) { return this.parseYield() }
-
- var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1;
- if (refDestructuringErrors) {
- oldParenAssign = refDestructuringErrors.parenthesizedAssign;
- oldTrailingComma = refDestructuringErrors.trailingComma;
- refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1;
- } else {
- refDestructuringErrors = new DestructuringErrors;
- ownDestructuringErrors = true;
- }
-
- var startPos = this.start, startLoc = this.startLoc;
- if (this.type == types.parenL || this.type == types.name)
- { this.potentialArrowAt = this.start; }
- var left = this.parseMaybeConditional(noIn, refDestructuringErrors);
- if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); }
- if (this.type.isAssign) {
- this.checkPatternErrors(refDestructuringErrors, true);
- if (!ownDestructuringErrors) { DestructuringErrors.call(refDestructuringErrors); }
- var node = this.startNodeAt(startPos, startLoc);
- node.operator = this.value;
- node.left = this.type === types.eq ? this.toAssignable(left) : left;
- refDestructuringErrors.shorthandAssign = -1;
- this.checkLVal(left);
- this.next();
- node.right = this.parseMaybeAssign(noIn);
- return this.finishNode(node, "AssignmentExpression")
- } else {
- if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); }
- }
- if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; }
- if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; }
- return left
-};
-
-
-pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) {
- var startPos = this.start, startLoc = this.startLoc;
- var expr = this.parseExprOps(noIn, refDestructuringErrors);
- if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
- if (this.eat(types.question)) {
- var node = this.startNodeAt(startPos, startLoc);
- node.test = expr;
- node.consequent = this.parseMaybeAssign();
- this.expect(types.colon);
- node.alternate = this.parseMaybeAssign(noIn);
- return this.finishNode(node, "ConditionalExpression")
- }
- return expr
-};
-
-
-pp$3.parseExprOps = function(noIn, refDestructuringErrors) {
- var startPos = this.start, startLoc = this.startLoc;
- var expr = this.parseMaybeUnary(refDestructuringErrors, false);
- if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
- return expr.start == startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn)
-};
-
-
-pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) {
- var prec = this.type.binop;
- if (prec != null && (!noIn || this.type !== types._in)) {
- if (prec > minPrec) {
- var logical = this.type === types.logicalOR || this.type === types.logicalAND;
- var op = this.value;
- this.next();
- var startPos = this.start, startLoc = this.startLoc;
- var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn);
- var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical);
- return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn)
- }
- }
- return left
-};
-
-pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) {
- var node = this.startNodeAt(startPos, startLoc);
- node.left = left;
- node.operator = op;
- node.right = right;
- return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression")
-};
-
-
-pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) {
- var this$1 = this;
-
- var startPos = this.start, startLoc = this.startLoc, expr;
- if (this.inAsync && this.isContextual("await")) {
- expr = this.parseAwait(refDestructuringErrors);
- sawUnary = true;
- } else if (this.type.prefix) {
- var node = this.startNode(), update = this.type === types.incDec;
- node.operator = this.value;
- node.prefix = true;
- this.next();
- node.argument = this.parseMaybeUnary(null, true);
- this.checkExpressionErrors(refDestructuringErrors, true);
- if (update) { this.checkLVal(node.argument); }
- else if (this.strict && node.operator === "delete" &&
- node.argument.type === "Identifier")
- { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); }
- else { sawUnary = true; }
- expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
- } else {
- expr = this.parseExprSubscripts(refDestructuringErrors);
- if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
- while (this.type.postfix && !this.canInsertSemicolon()) {
- var node$1 = this$1.startNodeAt(startPos, startLoc);
- node$1.operator = this$1.value;
- node$1.prefix = false;
- node$1.argument = expr;
- this$1.checkLVal(expr);
- this$1.next();
- expr = this$1.finishNode(node$1, "UpdateExpression");
- }
- }
-
- if (!sawUnary && this.eat(types.starstar))
- { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) }
- else
- { return expr }
-};
-
-
-pp$3.parseExprSubscripts = function(refDestructuringErrors) {
- var startPos = this.start, startLoc = this.startLoc;
- var expr = this.parseExprAtom(refDestructuringErrors);
- var skipArrowSubscripts = expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")";
- if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) { return expr }
- var result = this.parseSubscripts(expr, startPos, startLoc);
- if (refDestructuringErrors && result.type === "MemberExpression") {
- if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; }
- if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; }
- }
- return result
-};
-
-pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) {
- var this$1 = this;
-
- var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" &&
- this.lastTokEnd == base.end && !this.canInsertSemicolon();
- for (var computed = (void 0);;) {
- if ((computed = this$1.eat(types.bracketL)) || this$1.eat(types.dot)) {
- var node = this$1.startNodeAt(startPos, startLoc);
- node.object = base;
- node.property = computed ? this$1.parseExpression() : this$1.parseIdent(true);
- node.computed = !!computed;
- if (computed) { this$1.expect(types.bracketR); }
- base = this$1.finishNode(node, "MemberExpression");
- } else if (!noCalls && this$1.eat(types.parenL)) {
- var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this$1.yieldPos, oldAwaitPos = this$1.awaitPos;
- this$1.yieldPos = 0;
- this$1.awaitPos = 0;
- var exprList = this$1.parseExprList(types.parenR, this$1.options.ecmaVersion >= 8, false, refDestructuringErrors);
- if (maybeAsyncArrow && !this$1.canInsertSemicolon() && this$1.eat(types.arrow)) {
- this$1.checkPatternErrors(refDestructuringErrors, false);
- this$1.checkYieldAwaitInDefaultParams();
- this$1.yieldPos = oldYieldPos;
- this$1.awaitPos = oldAwaitPos;
- return this$1.parseArrowExpression(this$1.startNodeAt(startPos, startLoc), exprList, true)
- }
- this$1.checkExpressionErrors(refDestructuringErrors, true);
- this$1.yieldPos = oldYieldPos || this$1.yieldPos;
- this$1.awaitPos = oldAwaitPos || this$1.awaitPos;
- var node$1 = this$1.startNodeAt(startPos, startLoc);
- node$1.callee = base;
- node$1.arguments = exprList;
- base = this$1.finishNode(node$1, "CallExpression");
- } else if (this$1.type === types.backQuote) {
- var node$2 = this$1.startNodeAt(startPos, startLoc);
- node$2.tag = base;
- node$2.quasi = this$1.parseTemplate({isTagged: true});
- base = this$1.finishNode(node$2, "TaggedTemplateExpression");
- } else {
- return base
- }
- }
-};
-
-
-pp$3.parseExprAtom = function(refDestructuringErrors) {
- var node, canBeArrow = this.potentialArrowAt == this.start;
- switch (this.type) {
- case types._super:
- if (!this.inFunction)
- { this.raise(this.start, "'super' outside of function or class"); }
-
- case types._this:
- var type = this.type === types._this ? "ThisExpression" : "Super";
- node = this.startNode();
- this.next();
- return this.finishNode(node, type)
-
- case types.name:
- var startPos = this.start, startLoc = this.startLoc;
- var id = this.parseIdent(this.type !== types.name);
- if (this.options.ecmaVersion >= 8 && id.name === "async" && !this.canInsertSemicolon() && this.eat(types._function))
- { return this.parseFunction(this.startNodeAt(startPos, startLoc), false, false, true) }
- if (canBeArrow && !this.canInsertSemicolon()) {
- if (this.eat(types.arrow))
- { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) }
- if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types.name) {
- id = this.parseIdent();
- if (this.canInsertSemicolon() || !this.eat(types.arrow))
- { this.unexpected(); }
- return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true)
- }
- }
- return id
-
- case types.regexp:
- var value = this.value;
- node = this.parseLiteral(value.value);
- node.regex = {pattern: value.pattern, flags: value.flags};
- return node
-
- case types.num: case types.string:
- return this.parseLiteral(this.value)
-
- case types._null: case types._true: case types._false:
- node = this.startNode();
- node.value = this.type === types._null ? null : this.type === types._true;
- node.raw = this.type.keyword;
- this.next();
- return this.finishNode(node, "Literal")
-
- case types.parenL:
- var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow);
- if (refDestructuringErrors) {
- if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr))
- { refDestructuringErrors.parenthesizedAssign = start; }
- if (refDestructuringErrors.parenthesizedBind < 0)
- { refDestructuringErrors.parenthesizedBind = start; }
- }
- return expr
-
- case types.bracketL:
- node = this.startNode();
- this.next();
- node.elements = this.parseExprList(types.bracketR, true, true, refDestructuringErrors);
- return this.finishNode(node, "ArrayExpression")
-
- case types.braceL:
- return this.parseObj(false, refDestructuringErrors)
-
- case types._function:
- node = this.startNode();
- this.next();
- return this.parseFunction(node, false)
-
- case types._class:
- return this.parseClass(this.startNode(), false)
-
- case types._new:
- return this.parseNew()
-
- case types.backQuote:
- return this.parseTemplate()
-
- default:
- this.unexpected();
- }
-};
-
-pp$3.parseLiteral = function(value) {
- var node = this.startNode();
- node.value = value;
- node.raw = this.input.slice(this.start, this.end);
- this.next();
- return this.finishNode(node, "Literal")
-};
-
-pp$3.parseParenExpression = function() {
- this.expect(types.parenL);
- var val = this.parseExpression();
- this.expect(types.parenR);
- return val
-};
-
-pp$3.parseParenAndDistinguishExpression = function(canBeArrow) {
- var this$1 = this;
-
- var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8;
- if (this.options.ecmaVersion >= 6) {
- this.next();
-
- var innerStartPos = this.start, innerStartLoc = this.startLoc;
- var exprList = [], first = true, lastIsComma = false;
- var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart, innerParenStart;
- this.yieldPos = 0;
- this.awaitPos = 0;
- while (this.type !== types.parenR) {
- first ? first = false : this$1.expect(types.comma);
- if (allowTrailingComma && this$1.afterTrailingComma(types.parenR, true)) {
- lastIsComma = true;
- break
- } else if (this$1.type === types.ellipsis) {
- spreadStart = this$1.start;
- exprList.push(this$1.parseParenItem(this$1.parseRestBinding()));
- if (this$1.type === types.comma) { this$1.raise(this$1.start, "Comma is not permitted after the rest element"); }
- break
- } else {
- if (this$1.type === types.parenL && !innerParenStart) {
- innerParenStart = this$1.start;
- }
- exprList.push(this$1.parseMaybeAssign(false, refDestructuringErrors, this$1.parseParenItem));
- }
- }
- var innerEndPos = this.start, innerEndLoc = this.startLoc;
- this.expect(types.parenR);
-
- if (canBeArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) {
- this.checkPatternErrors(refDestructuringErrors, false);
- this.checkYieldAwaitInDefaultParams();
- if (innerParenStart) { this.unexpected(innerParenStart); }
- this.yieldPos = oldYieldPos;
- this.awaitPos = oldAwaitPos;
- return this.parseParenArrowList(startPos, startLoc, exprList)
- }
-
- if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); }
- if (spreadStart) { this.unexpected(spreadStart); }
- this.checkExpressionErrors(refDestructuringErrors, true);
- this.yieldPos = oldYieldPos || this.yieldPos;
- this.awaitPos = oldAwaitPos || this.awaitPos;
-
- if (exprList.length > 1) {
- val = this.startNodeAt(innerStartPos, innerStartLoc);
- val.expressions = exprList;
- this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc);
- } else {
- val = exprList[0];
- }
- } else {
- val = this.parseParenExpression();
- }
-
- if (this.options.preserveParens) {
- var par = this.startNodeAt(startPos, startLoc);
- par.expression = val;
- return this.finishNode(par, "ParenthesizedExpression")
- } else {
- return val
- }
-};
-
-pp$3.parseParenItem = function(item) {
- return item
-};
-
-pp$3.parseParenArrowList = function(startPos, startLoc, exprList) {
- return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList)
-};
-
-
-var empty$1 = [];
-
-pp$3.parseNew = function() {
- var node = this.startNode();
- var meta = this.parseIdent(true);
- if (this.options.ecmaVersion >= 6 && this.eat(types.dot)) {
- node.meta = meta;
- node.property = this.parseIdent(true);
- if (node.property.name !== "target")
- { this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target"); }
- if (!this.inFunction)
- { this.raiseRecoverable(node.start, "new.target can only be used in functions"); }
- return this.finishNode(node, "MetaProperty")
- }
- var startPos = this.start, startLoc = this.startLoc;
- node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true);
- if (this.eat(types.parenL)) { node.arguments = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false); }
- else { node.arguments = empty$1; }
- return this.finishNode(node, "NewExpression")
-};
-
-
-pp$3.parseTemplateElement = function(ref) {
- var isTagged = ref.isTagged;
-
- var elem = this.startNode();
- if (this.type === types.invalidTemplate) {
- if (!isTagged) {
- this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal");
- }
- elem.value = {
- raw: this.value,
- cooked: null
- };
- } else {
- elem.value = {
- raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"),
- cooked: this.value
- };
- }
- this.next();
- elem.tail = this.type === types.backQuote;
- return this.finishNode(elem, "TemplateElement")
-};
-
-pp$3.parseTemplate = function(ref) {
- var this$1 = this;
- if ( ref === void 0 ) ref = {};
- var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false;
-
- var node = this.startNode();
- this.next();
- node.expressions = [];
- var curElt = this.parseTemplateElement({isTagged: isTagged});
- node.quasis = [curElt];
- while (!curElt.tail) {
- this$1.expect(types.dollarBraceL);
- node.expressions.push(this$1.parseExpression());
- this$1.expect(types.braceR);
- node.quasis.push(curElt = this$1.parseTemplateElement({isTagged: isTagged}));
- }
- this.next();
- return this.finishNode(node, "TemplateLiteral")
-};
-
-
-pp$3.isAsyncProp = function(prop) {
- return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" &&
- (this.type === types.name || this.type === types.num || this.type === types.string || this.type === types.bracketL) &&
- !lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
-};
-
-pp$3.parseObj = function(isPattern, refDestructuringErrors) {
- var this$1 = this;
-
- var node = this.startNode(), first = true, propHash = {};
- node.properties = [];
- this.next();
- while (!this.eat(types.braceR)) {
- if (!first) {
- this$1.expect(types.comma);
- if (this$1.afterTrailingComma(types.braceR)) { break }
- } else { first = false; }
-
- var prop = this$1.startNode(), isGenerator = (void 0), isAsync = (void 0), startPos = (void 0), startLoc = (void 0);
- if (this$1.options.ecmaVersion >= 6) {
- prop.method = false;
- prop.shorthand = false;
- if (isPattern || refDestructuringErrors) {
- startPos = this$1.start;
- startLoc = this$1.startLoc;
- }
- if (!isPattern)
- { isGenerator = this$1.eat(types.star); }
- }
- this$1.parsePropertyName(prop);
- if (!isPattern && this$1.options.ecmaVersion >= 8 && !isGenerator && this$1.isAsyncProp(prop)) {
- isAsync = true;
- this$1.parsePropertyName(prop, refDestructuringErrors);
- } else {
- isAsync = false;
- }
- this$1.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors);
- this$1.checkPropClash(prop, propHash);
- node.properties.push(this$1.finishNode(prop, "Property"));
- }
- return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression")
-};
-
-pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors) {
- if ((isGenerator || isAsync) && this.type === types.colon)
- { this.unexpected(); }
-
- if (this.eat(types.colon)) {
- prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors);
- prop.kind = "init";
- } else if (this.options.ecmaVersion >= 6 && this.type === types.parenL) {
- if (isPattern) { this.unexpected(); }
- prop.kind = "init";
- prop.method = true;
- prop.value = this.parseMethod(isGenerator, isAsync);
- } else if (this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
- (prop.key.name === "get" || prop.key.name === "set") &&
- (this.type != types.comma && this.type != types.braceR)) {
- if (isGenerator || isAsync || isPattern) { this.unexpected(); }
- prop.kind = prop.key.name;
- this.parsePropertyName(prop);
- prop.value = this.parseMethod(false);
- var paramCount = prop.kind === "get" ? 0 : 1;
- if (prop.value.params.length !== paramCount) {
- var start = prop.value.start;
- if (prop.kind === "get")
- { this.raiseRecoverable(start, "getter should have no params"); }
- else
- { this.raiseRecoverable(start, "setter should have exactly one param"); }
- } else {
- if (prop.kind === "set" && prop.value.params[0].type === "RestElement")
- { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); }
- }
- } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
- this.checkUnreserved(prop.key);
- prop.kind = "init";
- if (isPattern) {
- prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
- } else if (this.type === types.eq && refDestructuringErrors) {
- if (refDestructuringErrors.shorthandAssign < 0)
- { refDestructuringErrors.shorthandAssign = this.start; }
- prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
- } else {
- prop.value = prop.key;
- }
- prop.shorthand = true;
- } else { this.unexpected(); }
-};
-
-pp$3.parsePropertyName = function(prop) {
- if (this.options.ecmaVersion >= 6) {
- if (this.eat(types.bracketL)) {
- prop.computed = true;
- prop.key = this.parseMaybeAssign();
- this.expect(types.bracketR);
- return prop.key
- } else {
- prop.computed = false;
- }
- }
- return prop.key = this.type === types.num || this.type === types.string ? this.parseExprAtom() : this.parseIdent(true)
-};
-
-
-pp$3.initFunction = function(node) {
- node.id = null;
- if (this.options.ecmaVersion >= 6) {
- node.generator = false;
- node.expression = false;
- }
- if (this.options.ecmaVersion >= 8)
- { node.async = false; }
-};
-
-
-pp$3.parseMethod = function(isGenerator, isAsync) {
- var node = this.startNode(), oldInGen = this.inGenerator, oldInAsync = this.inAsync,
- oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction;
-
- this.initFunction(node);
- if (this.options.ecmaVersion >= 6)
- { node.generator = isGenerator; }
- if (this.options.ecmaVersion >= 8)
- { node.async = !!isAsync; }
-
- this.inGenerator = node.generator;
- this.inAsync = node.async;
- this.yieldPos = 0;
- this.awaitPos = 0;
- this.inFunction = true;
- this.enterFunctionScope();
-
- this.expect(types.parenL);
- node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8);
- this.checkYieldAwaitInDefaultParams();
- this.parseFunctionBody(node, false);
-
- this.inGenerator = oldInGen;
- this.inAsync = oldInAsync;
- this.yieldPos = oldYieldPos;
- this.awaitPos = oldAwaitPos;
- this.inFunction = oldInFunc;
- return this.finishNode(node, "FunctionExpression")
-};
-
-
-pp$3.parseArrowExpression = function(node, params, isAsync) {
- var oldInGen = this.inGenerator, oldInAsync = this.inAsync,
- oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction;
-
- this.enterFunctionScope();
- this.initFunction(node);
- if (this.options.ecmaVersion >= 8)
- { node.async = !!isAsync; }
-
- this.inGenerator = false;
- this.inAsync = node.async;
- this.yieldPos = 0;
- this.awaitPos = 0;
- this.inFunction = true;
-
- node.params = this.toAssignableList(params, true);
- this.parseFunctionBody(node, true);
-
- this.inGenerator = oldInGen;
- this.inAsync = oldInAsync;
- this.yieldPos = oldYieldPos;
- this.awaitPos = oldAwaitPos;
- this.inFunction = oldInFunc;
- return this.finishNode(node, "ArrowFunctionExpression")
-};
-
-
-pp$3.parseFunctionBody = function(node, isArrowFunction) {
- var isExpression = isArrowFunction && this.type !== types.braceL;
- var oldStrict = this.strict, useStrict = false;
-
- if (isExpression) {
- node.body = this.parseMaybeAssign();
- node.expression = true;
- this.checkParams(node, false);
- } else {
- var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params);
- if (!oldStrict || nonSimple) {
- useStrict = this.strictDirective(this.end);
- if (useStrict && nonSimple)
- { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); }
- }
- var oldLabels = this.labels;
- this.labels = [];
- if (useStrict) { this.strict = true; }
-
- this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && this.isSimpleParamList(node.params));
- node.body = this.parseBlock(false);
- node.expression = false;
- this.labels = oldLabels;
- }
- this.exitFunctionScope();
-
- if (this.strict && node.id) {
- this.checkLVal(node.id, "none");
- }
- this.strict = oldStrict;
-};
-
-pp$3.isSimpleParamList = function(params) {
- for (var i = 0, list = params; i < list.length; i += 1)
- {
- var param = list[i];
-
- if (param.type !== "Identifier") { return false
- } }
- return true
-};
-
-
-pp$3.checkParams = function(node, allowDuplicates) {
- var this$1 = this;
-
- var nameHash = {};
- for (var i = 0, list = node.params; i < list.length; i += 1)
- {
- var param = list[i];
-
- this$1.checkLVal(param, "var", allowDuplicates ? null : nameHash);
- }
-};
-
-
-pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) {
- var this$1 = this;
-
- var elts = [], first = true;
- while (!this.eat(close)) {
- if (!first) {
- this$1.expect(types.comma);
- if (allowTrailingComma && this$1.afterTrailingComma(close)) { break }
- } else { first = false; }
-
- var elt = (void 0);
- if (allowEmpty && this$1.type === types.comma)
- { elt = null; }
- else if (this$1.type === types.ellipsis) {
- elt = this$1.parseSpread(refDestructuringErrors);
- if (refDestructuringErrors && this$1.type === types.comma && refDestructuringErrors.trailingComma < 0)
- { refDestructuringErrors.trailingComma = this$1.start; }
- } else {
- elt = this$1.parseMaybeAssign(false, refDestructuringErrors);
- }
- elts.push(elt);
- }
- return elts
-};
-
-
-pp$3.checkUnreserved = function(ref) {
- var start = ref.start;
- var end = ref.end;
- var name = ref.name;
-
- if (this.inGenerator && name === "yield")
- { this.raiseRecoverable(start, "Can not use 'yield' as identifier inside a generator"); }
- if (this.inAsync && name === "await")
- { this.raiseRecoverable(start, "Can not use 'await' as identifier inside an async function"); }
- if (this.isKeyword(name))
- { this.raise(start, ("Unexpected keyword '" + name + "'")); }
- if (this.options.ecmaVersion < 6 &&
- this.input.slice(start, end).indexOf("\\") != -1) { return }
- var re = this.strict ? this.reservedWordsStrict : this.reservedWords;
- if (re.test(name))
- { this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved")); }
-};
-
-pp$3.parseIdent = function(liberal, isBinding) {
- var node = this.startNode();
- if (liberal && this.options.allowReserved == "never") { liberal = false; }
- if (this.type === types.name) {
- node.name = this.value;
- } else if (this.type.keyword) {
- node.name = this.type.keyword;
- } else {
- this.unexpected();
- }
- this.next();
- this.finishNode(node, "Identifier");
- if (!liberal) { this.checkUnreserved(node); }
- return node
-};
-
-
-pp$3.parseYield = function() {
- if (!this.yieldPos) { this.yieldPos = this.start; }
-
- var node = this.startNode();
- this.next();
- if (this.type == types.semi || this.canInsertSemicolon() || (this.type != types.star && !this.type.startsExpr)) {
- node.delegate = false;
- node.argument = null;
- } else {
- node.delegate = this.eat(types.star);
- node.argument = this.parseMaybeAssign();
- }
- return this.finishNode(node, "YieldExpression")
-};
-
-pp$3.parseAwait = function() {
- if (!this.awaitPos) { this.awaitPos = this.start; }
-
- var node = this.startNode();
- this.next();
- node.argument = this.parseMaybeUnary(null, true);
- return this.finishNode(node, "AwaitExpression")
-};
-
-var pp$4 = Parser.prototype;
-
-
-pp$4.raise = function(pos, message) {
- var loc = getLineInfo(this.input, pos);
- message += " (" + loc.line + ":" + loc.column + ")";
- var err = new SyntaxError(message);
- err.pos = pos; err.loc = loc; err.raisedAt = this.pos;
- throw err
-};
-
-pp$4.raiseRecoverable = pp$4.raise;
-
-pp$4.curPosition = function() {
- if (this.options.locations) {
- return new Position(this.curLine, this.pos - this.lineStart)
- }
-};
-
-var pp$5 = Parser.prototype;
-
-var assign = Object.assign || function(target) {
- var sources = [], len = arguments.length - 1;
- while ( len-- > 0 ) sources[ len ] = arguments[ len + 1 ];
-
- for (var i = 0, list = sources; i < list.length; i += 1) {
- var source = list[i];
-
- for (var key in source) {
- if (has(source, key)) {
- target[key] = source[key];
- }
- }
- }
- return target
-};
-
-
-pp$5.enterFunctionScope = function() {
- this.scopeStack.push({var: {}, lexical: {}, childVar: {}, parentLexical: {}});
-};
-
-pp$5.exitFunctionScope = function() {
- this.scopeStack.pop();
-};
-
-pp$5.enterLexicalScope = function() {
- var parentScope = this.scopeStack[this.scopeStack.length - 1];
- var childScope = {var: {}, lexical: {}, childVar: {}, parentLexical: {}};
-
- this.scopeStack.push(childScope);
- assign(childScope.parentLexical, parentScope.lexical, parentScope.parentLexical);
-};
-
-pp$5.exitLexicalScope = function() {
- var childScope = this.scopeStack.pop();
- var parentScope = this.scopeStack[this.scopeStack.length - 1];
-
- assign(parentScope.childVar, childScope.var, childScope.childVar);
-};
-
-pp$5.canDeclareVarName = function(name) {
- var currentScope = this.scopeStack[this.scopeStack.length - 1];
-
- return !has(currentScope.lexical, name) && !has(currentScope.parentLexical, name)
-};
-
-pp$5.canDeclareLexicalName = function(name) {
- var currentScope = this.scopeStack[this.scopeStack.length - 1];
-
- return !has(currentScope.lexical, name) && !has(currentScope.var, name) && !has(currentScope.childVar, name)
-};
-
-pp$5.declareVarName = function(name) {
- this.scopeStack[this.scopeStack.length - 1].var[name] = true;
-};
-
-pp$5.declareLexicalName = function(name) {
- this.scopeStack[this.scopeStack.length - 1].lexical[name] = true;
-};
-
-var Node = function Node(parser, pos, loc) {
- this.type = "";
- this.start = pos;
- this.end = 0;
- if (parser.options.locations)
- { this.loc = new SourceLocation(parser, loc); }
- if (parser.options.directSourceFile)
- { this.sourceFile = parser.options.directSourceFile; }
- if (parser.options.ranges)
- { this.range = [pos, 0]; }
-};
-
-
-var pp$6 = Parser.prototype;
-
-pp$6.startNode = function() {
- return new Node(this, this.start, this.startLoc)
-};
-
-pp$6.startNodeAt = function(pos, loc) {
- return new Node(this, pos, loc)
-};
-
-
-function finishNodeAt(node, type, pos, loc) {
- node.type = type;
- node.end = pos;
- if (this.options.locations)
- { node.loc.end = loc; }
- if (this.options.ranges)
- { node.range[1] = pos; }
- return node
-}
-
-pp$6.finishNode = function(node, type) {
- return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc)
-};
-
-
-pp$6.finishNodeAt = function(node, type, pos, loc) {
- return finishNodeAt.call(this, node, type, pos, loc)
-};
-
-
-var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) {
- this.token = token;
- this.isExpr = !!isExpr;
- this.preserveSpace = !!preserveSpace;
- this.override = override;
- this.generator = !!generator;
-};
-
-var types$1 = {
- b_stat: new TokContext("{", false),
- b_expr: new TokContext("{", true),
- b_tmpl: new TokContext("${", false),
- p_stat: new TokContext("(", false),
- p_expr: new TokContext("(", true),
- q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }),
- f_stat: new TokContext("function", false),
- f_expr: new TokContext("function", true),
- f_expr_gen: new TokContext("function", true, false, null, true),
- f_gen: new TokContext("function", false, false, null, true)
-};
-
-var pp$7 = Parser.prototype;
-
-pp$7.initialContext = function() {
- return [types$1.b_stat]
-};
-
-pp$7.braceIsBlock = function(prevType) {
- var parent = this.curContext();
- if (parent === types$1.f_expr || parent === types$1.f_stat)
- { return true }
- if (prevType === types.colon && (parent === types$1.b_stat || parent === types$1.b_expr))
- { return !parent.isExpr }
-
- if (prevType === types._return || prevType == types.name && this.exprAllowed)
- { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) }
- if (prevType === types._else || prevType === types.semi || prevType === types.eof || prevType === types.parenR || prevType == types.arrow)
- { return true }
- if (prevType == types.braceL)
- { return parent === types$1.b_stat }
- if (prevType == types._var || prevType == types.name)
- { return false }
- return !this.exprAllowed
-};
-
-pp$7.inGeneratorContext = function() {
- var this$1 = this;
-
- for (var i = this.context.length - 1; i >= 1; i--) {
- var context = this$1.context[i];
- if (context.token === "function")
- { return context.generator }
- }
- return false
-};
-
-pp$7.updateContext = function(prevType) {
- var update, type = this.type;
- if (type.keyword && prevType == types.dot)
- { this.exprAllowed = false; }
- else if (update = type.updateContext)
- { update.call(this, prevType); }
- else
- { this.exprAllowed = type.beforeExpr; }
-};
-
-
-types.parenR.updateContext = types.braceR.updateContext = function() {
- if (this.context.length == 1) {
- this.exprAllowed = true;
- return
- }
- var out = this.context.pop();
- if (out === types$1.b_stat && this.curContext().token === "function") {
- out = this.context.pop();
- }
- this.exprAllowed = !out.isExpr;
-};
-
-types.braceL.updateContext = function(prevType) {
- this.context.push(this.braceIsBlock(prevType) ? types$1.b_stat : types$1.b_expr);
- this.exprAllowed = true;
-};
-
-types.dollarBraceL.updateContext = function() {
- this.context.push(types$1.b_tmpl);
- this.exprAllowed = true;
-};
-
-types.parenL.updateContext = function(prevType) {
- var statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while;
- this.context.push(statementParens ? types$1.p_stat : types$1.p_expr);
- this.exprAllowed = true;
-};
-
-types.incDec.updateContext = function() {
-};
-
-types._function.updateContext = types._class.updateContext = function(prevType) {
- if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else &&
- !((prevType === types.colon || prevType === types.braceL) && this.curContext() === types$1.b_stat))
- { this.context.push(types$1.f_expr); }
- else
- { this.context.push(types$1.f_stat); }
- this.exprAllowed = false;
-};
-
-types.backQuote.updateContext = function() {
- if (this.curContext() === types$1.q_tmpl)
- { this.context.pop(); }
- else
- { this.context.push(types$1.q_tmpl); }
- this.exprAllowed = false;
-};
-
-types.star.updateContext = function(prevType) {
- if (prevType == types._function) {
- var index = this.context.length - 1;
- if (this.context[index] === types$1.f_expr)
- { this.context[index] = types$1.f_expr_gen; }
- else
- { this.context[index] = types$1.f_gen; }
- }
- this.exprAllowed = true;
-};
-
-types.name.updateContext = function(prevType) {
- var allowed = false;
- if (this.options.ecmaVersion >= 6) {
- if (this.value == "of" && !this.exprAllowed ||
- this.value == "yield" && this.inGeneratorContext())
- { allowed = true; }
- }
- this.exprAllowed = allowed;
-};
-
-
-var Token = function Token(p) {
- this.type = p.type;
- this.value = p.value;
- this.start = p.start;
- this.end = p.end;
- if (p.options.locations)
- { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); }
- if (p.options.ranges)
- { this.range = [p.start, p.end]; }
-};
-
-
-var pp$8 = Parser.prototype;
-
-var isRhino = typeof Packages == "object" && Object.prototype.toString.call(Packages) == "[object JavaPackage]";
-
-
-pp$8.next = function() {
- if (this.options.onToken)
- { this.options.onToken(new Token(this)); }
-
- this.lastTokEnd = this.end;
- this.lastTokStart = this.start;
- this.lastTokEndLoc = this.endLoc;
- this.lastTokStartLoc = this.startLoc;
- this.nextToken();
-};
-
-pp$8.getToken = function() {
- this.next();
- return new Token(this)
-};
-
-if (typeof Symbol !== "undefined")
- { pp$8[Symbol.iterator] = function() {
- var this$1 = this;
-
- return {
- next: function () {
- var token = this$1.getToken();
- return {
- done: token.type === types.eof,
- value: token
- }
- }
- }
- }; }
-
-
-pp$8.curContext = function() {
- return this.context[this.context.length - 1]
-};
-
-
-pp$8.nextToken = function() {
- var curContext = this.curContext();
- if (!curContext || !curContext.preserveSpace) { this.skipSpace(); }
-
- this.start = this.pos;
- if (this.options.locations) { this.startLoc = this.curPosition(); }
- if (this.pos >= this.input.length) { return this.finishToken(types.eof) }
-
- if (curContext.override) { return curContext.override(this) }
- else { this.readToken(this.fullCharCodeAtPos()); }
-};
-
-pp$8.readToken = function(code) {
- if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 )
- { return this.readWord() }
-
- return this.getTokenFromCode(code)
-};
-
-pp$8.fullCharCodeAtPos = function() {
- var code = this.input.charCodeAt(this.pos);
- if (code <= 0xd7ff || code >= 0xe000) { return code }
- var next = this.input.charCodeAt(this.pos + 1);
- return (code << 10) + next - 0x35fdc00
-};
-
-pp$8.skipBlockComment = function() {
- var this$1 = this;
-
- var startLoc = this.options.onComment && this.curPosition();
- var start = this.pos, end = this.input.indexOf("*/", this.pos += 2);
- if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); }
- this.pos = end + 2;
- if (this.options.locations) {
- lineBreakG.lastIndex = start;
- var match;
- while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) {
- ++this$1.curLine;
- this$1.lineStart = match.index + match[0].length;
- }
- }
- if (this.options.onComment)
- { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos,
- startLoc, this.curPosition()); }
-};
-
-pp$8.skipLineComment = function(startSkip) {
- var this$1 = this;
-
- var start = this.pos;
- var startLoc = this.options.onComment && this.curPosition();
- var ch = this.input.charCodeAt(this.pos += startSkip);
- while (this.pos < this.input.length && !isNewLine(ch)) {
- ch = this$1.input.charCodeAt(++this$1.pos);
- }
- if (this.options.onComment)
- { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos,
- startLoc, this.curPosition()); }
-};
-
-
-pp$8.skipSpace = function() {
- var this$1 = this;
-
- loop: while (this.pos < this.input.length) {
- var ch = this$1.input.charCodeAt(this$1.pos);
- switch (ch) {
- case 32: case 160:
- ++this$1.pos;
- break
- case 13:
- if (this$1.input.charCodeAt(this$1.pos + 1) === 10) {
- ++this$1.pos;
- }
- case 10: case 8232: case 8233:
- ++this$1.pos;
- if (this$1.options.locations) {
- ++this$1.curLine;
- this$1.lineStart = this$1.pos;
- }
- break
- case 47:
- switch (this$1.input.charCodeAt(this$1.pos + 1)) {
- case 42:
- this$1.skipBlockComment();
- break
- case 47:
- this$1.skipLineComment(2);
- break
- default:
- break loop
- }
- break
- default:
- if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
- ++this$1.pos;
- } else {
- break loop
- }
- }
- }
-};
-
-
-pp$8.finishToken = function(type, val) {
- this.end = this.pos;
- if (this.options.locations) { this.endLoc = this.curPosition(); }
- var prevType = this.type;
- this.type = type;
- this.value = val;
-
- this.updateContext(prevType);
-};
-
-
-pp$8.readToken_dot = function() {
- var next = this.input.charCodeAt(this.pos + 1);
- if (next >= 48 && next <= 57) { return this.readNumber(true) }
- var next2 = this.input.charCodeAt(this.pos + 2);
- if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) {
- this.pos += 3;
- return this.finishToken(types.ellipsis)
- } else {
- ++this.pos;
- return this.finishToken(types.dot)
- }
-};
-
-pp$8.readToken_slash = function() {
- var next = this.input.charCodeAt(this.pos + 1);
- if (this.exprAllowed) { ++this.pos; return this.readRegexp() }
- if (next === 61) { return this.finishOp(types.assign, 2) }
- return this.finishOp(types.slash, 1)
-};
-
-pp$8.readToken_mult_modulo_exp = function(code) {
- var next = this.input.charCodeAt(this.pos + 1);
- var size = 1;
- var tokentype = code === 42 ? types.star : types.modulo;
-
- if (this.options.ecmaVersion >= 7 && next === 42) {
- ++size;
- tokentype = types.starstar;
- next = this.input.charCodeAt(this.pos + 2);
- }
-
- if (next === 61) { return this.finishOp(types.assign, size + 1) }
- return this.finishOp(tokentype, size)
-};
-
-pp$8.readToken_pipe_amp = function(code) {
- var next = this.input.charCodeAt(this.pos + 1);
- if (next === code) { return this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2) }
- if (next === 61) { return this.finishOp(types.assign, 2) }
- return this.finishOp(code === 124 ? types.bitwiseOR : types.bitwiseAND, 1)
-};
-
-pp$8.readToken_caret = function() {
- var next = this.input.charCodeAt(this.pos + 1);
- if (next === 61) { return this.finishOp(types.assign, 2) }
- return this.finishOp(types.bitwiseXOR, 1)
-};
-
-pp$8.readToken_plus_min = function(code) {
- var next = this.input.charCodeAt(this.pos + 1);
- if (next === code) {
- if (next == 45 && this.input.charCodeAt(this.pos + 2) == 62 &&
- (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) {
- this.skipLineComment(3);
- this.skipSpace();
- return this.nextToken()
- }
- return this.finishOp(types.incDec, 2)
- }
- if (next === 61) { return this.finishOp(types.assign, 2) }
- return this.finishOp(types.plusMin, 1)
-};
-
-pp$8.readToken_lt_gt = function(code) {
- var next = this.input.charCodeAt(this.pos + 1);
- var size = 1;
- if (next === code) {
- size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;
- if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types.assign, size + 1) }
- return this.finishOp(types.bitShift, size)
- }
- if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 &&
- this.input.charCodeAt(this.pos + 3) == 45) {
- if (this.inModule) { this.unexpected(); }
- this.skipLineComment(4);
- this.skipSpace();
- return this.nextToken()
- }
- if (next === 61) { size = 2; }
- return this.finishOp(types.relational, size)
-};
-
-pp$8.readToken_eq_excl = function(code) {
- var next = this.input.charCodeAt(this.pos + 1);
- if (next === 61) { return this.finishOp(types.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2) }
- if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) {
- this.pos += 2;
- return this.finishToken(types.arrow)
- }
- return this.finishOp(code === 61 ? types.eq : types.prefix, 1)
-};
-
-pp$8.getTokenFromCode = function(code) {
- switch (code) {
- case 46:
- return this.readToken_dot()
-
- case 40: ++this.pos; return this.finishToken(types.parenL)
- case 41: ++this.pos; return this.finishToken(types.parenR)
- case 59: ++this.pos; return this.finishToken(types.semi)
- case 44: ++this.pos; return this.finishToken(types.comma)
- case 91: ++this.pos; return this.finishToken(types.bracketL)
- case 93: ++this.pos; return this.finishToken(types.bracketR)
- case 123: ++this.pos; return this.finishToken(types.braceL)
- case 125: ++this.pos; return this.finishToken(types.braceR)
- case 58: ++this.pos; return this.finishToken(types.colon)
- case 63: ++this.pos; return this.finishToken(types.question)
-
- case 96:
- if (this.options.ecmaVersion < 6) { break }
- ++this.pos;
- return this.finishToken(types.backQuote)
-
- case 48:
- var next = this.input.charCodeAt(this.pos + 1);
- if (next === 120 || next === 88) { return this.readRadixNumber(16) }
- if (this.options.ecmaVersion >= 6) {
- if (next === 111 || next === 79) { return this.readRadixNumber(8) }
- if (next === 98 || next === 66) { 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(false)
-
- case 34: case 39:
- return this.readString(code)
-
-
- case 47:
- return this.readToken_slash()
-
- case 37: case 42:
- return this.readToken_mult_modulo_exp(code)
-
- case 124: case 38:
- return this.readToken_pipe_amp(code)
-
- case 94:
- return this.readToken_caret()
-
- case 43: case 45:
- return this.readToken_plus_min(code)
-
- case 60: case 62:
- return this.readToken_lt_gt(code)
-
- case 61: case 33:
- return this.readToken_eq_excl(code)
-
- case 126:
- return this.finishOp(types.prefix, 1)
- }
-
- this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'");
-};
-
-pp$8.finishOp = function(type, size) {
- var str = this.input.slice(this.pos, this.pos + size);
- this.pos += size;
- return this.finishToken(type, str)
-};
-
-
-function tryCreateRegexp(src, flags, throwErrorAt, parser) {
- try {
- return new RegExp(src, flags)
- } catch (e) {
- if (throwErrorAt !== undefined) {
- if (e instanceof SyntaxError) { parser.raise(throwErrorAt, "Error parsing regular expression: " + e.message); }
- throw e
- }
- }
-}
-
-var regexpUnicodeSupport = !!tryCreateRegexp("\uffff", "u");
-
-pp$8.readRegexp = function() {
- var this$1 = this;
-
- var escaped, inClass, start = this.pos;
- for (;;) {
- if (this$1.pos >= this$1.input.length) { this$1.raise(start, "Unterminated regular expression"); }
- var ch = this$1.input.charAt(this$1.pos);
- if (lineBreak.test(ch)) { this$1.raise(start, "Unterminated regular expression"); }
- if (!escaped) {
- if (ch === "[") { inClass = true; }
- else if (ch === "]" && inClass) { inClass = false; }
- else if (ch === "/" && !inClass) { break }
- escaped = ch === "\\";
- } else { escaped = false; }
- ++this$1.pos;
- }
- var content = this.input.slice(start, this.pos);
- ++this.pos;
- var mods = this.readWord1();
- var tmp = content, tmpFlags = "";
- if (mods) {
- var validFlags = /^[gim]*$/;
- if (this.options.ecmaVersion >= 6) { validFlags = /^[gimuy]*$/; }
- if (!validFlags.test(mods)) { this.raise(start, "Invalid regular expression flag"); }
- if (mods.indexOf("u") >= 0) {
- if (regexpUnicodeSupport) {
- tmpFlags = "u";
- } else {
- tmp = tmp.replace(/\\u\{([0-9a-fA-F]+)\}/g, function (_match, code, offset) {
- code = Number("0x" + code);
- if (code > 0x10FFFF) { this$1.raise(start + offset + 3, "Code point out of bounds"); }
- return "x"
- });
- tmp = tmp.replace(/\\u([a-fA-F0-9]{4})|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x");
- tmpFlags = tmpFlags.replace("u", "");
- }
- }
- }
- var value = null;
- if (!isRhino) {
- tryCreateRegexp(tmp, tmpFlags, start, this);
- value = tryCreateRegexp(content, mods);
- }
- return this.finishToken(types.regexp, {pattern: content, flags: mods, value: value})
-};
-
-
-pp$8.readInt = function(radix, len) {
- var this$1 = this;
-
- var start = this.pos, total = 0;
- for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) {
- var code = this$1.input.charCodeAt(this$1.pos), val = (void 0);
- if (code >= 97) { val = code - 97 + 10; }
- else if (code >= 65) { val = code - 65 + 10; }
- else if (code >= 48 && code <= 57) { val = code - 48; }
- else { val = Infinity; }
- if (val >= radix) { break }
- ++this$1.pos;
- total = total * radix + val;
- }
- if (this.pos === start || len != null && this.pos - start !== len) { return null }
-
- return total
-};
-
-pp$8.readRadixNumber = function(radix) {
- this.pos += 2;
- var val = this.readInt(radix);
- if (val == null) { this.raise(this.start + 2, "Expected number in radix " + radix); }
- if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
- return this.finishToken(types.num, val)
-};
-
-
-pp$8.readNumber = function(startsWithDot) {
- var start = this.pos, isFloat = false, octal = this.input.charCodeAt(this.pos) === 48;
- if (!startsWithDot && this.readInt(10) === null) { this.raise(start, "Invalid number"); }
- if (octal && this.pos == start + 1) { octal = false; }
- var next = this.input.charCodeAt(this.pos);
- if (next === 46 && !octal) {
- ++this.pos;
- this.readInt(10);
- isFloat = true;
- next = this.input.charCodeAt(this.pos);
- }
- if ((next === 69 || next === 101) && !octal) {
- next = this.input.charCodeAt(++this.pos);
- if (next === 43 || next === 45) { ++this.pos; }
- if (this.readInt(10) === null) { this.raise(start, "Invalid number"); }
- isFloat = true;
- }
- if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
-
- var str = this.input.slice(start, this.pos), val;
- if (isFloat) { val = parseFloat(str); }
- else if (!octal || str.length === 1) { val = parseInt(str, 10); }
- else if (this.strict) { this.raise(start, "Invalid number"); }
- else if (/[89]/.test(str)) { val = parseInt(str, 10); }
- else { val = parseInt(str, 8); }
- return this.finishToken(types.num, val)
-};
-
-
-pp$8.readCodePoint = function() {
- var ch = this.input.charCodeAt(this.pos), code;
-
- if (ch === 123) {
- if (this.options.ecmaVersion < 6) { this.unexpected(); }
- var codePos = ++this.pos;
- code = this.readHexChar(this.input.indexOf("}", this.pos) - this.pos);
- ++this.pos;
- if (code > 0x10FFFF) { this.invalidStringToken(codePos, "Code point out of bounds"); }
- } else {
- code = this.readHexChar(4);
- }
- return code
-};
-
-function codePointToString(code) {
- if (code <= 0xFFFF) { return String.fromCharCode(code) }
- code -= 0x10000;
- return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00)
-}
-
-pp$8.readString = function(quote) {
- var this$1 = this;
-
- var out = "", chunkStart = ++this.pos;
- for (;;) {
- if (this$1.pos >= this$1.input.length) { this$1.raise(this$1.start, "Unterminated string constant"); }
- var ch = this$1.input.charCodeAt(this$1.pos);
- if (ch === quote) { break }
- if (ch === 92) {
- out += this$1.input.slice(chunkStart, this$1.pos);
- out += this$1.readEscapedChar(false);
- chunkStart = this$1.pos;
- } else {
- if (isNewLine(ch)) { this$1.raise(this$1.start, "Unterminated string constant"); }
- ++this$1.pos;
- }
- }
- out += this.input.slice(chunkStart, this.pos++);
- return this.finishToken(types.string, out)
-};
-
-
-var INVALID_TEMPLATE_ESCAPE_ERROR = {};
-
-pp$8.tryReadTemplateToken = function() {
- this.inTemplateElement = true;
- try {
- this.readTmplToken();
- } catch (err) {
- if (err === INVALID_TEMPLATE_ESCAPE_ERROR) {
- this.readInvalidTemplateToken();
- } else {
- throw err
- }
- }
-
- this.inTemplateElement = false;
-};
-
-pp$8.invalidStringToken = function(position, message) {
- if (this.inTemplateElement && this.options.ecmaVersion >= 9) {
- throw INVALID_TEMPLATE_ESCAPE_ERROR
- } else {
- this.raise(position, message);
- }
-};
-
-pp$8.readTmplToken = function() {
- var this$1 = this;
-
- var out = "", chunkStart = this.pos;
- for (;;) {
- if (this$1.pos >= this$1.input.length) { this$1.raise(this$1.start, "Unterminated template"); }
- var ch = this$1.input.charCodeAt(this$1.pos);
- if (ch === 96 || ch === 36 && this$1.input.charCodeAt(this$1.pos + 1) === 123) {
- if (this$1.pos === this$1.start && (this$1.type === types.template || this$1.type === types.invalidTemplate)) {
- if (ch === 36) {
- this$1.pos += 2;
- return this$1.finishToken(types.dollarBraceL)
- } else {
- ++this$1.pos;
- return this$1.finishToken(types.backQuote)
- }
- }
- out += this$1.input.slice(chunkStart, this$1.pos);
- return this$1.finishToken(types.template, out)
- }
- if (ch === 92) {
- out += this$1.input.slice(chunkStart, this$1.pos);
- out += this$1.readEscapedChar(true);
- chunkStart = this$1.pos;
- } else if (isNewLine(ch)) {
- out += this$1.input.slice(chunkStart, this$1.pos);
- ++this$1.pos;
- switch (ch) {
- case 13:
- if (this$1.input.charCodeAt(this$1.pos) === 10) { ++this$1.pos; }
- case 10:
- out += "\n";
- break
- default:
- out += String.fromCharCode(ch);
- break
- }
- if (this$1.options.locations) {
- ++this$1.curLine;
- this$1.lineStart = this$1.pos;
- }
- chunkStart = this$1.pos;
- } else {
- ++this$1.pos;
- }
- }
-};
-
-pp$8.readInvalidTemplateToken = function() {
- var this$1 = this;
-
- for (; this.pos < this.input.length; this.pos++) {
- switch (this$1.input[this$1.pos]) {
- case "\\":
- ++this$1.pos;
- break
-
- case "$":
- if (this$1.input[this$1.pos + 1] !== "{") {
- break
- }
-
- case "`":
- return this$1.finishToken(types.invalidTemplate, this$1.input.slice(this$1.start, this$1.pos))
-
- }
- }
- this.raise(this.start, "Unterminated template");
-};
-
-
-pp$8.readEscapedChar = function(inTemplate) {
- var ch = this.input.charCodeAt(++this.pos);
- ++this.pos;
- switch (ch) {
- case 110: return "\n"
- case 114: return "\r"
- case 120: return String.fromCharCode(this.readHexChar(2))
- case 117: return codePointToString(this.readCodePoint())
- case 116: return "\t"
- case 98: return "\b"
- case 118: return "\u000b"
- case 102: return "\f"
- case 13: if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; }
- case 10:
- if (this.options.locations) { this.lineStart = this.pos; ++this.curLine; }
- return ""
- default:
- if (ch >= 48 && ch <= 55) {
- var octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0];
- var octal = parseInt(octalStr, 8);
- if (octal > 255) {
- octalStr = octalStr.slice(0, -1);
- octal = parseInt(octalStr, 8);
- }
- if (octalStr !== "0" && (this.strict || inTemplate)) {
- this.invalidStringToken(this.pos - 2, "Octal literal in strict mode");
- }
- this.pos += octalStr.length - 1;
- return String.fromCharCode(octal)
- }
- return String.fromCharCode(ch)
- }
-};
-
-
-pp$8.readHexChar = function(len) {
- var codePos = this.pos;
- var n = this.readInt(16, len);
- if (n === null) { this.invalidStringToken(codePos, "Bad character escape sequence"); }
- return n
-};
-
-
-pp$8.readWord1 = function() {
- var this$1 = this;
-
- this.containsEsc = false;
- var word = "", first = true, chunkStart = this.pos;
- var astral = this.options.ecmaVersion >= 6;
- while (this.pos < this.input.length) {
- var ch = this$1.fullCharCodeAtPos();
- if (isIdentifierChar(ch, astral)) {
- this$1.pos += ch <= 0xffff ? 1 : 2;
- } else if (ch === 92) {
- this$1.containsEsc = true;
- word += this$1.input.slice(chunkStart, this$1.pos);
- var escStart = this$1.pos;
- if (this$1.input.charCodeAt(++this$1.pos) != 117)
- { this$1.invalidStringToken(this$1.pos, "Expecting Unicode escape sequence \\uXXXX"); }
- ++this$1.pos;
- var esc = this$1.readCodePoint();
- if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral))
- { this$1.invalidStringToken(escStart, "Invalid Unicode escape"); }
- word += codePointToString(esc);
- chunkStart = this$1.pos;
- } else {
- break
- }
- first = false;
- }
- return word + this.input.slice(chunkStart, this.pos)
-};
-
-
-pp$8.readWord = function() {
- var word = this.readWord1();
- var type = types.name;
- if (this.keywords.test(word)) {
- if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword " + word); }
- type = keywords$1[word];
- }
- return this.finishToken(type, word)
-};
-
-
-var version = "5.1.1";
-
-
-function parse(input, options) {
- return new Parser(options, input).parse()
-}
-
-
-function parseExpressionAt(input, pos, options) {
- var p = new Parser(options, input, pos);
- p.nextToken();
- return p.parseExpression()
-}
-
-
-function tokenizer(input, options) {
- return new Parser(options, input)
-}
-
-function addLooseExports(parse, Parser$$1, plugins$$1) {
- exports.parse_dammit = parse;
- exports.LooseParser = Parser$$1;
- exports.pluginsLoose = plugins$$1;
-}
-
-exports.version = version;
-exports.parse = parse;
-exports.parseExpressionAt = parseExpressionAt;
-exports.tokenizer = tokenizer;
-exports.addLooseExports = addLooseExports;
-exports.Parser = Parser;
-exports.plugins = plugins;
-exports.defaultOptions = defaultOptions;
-exports.Position = Position;
-exports.SourceLocation = SourceLocation;
-exports.getLineInfo = getLineInfo;
-exports.Node = Node;
-exports.TokenType = TokenType;
-exports.tokTypes = types;
-exports.keywordTypes = keywords$1;
-exports.TokContext = TokContext;
-exports.tokContexts = types$1;
-exports.isIdentifierChar = isIdentifierChar;
-exports.isIdentifierStart = isIdentifierStart;
-exports.Token = Token;
-exports.isNewLine = isNewLine;
-exports.lineBreak = lineBreak;
-exports.lineBreakG = lineBreakG;
-exports.nonASCIIwhitespace = nonASCIIwhitespace;
-
-Object.defineProperty(exports, '__esModule', { value: true });
-
-})));
-
-},{}],28:[function(require,module,exports){
-
-},{}]},{},[26]);
diff --git a/bin/gpu.min.js b/bin/gpu.min.js
deleted file mode 100644
index 68273f75..00000000
--- a/bin/gpu.min.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * gpu.js
- * http://gpu.rocks/
- *
- * GPU Accelerated JavaScript
- *
- * @version 1.0.0-rc.7
- * @date Sat Nov 11 2017 08:38:09 GMT-0500 (EST)
- *
- * @license MIT
- * The MIT License
- *
- * Copyright (c) 2017 gpu.js Team
- */
-"use strict";!function t(e,n,r){function i(a,o){if(!n[a]){if(!e[a]){var u="function"==typeof require&&require;if(!o&&u)return u(a,!0);if(s)return s(a,!0);var h=new Error("Cannot find module '"+a+"'");throw h.code="MODULE_NOT_FOUND",h}var l=n[a]={exports:{}};e[a][0].call(l.exports,function(t){var n=e[a][1][t];return i(n?n:t)},l,l.exports,t,e,n,r)}return n[a].exports}for(var s="function"==typeof require&&require,a=0;a0&&e.push(", "),e.push(" "),e.push("user_"),e.push(i)}e.push(") {\n")}for(var s=0;s1){for(var a=null,o=0;o0&&e.push(","),this.astGeneric(t.declarations[r],e,n);return e.push(";"),e}},{key:"astVariableDeclarator",value:function(t,e,n){return this.astGeneric(t.id,e,n),null!==t.init&&(e.push("="),this.astGeneric(t.init,e,n)),e}},{key:"astIfStatement",value:function(t,e,n){return e.push("if ("),this.astGeneric(t.test,e,n),e.push(")"),"BlockStatement"===t.consequent.type?this.astGeneric(t.consequent,e,n):(e.push(" {\n"),this.astGeneric(t.consequent,e,n),e.push("\n}\n")),t.alternate&&(e.push("else "),"BlockStatement"===t.alternate.type?this.astGeneric(t.alternate,e,n):(e.push(" {\n"),this.astGeneric(t.alternate,e,n),e.push("\n}\n"))),e}},{key:"astBreakStatement",value:function(t,e,n){return e.push("break;\n"),e}},{key:"astContinueStatement",value:function(t,e,n){return e.push("continue;\n"),e}},{key:"astLogicalExpression",value:function(t,e,n){return e.push("("),this.astGeneric(t.left,e,n),e.push(t.operator),this.astGeneric(t.right,e,n),e.push(")"),e}},{key:"astUpdateExpression",value:function(t,e,n){return t.prefix?(e.push(t.operator),this.astGeneric(t.argument,e,n)):(this.astGeneric(t.argument,e,n),e.push(t.operator)),e}},{key:"astUnaryExpression",value:function(t,e,n){return t.prefix?(e.push(t.operator),this.astGeneric(t.argument,e,n)):(this.astGeneric(t.argument,e,n),e.push(t.operator)),e}},{key:"astThisExpression",value:function(t,e,n){return e.push("_this"),e}},{key:"astMemberExpression",value:function(t,e,n){if(t.computed)if("Identifier"===t.object.type)this.astGeneric(t.object,e,n),e.push("["),this.astGeneric(t.property,e,n),e.push("]");else{this.astGeneric(t.object,e,n);var r=e.pop();e.push("]["),this.astGeneric(t.property,e,n),e.push(r)}else{var i=this.astMemberExpressionUnroll(t);switch("Identifier"===t.property.type&&t.computed&&(i="user_"+i),0===i.indexOf("this")&&(i="_"+i),i){case"_this.output.x":e.push(this.output[0]);break;case"_this.output.y":e.push(this.output[1]);break;case"_this.output.z":e.push(this.output[2]);break;default:e.push(i)}}return e}},{key:"astSequenceExpression",value:function(t,e,n){for(var r=0;r0&&e.push(","),this.astGeneric(t.expressions,e,n);return e}},{key:"astCallExpression",value:function(t,e,n){if(t.callee){var r=this.astMemberExpressionUnroll(t.callee);n.calledFunctions.indexOf(r)<0&&n.calledFunctions.push(r),n.hasOwnProperty("funcName")||(n.calledFunctionsArguments[r]=[]);var i=[];n.calledFunctionsArguments[r].push(i),e.push(r),e.push("(");for(var s=0;s0&&e.push(", "),this.astGeneric(a,e,n),"Identifier"===a.type){var o=n.paramNames.indexOf(a.name);o===-1?i.push(null):i.push({name:a.name,type:n.paramTypes[o]})}else i.push(null)}return e.push(")"),e}throw this.astErrorOutput("Unknown CallExpression",t,n)}},{key:"astArrayExpression",value:function(t,e,n){var r=t.elements.length;e.push("new Float32Array(");for(var i=0;i0&&e.push(", ");var s=t.elements[i];this.astGeneric(s,e,n)}return e.push(")"),e}},{key:"astDebuggerStatement",value:function(t,e,n){return e.push("debugger;"),e}}],[{key:"astFunctionPrototype",value:function(t,e,n){if(n.isRootKernel||n.isSubKernel)return e;e.push(n.returnType),e.push(" "),e.push(n.functionName),e.push("(");for(var r=0;r0&&e.push(", "),e.push(n.paramTypes[r]),e.push(" "),e.push("user_"),e.push(n.paramNames[r]);return e.push(");\n"),e}}]),e}(o)},{"../../core/utils":25,"../function-node-base":7}],3:[function(t,e,n){var r=t("../../core/utils"),i=t("../kernel-run-shortcut");e.exports=function(t,e){return"() => {\n "+i.toString()+";\n const utils = {\n allPropertiesOf: function "+r.allPropertiesOf.toString()+",\n clone: function "+r.clone.toString()+",\n /*splitArray: function "+r.splitArray.toString()+",\n getArgumentType: function "+r.getArgumentType.toString()+",\n getOutput: function "+r.getOutput.toString()+",\n dimToTexSize: function "+r.dimToTexSize.toString()+",\n copyFlatten: function "+r.copyFlatten.toString()+",\n flatten: function "+r.flatten.toString()+",\n systemEndianness: '"+r.systemEndianness()+"',\n initWebGl: function "+r.initWebGl.toString()+",\n isArray: function "+r.isArray.toString()+"*/\n };\n class "+(e||"Kernel")+" {\n constructor() { \n this.argumentsLength = 0;\n this._canvas = null;\n this._webGl = null;\n this.built = false;\n this.program = null;\n this.paramNames = "+JSON.stringify(t.paramNames)+";\n this.paramTypes = "+JSON.stringify(t.paramTypes)+";\n this.texSize = "+JSON.stringify(t.texSize)+";\n this.output = "+JSON.stringify(t.output)+";\n this._kernelString = `"+t._kernelString+"`;\n this.output = "+JSON.stringify(t.output)+";\n\t\t this.run = function() {\n this.run = null;\n this.build();\n return this.run.apply(this, arguments);\n }.bind(this);\n this.thread = {\n x: 0,\n y: 0,\n z: 0\n };\n }\n setCanvas(canvas) { this._canvas = canvas; return this; }\n setWebGl(webGl) { this._webGl = webGl; return this; }\n "+t.build.toString()+"\n run () { "+t.kernelString+" }\n getKernelString() { return this._kernelString; }\n };\n return kernelRunShortcut(new Kernel());\n };"}},{"../../core/utils":25,"../kernel-run-shortcut":9}],4:[function(t,e,n){function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}var a=function(){function t(t,e){for(var n=0;n0?h.join("\n"):"")+"\n }.bind(this);";return p}},{key:"toString",value:function(){return h(this)}},{key:"precompileKernelObj",value:function(t){var e=this.threadDim||(this.threadDim=u.clone(this.output));return{threadDim:e}}},{key:"_getLoopMaxString",value:function(){return this.loopMaxIterations?" "+parseInt(this.loopMaxIterations)+";\n":" 1000;\n"}}],[{key:"compileKernel",value:function(t){for(var e=t.threadDim;e.length<3;)e.push(1)}}]),e}(o)},{"../../core/utils":25,"../kernel-base":8,"./kernel-string":3}],5:[function(t,e,n){function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}var a=function(){function t(t,e){for(var n=0;n=0||e.push(t)),e}},{key:"addKernel",value:function(t,e,n,r){var i=new this.Node("kernel",t,e,r);return i.setAddFunction(this.addFunction.bind(this)),i.paramNames=n,i.paramTypes=r,i.isRootKernel=!0,this.addFunctionNode(i),i}},{key:"addSubKernel",value:function(t,e,n,r){var i=new this.Node(null,t,e,n,r);return i.setAddFunction(this.addFunction.bind(this)),i.isSubKernel=!0,this.addFunctionNode(i),i}},{key:"getPrototypeString",value:function(t){return this.getPrototypes(t).join("\n")}},{key:"getPrototypes",value:function(t){return this.rootKernel.generate(),t?this.getPrototypesFromFunctionNames(this.traceFunctionCalls(t,[]).reverse()):this.getPrototypesFromFunctionNames(Object.keys(this.nodeMap))}},{key:"getStringFromFunctionNames",value:function(t){for(var e=[],n=0;n ("+r.length+","+this.paramNames.length+")";this.paramTypes=r}else if("object"===("undefined"==typeof r?"undefined":_typeof(r))){var s=Object.keys(r);if(r.hasOwnProperty("returns")&&(this.returnType=r.returns,s.splice(s.indexOf("returns"),1)),s.length>0&&s.length!==this.paramNames.length)throw"Invalid argument type array length, against function length -> ("+s.length+","+this.paramNames.length+")";this.paramTypes=this.paramNames.map(function(t){return r.hasOwnProperty(t)?r[t]:"float"})}}else this.paramTypes=[];this.returnType||(this.returnType=i||"float")}return _createClass(BaseFunctionNode,[{key:"isIdentifierConstant",value:function(t){return!!this.constants&&this.constants.hasOwnProperty(t)}},{key:"setAddFunction",value:function(t){return this.addFunction=t,this}},{key:"getJsFunction",value:function getJsFunction(){if(this.jsFunction)return this.jsFunction;if(this.jsFunctionString)return this.jsFunction=eval(this.jsFunctionString),this.jsFunction;throw"Missing jsFunction, and jsFunctionString parameter"}},{key:"astMemberExpressionUnroll",value:function(t,e){if("Identifier"===t.type)return t.name;if("ThisExpression"===t.type)return"this";if("MemberExpression"===t.type&&t.object&&t.property)return t.object.hasOwnProperty("name")&&"_"===t.object.name[0]?this.astMemberExpressionUnroll(t.property,e):this.astMemberExpressionUnroll(t.object,e)+"."+this.astMemberExpressionUnroll(t.property,e);if(t.hasOwnProperty("expressions")){var n=t.expressions[0];if("Literal"===n.type&&0===n.value&&2===t.expressions.length)return this.astMemberExpressionUnroll(t.expressions[1])}throw this.astErrorOutput("Unknown CallExpression_unroll",t,e)}},{key:"getJsAST",value:function(t){if(this.jsFunctionAST)return this.jsFunctionAST;if(t=t||acorn,null===t)throw"Missing JS to AST parser";var e=t.parse("var "+this.functionName+" = "+this.jsFunctionString+";",{locations:!0});if(null===e)throw"Failed to parse JS code";var n=e.body[0].declarations[0].init;return this.jsFunctionAST=n,n}},{key:"getFunctionString",value:function(){return this.generate(),this.functionString}},{key:"setFunctionString",value:function(t){this.functionString=t}},{key:"getParamType",value:function(t){var e=this.paramNames.indexOf(t);if(e===-1)return null;if(!this.parent)return null;if(this.paramTypes[e])return this.paramTypes[e];for(var n=this.parent.calledFunctionsArguments[this.functionName],r=0;r0&&e.push(", ");var s=n.getParamType(i);switch(s){case"Texture":case"Input":case"Array":e.push("sampler2D");break;default:e.push("float")}e.push(" "),e.push("user_"),e.push(i)}e.push(") {\n");for(var a=0;a1){for(var a=null,o=0;o0&&e.push(","),this.astGeneric(t.declarations[r],e,n);return e.push(";"),e}},{key:"astVariableDeclarator",value:function(t,e,n){return this.astGeneric(t.id,e,n),null!==t.init&&(e.push("="),this.astGeneric(t.init,e,n)),e}},{key:"astIfStatement",value:function(t,e,n){return e.push("if ("),this.astGeneric(t.test,e,n),e.push(")"),"BlockStatement"===t.consequent.type?this.astGeneric(t.consequent,e,n):(e.push(" {\n"),this.astGeneric(t.consequent,e,n),e.push("\n}\n")),t.alternate&&(e.push("else "),"BlockStatement"===t.alternate.type?this.astGeneric(t.alternate,e,n):(e.push(" {\n"),this.astGeneric(t.alternate,e,n),e.push("\n}\n"))),e}},{key:"astBreakStatement",value:function(t,e,n){return e.push("break;\n"),e}},{key:"astContinueStatement",value:function(t,e,n){return e.push("continue;\n"),e}},{key:"astLogicalExpression",value:function(t,e,n){return e.push("("),this.astGeneric(t.left,e,n),e.push(t.operator),this.astGeneric(t.right,e,n),e.push(")"),e}},{key:"astUpdateExpression",value:function(t,e,n){return t.prefix?(e.push(t.operator),this.astGeneric(t.argument,e,n)):(this.astGeneric(t.argument,e,n),e.push(t.operator)),e}},{key:"astUnaryExpression",value:function(t,e,n){return t.prefix?(e.push(t.operator),this.astGeneric(t.argument,e,n)):(this.astGeneric(t.argument,e,n),e.push(t.operator)),e}},{key:"astThisExpression",value:function(t,e,n){return e.push("this"),e}},{key:"astMemberExpression",value:function(t,e,n){if(t.computed)if("Identifier"===t.object.type){var r=t.object.name,i=(n.functionName||"kernel",!1);if(n.paramNames){var s=n.paramNames.indexOf(r);s>=0&&"float"===n.paramTypes[s]&&(i=!0)}i?(this.astGeneric(t.object,e,n),e.push("[int("),this.astGeneric(t.property,e,n),e.push(")]")):(e.push("get("),this.astGeneric(t.object,e,n),e.push(", vec2("),this.astGeneric(t.object,e,n),e.push("Size[0],"),this.astGeneric(t.object,e,n),e.push("Size[1]), vec3("),this.astGeneric(t.object,e,n),e.push("Dim[0],"),this.astGeneric(t.object,e,n),e.push("Dim[1],"),this.astGeneric(t.object,e,n),e.push("Dim[2]"),e.push("), "),this.astGeneric(t.property,e,n),e.push(")"))}else{this.astGeneric(t.object,e,n);var a=e.pop();e.push(","),this.astGeneric(t.property,e,n),e.push(a)}else{var o=this.astMemberExpressionUnroll(t),u=o.toLowerCase();switch(0===o.indexOf(c)&&(o="constants_"+o.slice(c.length)),u){case"this.thread.x":e.push("threadId.x");break;case"this.thread.y":e.push("threadId.y");break;case"this.thread.z":e.push("threadId.z");break;case"this.output.x":e.push(this.output[0]+".0");break;case"this.output.y":e.push(this.output[1]+".0");break;case"this.output.z":e.push(this.output[2]+".0");break;default:e.push(o)}}return e}},{key:"astSequenceExpression",value:function(t,e,n){for(var r=0;r0&&e.push(","),this.astGeneric(t.expressions,e,n);return e}},{key:"astCallExpression",value:function(t,e,n){if(t.callee){var r=this.astMemberExpressionUnroll(t.callee);0===r.indexOf(l)&&(r=r.slice(l.length)),0===r.indexOf(p)&&(r=r.slice(p.length)),n.calledFunctions.indexOf(r)<0&&n.calledFunctions.push(r),n.hasOwnProperty("funcName")||(n.calledFunctionsArguments[r]=[]);var i=[];n.calledFunctionsArguments[r].push(i),e.push(r),e.push("(");for(var s=0;s0&&e.push(", "),this.astGeneric(a,e,n),"Identifier"===a.type){var o=n.paramNames.indexOf(a.name);o===-1?i.push(null):i.push({name:a.name,type:n.paramTypes[o]})}else i.push(null)}return e.push(")"),e}throw this.astErrorOutput("Unknown CallExpression",t,n)}},{key:"astArrayExpression",value:function(t,e,n){var r=t.elements.length;e.push("float["+r+"](");for(var i=0;i0&&e.push(", ");var s=t.elements[i];this.astGeneric(s,e,n)}return e.push(")"),e}},{key:"getFunctionPrototypeString",value:function(){return this.webGlFunctionPrototypeString?this.webGlFunctionPrototypeString:this.webGlFunctionPrototypeString=this.generate()}},{key:"build",value:function(){return this.getFunctionPrototypeString().length>0}}],[{key:"astFunctionPrototype",value:function(t,e,n){if(n.isRootKernel||n.isSubKernel)return e;e.push(n.returnType),e.push(" "),e.push(n.functionName),e.push("(");for(var r=0;r0&&e.push(", "),e.push(n.paramTypes[r]),e.push(" "),e.push("user_"),e.push(n.paramNames[r]);return e.push(");\n"),e}}]),e}(u)},{"../../core/utils":25,"../function-node-base":7}],13:[function(t,e,n){var r=t("../../core/utils"),i=t("../kernel-run-shortcut");e.exports=function(t,e){return"() => {\n "+i.toString()+";\n const utils = {\n allPropertiesOf: function "+r.allPropertiesOf.toString()+",\n clone: function "+r.clone.toString()+",\n splitArray: function "+r.splitArray.toString()+",\n getArgumentType: function "+r.getArgumentType.toString()+",\n getDimensions: function "+r.getDimensions.toString()+",\n dimToTexSize: function "+r.dimToTexSize.toString()+",\n copyFlatten: function "+r.copyFlatten.toString()+",\n flatten: function "+r.flatten.toString()+",\n systemEndianness: '"+r.systemEndianness()+"',\n initWebGl: function "+r.initWebGl.toString()+",\n isArray: function "+r.isArray.toString()+"\n };\n class "+(e||"Kernel")+" {\n constructor() {\n this.argumentsLength = 0;\n this._canvas = null;\n this._webGl = null;\n this.built = false;\n this.program = null;\n this.paramNames = "+JSON.stringify(t.paramNames)+";\n this.paramTypes = "+JSON.stringify(t.paramTypes)+";\n this.texSize = "+JSON.stringify(t.texSize)+";\n this.output = "+JSON.stringify(t.output)+";\n this.compiledFragShaderString = `"+t.compiledFragShaderString+"`;\n\t\t this.compiledVertShaderString = `"+t.compiledVertShaderString+"`;\n\t\t this.programUniformLocationCache = {};\n\t\t this.textureCache = {};\n\t\t this.subKernelOutputTextures = null;\n }\n "+t._getFragShaderString.toString()+"\n "+t._getVertShaderString.toString()+"\n validateOptions() {}\n setupParams() {}\n setCanvas(canvas) { this._canvas = canvas; return this; }\n setWebGl(webGl) { this._webGl = webGl; return this; }\n "+t.getUniformLocation.toString()+"\n "+t.setupParams.toString()+"\n "+t.build.toString()+"\n\t\t "+t.run.toString()+"\n\t\t "+t._addArgument.toString()+"\n\t\t "+t.getArgumentTexture.toString()+"\n\t\t "+t.getTextureCache.toString()+"\n\t\t "+t.getOutputTexture.toString()+"\n\t\t "+t.renderOutput.toString()+"\n };\n return kernelRunShortcut(new Kernel());\n };"}},{"../../core/utils":25,"../kernel-run-shortcut":9}],14:[function(t,e,n){function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}var a=function(){function t(t,e){for(var n=0;n0?t.join(";\n")+";\n":"\n"}},{key:"_replaceArtifacts",value:function(t,e){return t.replace(/[ ]*__([A-Z]+[0-9]*([_]?[A-Z])*)__;\n/g,function(t,n){if(e.hasOwnProperty(n))return e[n];throw"unhandled artifact "+n})}},{key:"_addKernels",value:function(){var t=this.functionBuilder,e=this._webGl;if(t.addFunctions(this.functions,{constants:this.constants,output:this.output}),t.addNativeFunctions(this.nativeFunctions),t.addKernel(this.fnString,{prototypeOnly:!1,constants:this.constants,output:this.output,debug:this.debug,loopMaxIterations:this.loopMaxIterations},this.paramNames,this.paramTypes),null!==this.subKernels){var n=this.ext=e.getExtension("WEBGL_draw_buffers");if(!n)throw new Error("could not instantiate draw buffers extension");this.subKernelOutputTextures=[],this.subKernelOutputVariableNames=[];for(var r=0;r floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nhighp int integerMod(highp int x, highp int y) {\n return int(integerMod(float(x), float(y)));\n}\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\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\nhighp float decode32(highp vec4 rgba) {\n __DECODE32_ENDIANNESS__;\n rgba *= 255.0;\n vec2 gte128;\n gte128.x = rgba.b >= 128.0 ? 1.0 : 0.0;\n gte128.y = rgba.a >= 128.0 ? 1.0 : 0.0;\n float exponent = 2.0 * rgba.a - 127.0 + dot(gte128, MAGIC_VEC);\n float res = exp2(round(exponent));\n rgba.b = rgba.b - 128.0 * gte128.x;\n res = dot(rgba, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;\n res *= gte128.y * -2.0 + 1.0;\n return res;\n}\n\nhighp vec4 encode32(highp float f) {\n highp float F = abs(f);\n highp float sign = f < 0.0 ? 1.0 : 0.0;\n highp float exponent = floor(log2(F));\n highp float mantissa = (exp2(-exponent) * F);\n // exponent += floor(log2(mantissa));\n vec4 rgba = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n rgba.rg = integerMod(rgba.rg, 256.0);\n rgba.b = integerMod(rgba.b, 128.0);\n rgba.a = exponent*0.5 + 63.5;\n rgba.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n rgba = floor(rgba);\n rgba *= 0.003921569; // 1/255\n __ENCODE32_ENDIANNESS__;\n return rgba;\n}\n// Dragons end here\n\nhighp float index;\nhighp vec3 threadId;\n\nhighp vec3 indexTo3D(highp float idx, highp vec3 texDim) {\n highp float z = floor(idx / (texDim.x * texDim.y));\n idx -= z * texDim.x * texDim.y;\n highp float y = floor(idx / texDim.x);\n highp float x = integerMod(idx, texDim.x);\n return vec3(x, y, z);\n}\n\nhighp float get(highp sampler2D tex, highp vec2 texSize, highp vec3 texDim, highp float z, highp float y, highp float x) {\n highp vec3 xyz = vec3(x, y, z);\n xyz = floor(xyz + 0.5);\n __GET_WRAPAROUND__;\n highp float index = round(xyz.x + texDim.x * (xyz.y + texDim.y * xyz.z));\n __GET_TEXTURE_CHANNEL__;\n highp float w = round(texSize.x);\n vec2 st = vec2(integerMod(index, w), float(int(index) / int(w))) + 0.5;\n __GET_TEXTURE_INDEX__;\n highp vec4 texel = texture2D(tex, st / texSize);\n __GET_RESULT__;\n}\n\nhighp float get(highp sampler2D tex, highp vec2 texSize, highp vec3 texDim, highp float y, highp float x) {\n return get(tex, texSize, texDim, 0.0, y, x);\n}\n\nhighp float get(highp sampler2D tex, highp vec2 texSize, highp vec3 texDim, highp float x) {\n return get(tex, texSize, texDim, 0.0, 0.0, x);\n}\n\nhighp vec4 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\n__MAIN_PARAMS__;\n__MAIN_CONSTANTS__;\n__KERNEL__;\n\nvoid main(void) {\n index = floor(vTexCoord.s * float(uTexSize.x)) + floor(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n __MAIN_RESULT__;\n}"},{}],17:[function(t,e,n){e.exports="precision highp float;\nprecision highp int;\nprecision highp sampler2D;\n\nattribute highp vec2 aPos;\nattribute highp vec2 aTexCoord;\n\nvarying highp 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}"},{}],18:[function(t,e,n){function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}var a=function(){function t(t,e){for(var n=0;nt)return!1;if(n+=e[r+1],n>=t)return!0}}function n(t,n){return t<65?36===t:t<91||(t<97?95===t:t<123||(t<=65535?t>=170&&T.test(String.fromCharCode(t)):n!==!1&&e(t,A)))}function r(t,n){return t<48?36===t:t<58||!(t<65)&&(t<91||(t<97?95===t:t<123||(t<=65535?t>=170&&w.test(String.fromCharCode(t)):n!==!1&&(e(t,A)||e(t,O)))))}function i(t,e){return new N(t,{beforeExpr:!0,binop:e})}function s(t,e){return void 0===e&&(e={}),e.keyword=t,F[t]=new N(t,e)}function a(t){return 10===t||13===t||8232===t||8233===t}function o(t,e){return U.call(t,e)}function u(t,e){for(var n=1,r=0;;){I.lastIndex=r;var i=I.exec(t);if(!(i&&i.index=2015&&(e.ecmaVersion-=2009),null==e.allowReserved&&(e.allowReserved=e.ecmaVersion<5),B(e.onToken)){var r=e.onToken;e.onToken=function(t){return r.push(t)}}return B(e.onComment)&&(e.onComment=l(e,e.onComment)),e}function l(t,e){return function(n,r,i,s,a,o){var u={type:n?"Block":"Line",value:r,start:i,end:s};t.locations&&(u.loc=new K(this,a,o)),t.ranges&&(u.range=[i,s]),e.push(u)}}function p(t){return new RegExp("^(?:"+t.replace(/ /g,"|")+")$")}function c(){this.shorthandAssign=this.trailingComma=this.parenthesizedAssign=this.parenthesizedBind=-1}function f(t,e,n,r){return t.type=e,t.end=n,this.options.locations&&(t.loc.end=r),this.options.ranges&&(t.range[1]=n),t}function d(t,e,n,r){try{return new RegExp(t,e)}catch(i){if(void 0!==n)throw i instanceof SyntaxError&&r.raise(n,"Error parsing regular expression: "+i.message),i}}function m(t){return t<=65535?String.fromCharCode(t):(t-=65536,String.fromCharCode((t>>10)+55296,(1023&t)+56320))}function g(t,e){return new X(e,t).parse()}function y(t,e,n){var r=new X(n,t,e);return r.nextToken(),r.parseExpression()}function v(t,e){return new X(e,t)}function b(e,n,r){t.parse_dammit=e,t.LooseParser=n,t.pluginsLoose=r}var x={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"},k="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",S={5:k,6:k+" const class extends export import super"},E="ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙա-ևא-תװ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࢠ-ࢴࢶ-ࢽऄ-हऽॐक़-ॡॱ-ঀঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡૹଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-హఽౘ-ౚౠౡಀಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡೱೲഅ-ഌഎ-ഐഒ-ഺഽൎൔ-ൖൟ-ൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏽᏸ-ᏽᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᢰ-ᣵᤀ-ᤞᥐ-ᥭᥰ-ᥴᦀ-ᦫᦰ-ᧉᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᲀ-ᲈᳩ-ᳬᳮ-ᳱᳵᳶᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕ℘-ℝℤΩℨK-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ々-〇〡-〩〱-〵〸-〼ぁ-ゖ゛-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿕ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚝꚠ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꞮꞰ-ꞷꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꣽꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꩾ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭥꭰ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ",_="·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-٩ٰۖ-ۜ۟-۪ۤۧۨ-ۭ۰-۹ܑܰ-݊ަ-ް߀-߉߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛ࣔ-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣ०-९ঁ-ঃ়া-ৄেৈো-্ৗৢৣ০-৯ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑ੦-ੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣ૦-૯ଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣ୦-୯ஂா-ூெ-ைொ-்ௗ௦-௯ఀ-ఃా-ౄె-ైొ-్ౕౖౢౣ౦-౯ಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣ೦-೯ഁ-ഃാ-ൄെ-ൈൊ-്ൗൢൣ൦-൯ංඃ්ා-ුූෘ-ෟ෦-෯ෲෳัิ-ฺ็-๎๐-๙ັິ-ູົຼ່-ໍ໐-໙༘༙༠-༩༹༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှ၀-၉ၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏ-ႝ፝-፟፩-፱ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝០-៩᠋-᠍᠐-᠙ᢩᤠ-ᤫᤰ-᤻᥆-᥏᧐-᧚ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼-᪉᪐-᪙᪰-᪽ᬀ-ᬄ᬴-᭄᭐-᭙᭫-᭳ᮀ-ᮂᮡ-ᮭ᮰-᮹᯦-᯳ᰤ-᰷᱀-᱉᱐-᱙᳐-᳔᳒-᳨᳭ᳲ-᳴᳸᳹᷀-᷵᷻-᷿‿⁀⁔⃐-⃥⃜⃡-⃰⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꘠-꘩꙯ꙴ-꙽ꚞꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-ꣅ꣐-꣙꣠-꣱꤀-꤉ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀꧐-꧙ꧥ꧰-꧹ꨩ-ꨶꩃꩌꩍ꩐-꩙ꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭꯰-꯹ﬞ︀-️︠-︯︳︴﹍-﹏0-9_",T=new RegExp("["+E+"]"),w=new RegExp("["+E+_+"]");E=_=null;var A=[0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,17,26,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,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,26,45,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,785,52,76,44,33,24,27,35,42,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,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,159,52,19,3,54,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,86,25,391,63,32,0,449,56,264,8,2,36,18,0,50,29,881,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,881,68,12,0,67,12,65,0,32,6124,20,754,9486,1,3071,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,4149,196,60,67,1213,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,42710,42,4148,12,221,3,5761,10591,541],O=[509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,1306,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,52,0,13,2,49,13,10,2,4,9,83,11,7,0,161,11,6,9,7,3,57,0,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,87,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,423,9,838,7,2,7,17,9,57,21,2,13,19882,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,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,2214,6,110,6,6,9,792487,239],N=function(t,e){void 0===e&&(e={}),this.label=t,this.keyword=e.keyword,this.beforeExpr=!!e.beforeExpr,this.startsExpr=!!e.startsExpr,this.isLoop=!!e.isLoop,this.isAssign=!!e.isAssign,this.prefix=!!e.prefix,this.postfix=!!e.postfix,this.binop=e.binop||null,this.updateContext=null},P={beforeExpr:!0},C={startsExpr:!0},F={},R={num:new N("num",C),regexp:new N("regexp",C),string:new N("string",C),name:new N("name",C),eof:new N("eof"),bracketL:new N("[",{beforeExpr:!0,startsExpr:!0}),bracketR:new N("]"),braceL:new N("{",{beforeExpr:!0,startsExpr:!0}),braceR:new N("}"),parenL:new N("(",{beforeExpr:!0,startsExpr:!0}),parenR:new N(")"),comma:new N(",",P),semi:new N(";",P),colon:new N(":",P),dot:new N("."),question:new N("?",P),arrow:new N("=>",P),template:new N("template"),invalidTemplate:new N("invalidTemplate"),ellipsis:new N("...",P),backQuote:new N("`",C),dollarBraceL:new N("${",{beforeExpr:!0,startsExpr:!0}),eq:new N("=",{beforeExpr:!0,isAssign:!0}),assign:new N("_=",{beforeExpr:!0,isAssign:!0}),incDec:new N("++/--",{prefix:!0,postfix:!0,startsExpr:!0}),prefix:new N("prefix",{beforeExpr:!0,prefix:!0,startsExpr:!0}),logicalOR:i("||",1),logicalAND:i("&&",2),bitwiseOR:i("|",3),bitwiseXOR:i("^",4),bitwiseAND:i("&",5),equality:i("==/!=",6),relational:i(">",7),bitShift:i("<>>",8),plusMin:new N("+/-",{beforeExpr:!0,binop:9,prefix:!0,startsExpr:!0}),modulo:i("%",10),star:i("*",10),slash:i("/",10),starstar:new N("**",{beforeExpr:!0}),_break:s("break"),_case:s("case",P),_catch:s("catch"),_continue:s("continue"),_debugger:s("debugger"),_default:s("default",P),_do:s("do",{isLoop:!0,beforeExpr:!0}),_else:s("else",P),_finally:s("finally"),_for:s("for",{isLoop:!0}),_function:s("function",C),_if:s("if"),_return:s("return",P),_switch:s("switch"),_throw:s("throw",P),_try:s("try"),_var:s("var"),_const:s("const"),_while:s("while",{isLoop:!0}),_with:s("with"),_new:s("new",{beforeExpr:!0,startsExpr:!0}),_this:s("this",C),_super:s("super",C),_class:s("class",C),_extends:s("extends",P),_export:s("export"),_import:s("import"),_null:s("null",C),_true:s("true",C),_false:s("false",C),_in:s("in",{beforeExpr:!0,binop:7}),_instanceof:s("instanceof",{beforeExpr:!0,binop:7}),_typeof:s("typeof",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_void:s("void",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_delete:s("delete",{beforeExpr:!0,prefix:!0,startsExpr:!0})},L=/\r\n?|\n|\u2028|\u2029/,I=new RegExp(L.source,"g"),D=/[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/,G=/(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g,M=Object.prototype,U=M.hasOwnProperty,j=M.toString,B=Array.isArray||function(t){return"[object Array]"===j.call(t)},V=function(t,e){this.line=t,this.column=e};V.prototype.offset=function(t){return new V(this.line,this.column+t)};var K=function(t,e,n){this.start=e,this.end=n,null!==t.sourceFile&&(this.source=t.sourceFile)},z={ecmaVersion:7,sourceType:"script",onInsertedSemicolon:null,onTrailingComma:null,allowReserved:null,allowReturnOutsideFunction:!1,allowImportExportEverywhere:!1,allowHashBang:!1,locations:!1,onToken:null,onComment:null,ranges:!1,program:null,sourceFile:null,directSourceFile:null,preserveParens:!1,plugins:{}},W={},X=function(t,e,n){this.options=t=h(t),this.sourceFile=t.sourceFile,this.keywords=p(S[t.ecmaVersion>=6?6:5]);var r="";if(!t.allowReserved){for(var i=t.ecmaVersion;!(r=x[i]);i--);"module"==t.sourceType&&(r+=" await")}this.reservedWords=p(r);var s=(r?r+" ":"")+x.strict;this.reservedWordsStrict=p(s),this.reservedWordsStrictBind=p(s+" "+x.strictBind),this.input=String(e),this.containsEsc=!1,this.loadPlugins(t.plugins),n?(this.pos=n,this.lineStart=this.input.lastIndexOf("\n",n-1)+1,this.curLine=this.input.slice(0,this.lineStart).split(L).length):(this.pos=this.lineStart=0,this.curLine=1),this.type=R.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"===t.sourceType,this.strict=this.inModule||this.strictDirective(this.pos),this.potentialArrowAt=-1,this.inFunction=this.inGenerator=this.inAsync=!1,this.yieldPos=this.awaitPos=0,this.labels=[],0===this.pos&&t.allowHashBang&&"#!"===this.input.slice(0,2)&&this.skipLineComment(2),this.scopeStack=[],this.enterFunctionScope()};X.prototype.isKeyword=function(t){return this.keywords.test(t)},X.prototype.isReservedWord=function(t){return this.reservedWords.test(t)},X.prototype.extend=function(t,e){this[t]=e(this[t])},X.prototype.loadPlugins=function(t){var e=this;for(var n in t){var r=W[n];if(!r)throw new Error("Plugin '"+n+"' not found");r(e,t[n])}},X.prototype.parse=function(){var t=this.options.program||this.startNode();return this.nextToken(),this.parseTopLevel(t)};var q=X.prototype,Y=/^(?:'((?:[^']|\.)*)'|"((?:[^"]|\.)*)"|;)/;q.strictDirective=function(t){for(var e=this;;){G.lastIndex=t,t+=G.exec(e.input)[0].length;var n=Y.exec(e.input.slice(t));if(!n)return!1;if("use strict"==(n[1]||n[2]))return!0;t+=n[0].length}},q.eat=function(t){return this.type===t&&(this.next(),!0)},q.isContextual=function(t){return this.type===R.name&&this.value===t},q.eatContextual=function(t){return this.value===t&&this.eat(R.name)},q.expectContextual=function(t){this.eatContextual(t)||this.unexpected()},q.canInsertSemicolon=function(){return this.type===R.eof||this.type===R.braceR||L.test(this.input.slice(this.lastTokEnd,this.start))},q.insertSemicolon=function(){if(this.canInsertSemicolon())return this.options.onInsertedSemicolon&&this.options.onInsertedSemicolon(this.lastTokEnd,this.lastTokEndLoc),!0},q.semicolon=function(){this.eat(R.semi)||this.insertSemicolon()||this.unexpected()},q.afterTrailingComma=function(t,e){if(this.type==t)return this.options.onTrailingComma&&this.options.onTrailingComma(this.lastTokStart,this.lastTokStartLoc),e||this.next(),!0},q.expect=function(t){this.eat(t)||this.unexpected()},q.unexpected=function(t){this.raise(null!=t?t:this.start,"Unexpected token")},q.checkPatternErrors=function(t,e){if(t){t.trailingComma>-1&&this.raiseRecoverable(t.trailingComma,"Comma is not permitted after the rest element");var n=e?t.parenthesizedAssign:t.parenthesizedBind;n>-1&&this.raiseRecoverable(n,"Parenthesized pattern")}},q.checkExpressionErrors=function(t,e){var n=t?t.shorthandAssign:-1;return e?void(n>-1&&this.raise(n,"Shorthand property assignments are valid only in destructuring patterns")):n>=0},q.checkYieldAwaitInDefaultParams=function(){this.yieldPos&&(!this.awaitPos||this.yieldPos=6&&(t.sourceType=this.options.sourceType),this.finishNode(t,"Program")};var H={kind:"loop"},Z={kind:"switch"};J.isLet=function(){if(this.type!==R.name||this.options.ecmaVersion<6||"let"!=this.value)return!1;G.lastIndex=this.pos;var t=G.exec(this.input),e=this.pos+t[0].length,i=this.input.charCodeAt(e);if(91===i||123==i)return!0;if(n(i,!0)){for(var s=e+1;r(this.input.charCodeAt(s),!0);)++s;var a=this.input.slice(e,s);if(!this.isKeyword(a))return!0}return!1},J.isAsyncFunction=function(){if(this.type!==R.name||this.options.ecmaVersion<8||"async"!=this.value)return!1;G.lastIndex=this.pos;var t=G.exec(this.input),e=this.pos+t[0].length;return!(L.test(this.input.slice(this.pos,e))||"function"!==this.input.slice(e,e+8)||e+8!=this.input.length&&r(this.input.charAt(e+8)))},J.parseStatement=function(t,e,n){var r,i=this.type,s=this.startNode();switch(this.isLet()&&(i=R._var,r="let"),i){case R._break:case R._continue:return this.parseBreakContinueStatement(s,i.keyword);case R._debugger:return this.parseDebuggerStatement(s);case R._do:return this.parseDoStatement(s);case R._for:return this.parseForStatement(s);case R._function:return!t&&this.options.ecmaVersion>=6&&this.unexpected(),this.parseFunctionStatement(s,!1);case R._class:return t||this.unexpected(),this.parseClass(s,!0);case R._if:return this.parseIfStatement(s);case R._return:return this.parseReturnStatement(s);case R._switch:return this.parseSwitchStatement(s);case R._throw:return this.parseThrowStatement(s);case R._try:return this.parseTryStatement(s);case R._const:case R._var:return r=r||this.value,t||"var"==r||this.unexpected(),this.parseVarStatement(s,r);case R._while:return this.parseWhileStatement(s);case R._with:return this.parseWithStatement(s);case R.braceL:return this.parseBlock();case R.semi:return this.parseEmptyStatement(s);case R._export:case R._import:return this.options.allowImportExportEverywhere||(e||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'")),i===R._import?this.parseImport(s):this.parseExport(s,n);default:if(this.isAsyncFunction()&&t)return this.next(),this.parseFunctionStatement(s,!0);var a=this.value,o=this.parseExpression();return i===R.name&&"Identifier"===o.type&&this.eat(R.colon)?this.parseLabeledStatement(s,a,o):this.parseExpressionStatement(s,o)}},J.parseBreakContinueStatement=function(t,e){var n=this,r="break"==e;this.next(),this.eat(R.semi)||this.insertSemicolon()?t.label=null:this.type!==R.name?this.unexpected():(t.label=this.parseIdent(),this.semicolon());for(var i=0;i=6?this.eat(R.semi):this.semicolon(),this.finishNode(t,"DoWhileStatement")},J.parseForStatement=function(t){if(this.next(),this.labels.push(H),this.enterLexicalScope(),this.expect(R.parenL),this.type===R.semi)return this.parseFor(t,null);var e=this.isLet();if(this.type===R._var||this.type===R._const||e){var n=this.startNode(),r=e?"let":this.value;return this.next(),this.parseVar(n,!0,r),this.finishNode(n,"VariableDeclaration"),!(this.type===R._in||this.options.ecmaVersion>=6&&this.isContextual("of"))||1!==n.declarations.length||"var"!==r&&n.declarations[0].init?this.parseFor(t,n):this.parseForIn(t,n)}var i=new c,s=this.parseExpression(!0,i);return this.type===R._in||this.options.ecmaVersion>=6&&this.isContextual("of")?(this.toAssignable(s),this.checkLVal(s),this.checkPatternErrors(i,!0),this.parseForIn(t,s)):(this.checkExpressionErrors(i,!0),this.parseFor(t,s))},J.parseFunctionStatement=function(t,e){return this.next(),this.parseFunction(t,!0,!1,e)},J.isFunction=function(){return this.type===R._function||this.isAsyncFunction()},J.parseIfStatement=function(t){return this.next(),t.test=this.parseParenExpression(),t.consequent=this.parseStatement(!this.strict&&this.isFunction()),t.alternate=this.eat(R._else)?this.parseStatement(!this.strict&&this.isFunction()):null,this.finishNode(t,"IfStatement")},J.parseReturnStatement=function(t){return this.inFunction||this.options.allowReturnOutsideFunction||this.raise(this.start,"'return' outside of function"),this.next(),this.eat(R.semi)||this.insertSemicolon()?t.argument=null:(t.argument=this.parseExpression(),this.semicolon()),this.finishNode(t,"ReturnStatement")},J.parseSwitchStatement=function(t){var e=this;this.next(),t.discriminant=this.parseParenExpression(),t.cases=[],this.expect(R.braceL),this.labels.push(Z),this.enterLexicalScope();for(var n,r=!1;this.type!=R.braceR;)if(e.type===R._case||e.type===R._default){var i=e.type===R._case;n&&e.finishNode(n,"SwitchCase"),t.cases.push(n=e.startNode()),n.consequent=[],e.next(),i?n.test=e.parseExpression():(r&&e.raiseRecoverable(e.lastTokStart,"Multiple default clauses"),r=!0,n.test=null),e.expect(R.colon)}else n||e.unexpected(),n.consequent.push(e.parseStatement(!0));return this.exitLexicalScope(),n&&this.finishNode(n,"SwitchCase"),this.next(),this.labels.pop(),this.finishNode(t,"SwitchStatement")},J.parseThrowStatement=function(t){return this.next(),L.test(this.input.slice(this.lastTokEnd,this.start))&&this.raise(this.lastTokEnd,"Illegal newline after throw"),t.argument=this.parseExpression(),this.semicolon(),this.finishNode(t,"ThrowStatement")};var $=[];J.parseTryStatement=function(t){if(this.next(),t.block=this.parseBlock(),t.handler=null,this.type===R._catch){var e=this.startNode();this.next(),this.expect(R.parenL),e.param=this.parseBindingAtom(),this.enterLexicalScope(),this.checkLVal(e.param,"let"),this.expect(R.parenR),e.body=this.parseBlock(!1),this.exitLexicalScope(),t.handler=this.finishNode(e,"CatchClause")}return t.finalizer=this.eat(R._finally)?this.parseBlock():null,t.handler||t.finalizer||this.raise(t.start,"Missing catch or finally clause"),this.finishNode(t,"TryStatement")},J.parseVarStatement=function(t,e){return this.next(),this.parseVar(t,!1,e),this.semicolon(),this.finishNode(t,"VariableDeclaration")},J.parseWhileStatement=function(t){return this.next(),t.test=this.parseParenExpression(),this.labels.push(H),t.body=this.parseStatement(!1),this.labels.pop(),this.finishNode(t,"WhileStatement")},J.parseWithStatement=function(t){return this.strict&&this.raise(this.start,"'with' in strict mode"),this.next(),t.object=this.parseParenExpression(),t.body=this.parseStatement(!1),this.finishNode(t,"WithStatement")},J.parseEmptyStatement=function(t){return this.next(),this.finishNode(t,"EmptyStatement")},J.parseLabeledStatement=function(t,e,n){for(var r=this,i=0,s=r.labels;i=0;u--){var h=r.labels[u];if(h.statementStart!=t.start)break;h.statementStart=r.start,h.kind=o}return this.labels.push({name:e,kind:o,statementStart:this.start}),t.body=this.parseStatement(!0),("ClassDeclaration"==t.body.type||"VariableDeclaration"==t.body.type&&"var"!=t.body.kind||"FunctionDeclaration"==t.body.type&&(this.strict||t.body.generator))&&this.raiseRecoverable(t.body.start,"Invalid labeled declaration"),this.labels.pop(),t.label=n,this.finishNode(t,"LabeledStatement")},J.parseExpressionStatement=function(t,e){return t.expression=e,this.semicolon(),this.finishNode(t,"ExpressionStatement")},J.parseBlock=function(t){var e=this;void 0===t&&(t=!0);var n=this.startNode();for(n.body=[],this.expect(R.braceL),t&&this.enterLexicalScope();!this.eat(R.braceR);){var r=e.parseStatement(!0);n.body.push(r)}return t&&this.exitLexicalScope(),this.finishNode(n,"BlockStatement")},J.parseFor=function(t,e){return t.init=e,this.expect(R.semi),t.test=this.type===R.semi?null:this.parseExpression(),this.expect(R.semi),t.update=this.type===R.parenR?null:this.parseExpression(),this.expect(R.parenR),this.exitLexicalScope(),t.body=this.parseStatement(!1),this.labels.pop(),this.finishNode(t,"ForStatement")},J.parseForIn=function(t,e){var n=this.type===R._in?"ForInStatement":"ForOfStatement";return this.next(),t.left=e,t.right=this.parseExpression(),this.expect(R.parenR),this.exitLexicalScope(),t.body=this.parseStatement(!1),this.labels.pop(),this.finishNode(t,n)},J.parseVar=function(t,e,n){var r=this;for(t.declarations=[],t.kind=n;;){var i=r.startNode();if(r.parseVarId(i,n),r.eat(R.eq)?i.init=r.parseMaybeAssign(e):"const"!==n||r.type===R._in||r.options.ecmaVersion>=6&&r.isContextual("of")?"Identifier"==i.id.type||e&&(r.type===R._in||r.isContextual("of"))?i.init=null:r.raise(r.lastTokEnd,"Complex binding patterns require an initialization value"):r.unexpected(),t.declarations.push(r.finishNode(i,"VariableDeclarator")),!r.eat(R.comma))break}return t},J.parseVarId=function(t,e){t.id=this.parseBindingAtom(e),this.checkLVal(t.id,e,!1)},J.parseFunction=function(t,e,n,r){this.initFunction(t),this.options.ecmaVersion>=6&&!r&&(t.generator=this.eat(R.star)),this.options.ecmaVersion>=8&&(t.async=!!r),e&&(t.id="nullableID"===e&&this.type!=R.name?null:this.parseIdent(),t.id&&this.checkLVal(t.id,"var"));var i=this.inGenerator,s=this.inAsync,a=this.yieldPos,o=this.awaitPos,u=this.inFunction;return this.inGenerator=t.generator,this.inAsync=t.async,this.yieldPos=0,this.awaitPos=0,this.inFunction=!0,this.enterFunctionScope(),e||(t.id=this.type==R.name?this.parseIdent():null),this.parseFunctionParams(t),this.parseFunctionBody(t,n),this.inGenerator=i,this.inAsync=s,this.yieldPos=a,this.awaitPos=o,this.inFunction=u,this.finishNode(t,e?"FunctionDeclaration":"FunctionExpression")},J.parseFunctionParams=function(t){this.expect(R.parenL),t.params=this.parseBindingList(R.parenR,!1,this.options.ecmaVersion>=8),this.checkYieldAwaitInDefaultParams()},J.parseClass=function(t,e){var n=this;this.next(),this.parseClassId(t,e),this.parseClassSuper(t);var r=this.startNode(),i=!1;for(r.body=[],this.expect(R.braceL);!this.eat(R.braceR);)if(!n.eat(R.semi)){var s=n.startNode(),a=n.eat(R.star),o=!1,u=n.type===R.name&&"static"===n.value;n.parsePropertyName(s),s["static"]=u&&n.type!==R.parenL,s["static"]&&(a&&n.unexpected(),a=n.eat(R.star),n.parsePropertyName(s)),n.options.ecmaVersion>=8&&!a&&!s.computed&&"Identifier"===s.key.type&&"async"===s.key.name&&n.type!==R.parenL&&!n.canInsertSemicolon()&&(o=!0,n.parsePropertyName(s)),s.kind="method";var h=!1;if(!s.computed){var l=s.key;a||o||"Identifier"!==l.type||n.type===R.parenL||"get"!==l.name&&"set"!==l.name||(h=!0,s.kind=l.name,l=n.parsePropertyName(s)),!s["static"]&&("Identifier"===l.type&&"constructor"===l.name||"Literal"===l.type&&"constructor"===l.value)&&(i&&n.raise(l.start,"Duplicate constructor in the same class"),h&&n.raise(l.start,"Constructor can't have get/set modifier"),a&&n.raise(l.start,"Constructor can't be a generator"),o&&n.raise(l.start,"Constructor can't be an async method"),s.kind="constructor",i=!0)}if(n.parseClassMethod(r,s,a,o),h){var p="get"===s.kind?0:1;if(s.value.params.length!==p){var c=s.value.start;"get"===s.kind?n.raiseRecoverable(c,"getter should have no params"):n.raiseRecoverable(c,"setter should have exactly one param")}else"set"===s.kind&&"RestElement"===s.value.params[0].type&&n.raiseRecoverable(s.value.params[0].start,"Setter cannot use rest params")}}return t.body=this.finishNode(r,"ClassBody"),this.finishNode(t,e?"ClassDeclaration":"ClassExpression")},J.parseClassMethod=function(t,e,n,r){e.value=this.parseMethod(n,r),t.body.push(this.finishNode(e,"MethodDefinition"))},J.parseClassId=function(t,e){t.id=this.type===R.name?this.parseIdent():e===!0?this.unexpected():null},J.parseClassSuper=function(t){t.superClass=this.eat(R._extends)?this.parseExprSubscripts():null},J.parseExport=function(t,e){var n=this;if(this.next(),this.eat(R.star))return this.expectContextual("from"),t.source=this.type===R.string?this.parseExprAtom():this.unexpected(),this.semicolon(),this.finishNode(t,"ExportAllDeclaration");if(this.eat(R._default)){this.checkExport(e,"default",this.lastTokStart);var r;if(this.type===R._function||(r=this.isAsyncFunction())){var i=this.startNode();this.next(),r&&this.next(),t.declaration=this.parseFunction(i,"nullableID",!1,r)}else if(this.type===R._class){var s=this.startNode();t.declaration=this.parseClass(s,"nullableID")}else t.declaration=this.parseMaybeAssign(),this.semicolon();return this.finishNode(t,"ExportDefaultDeclaration")}if(this.shouldParseExportStatement())t.declaration=this.parseStatement(!0),"VariableDeclaration"===t.declaration.type?this.checkVariableExport(e,t.declaration.declarations):this.checkExport(e,t.declaration.id.name,t.declaration.id.start),t.specifiers=[],t.source=null;else{if(t.declaration=null,t.specifiers=this.parseExportSpecifiers(e),this.eatContextual("from"))t.source=this.type===R.string?this.parseExprAtom():this.unexpected();else{for(var a=0,o=t.specifiers;a=6&&t)switch(t.type){case"Identifier":this.inAsync&&"await"===t.name&&this.raise(t.start,"Can not use 'await' as identifier inside an async function");break;case"ObjectPattern":case"ArrayPattern":break;case"ObjectExpression":t.type="ObjectPattern";for(var r=0,i=t.properties;r=6&&(t.computed||t.method||t.shorthand))){var n,r=t.key;switch(r.type){case"Identifier":n=r.name;break;case"Literal":n=String(r.value);break;default:return}var i=t.kind;if(this.options.ecmaVersion>=6)return void("__proto__"===n&&"init"===i&&(e.proto&&this.raiseRecoverable(r.start,"Redefinition of __proto__ property"),e.proto=!0));n="$"+n;var s=e[n];if(s){var a;a="init"===i?this.strict&&s.init||s.get||s.set:s.init||s[i],a&&this.raiseRecoverable(r.start,"Redefinition of property")}else s=e[n]={init:!1,get:!1,set:!1};s[i]=!0}},tt.parseExpression=function(t,e){var n=this,r=this.start,i=this.startLoc,s=this.parseMaybeAssign(t,e);if(this.type===R.comma){var a=this.startNodeAt(r,i);for(a.expressions=[s];this.eat(R.comma);)a.expressions.push(n.parseMaybeAssign(t,e));return this.finishNode(a,"SequenceExpression")}return s},tt.parseMaybeAssign=function(t,e,n){if(this.inGenerator&&this.isContextual("yield"))return this.parseYield();var r=!1,i=-1,s=-1;e?(i=e.parenthesizedAssign,s=e.trailingComma,e.parenthesizedAssign=e.trailingComma=-1):(e=new c,r=!0);var a=this.start,o=this.startLoc;this.type!=R.parenL&&this.type!=R.name||(this.potentialArrowAt=this.start);var u=this.parseMaybeConditional(t,e);if(n&&(u=n.call(this,u,a,o)),this.type.isAssign){this.checkPatternErrors(e,!0),r||c.call(e);var h=this.startNodeAt(a,o);return h.operator=this.value,h.left=this.type===R.eq?this.toAssignable(u):u,e.shorthandAssign=-1,this.checkLVal(u),this.next(),h.right=this.parseMaybeAssign(t),this.finishNode(h,"AssignmentExpression")}return r&&this.checkExpressionErrors(e,!0),i>-1&&(e.parenthesizedAssign=i),s>-1&&(e.trailingComma=s),u},tt.parseMaybeConditional=function(t,e){var n=this.start,r=this.startLoc,i=this.parseExprOps(t,e);if(this.checkExpressionErrors(e))return i;if(this.eat(R.question)){
-var s=this.startNodeAt(n,r);return s.test=i,s.consequent=this.parseMaybeAssign(),this.expect(R.colon),s.alternate=this.parseMaybeAssign(t),this.finishNode(s,"ConditionalExpression")}return i},tt.parseExprOps=function(t,e){var n=this.start,r=this.startLoc,i=this.parseMaybeUnary(e,!1);return this.checkExpressionErrors(e)?i:i.start==n&&"ArrowFunctionExpression"===i.type?i:this.parseExprOp(i,n,r,-1,t)},tt.parseExprOp=function(t,e,n,r,i){var s=this.type.binop;if(null!=s&&(!i||this.type!==R._in)&&s>r){var a=this.type===R.logicalOR||this.type===R.logicalAND,o=this.value;this.next();var u=this.start,h=this.startLoc,l=this.parseExprOp(this.parseMaybeUnary(null,!1),u,h,s,i),p=this.buildBinary(e,n,t,l,o,a);return this.parseExprOp(p,e,n,r,i)}return t},tt.buildBinary=function(t,e,n,r,i,s){var a=this.startNodeAt(t,e);return a.left=n,a.operator=i,a.right=r,this.finishNode(a,s?"LogicalExpression":"BinaryExpression")},tt.parseMaybeUnary=function(t,e){var n,r=this,i=this.start,s=this.startLoc;if(this.inAsync&&this.isContextual("await"))n=this.parseAwait(t),e=!0;else if(this.type.prefix){var a=this.startNode(),o=this.type===R.incDec;a.operator=this.value,a.prefix=!0,this.next(),a.argument=this.parseMaybeUnary(null,!0),this.checkExpressionErrors(t,!0),o?this.checkLVal(a.argument):this.strict&&"delete"===a.operator&&"Identifier"===a.argument.type?this.raiseRecoverable(a.start,"Deleting local variable in strict mode"):e=!0,n=this.finishNode(a,o?"UpdateExpression":"UnaryExpression")}else{if(n=this.parseExprSubscripts(t),this.checkExpressionErrors(t))return n;for(;this.type.postfix&&!this.canInsertSemicolon();){var u=r.startNodeAt(i,s);u.operator=r.value,u.prefix=!1,u.argument=n,r.checkLVal(n),r.next(),n=r.finishNode(u,"UpdateExpression")}}return!e&&this.eat(R.starstar)?this.buildBinary(i,s,n,this.parseMaybeUnary(null,!1),"**",!1):n},tt.parseExprSubscripts=function(t){var e=this.start,n=this.startLoc,r=this.parseExprAtom(t),i="ArrowFunctionExpression"===r.type&&")"!==this.input.slice(this.lastTokStart,this.lastTokEnd);if(this.checkExpressionErrors(t)||i)return r;var s=this.parseSubscripts(r,e,n);return t&&"MemberExpression"===s.type&&(t.parenthesizedAssign>=s.start&&(t.parenthesizedAssign=-1),t.parenthesizedBind>=s.start&&(t.parenthesizedBind=-1)),s},tt.parseSubscripts=function(t,e,n,r){for(var i=this,s=this.options.ecmaVersion>=8&&"Identifier"===t.type&&"async"===t.name&&this.lastTokEnd==t.end&&!this.canInsertSemicolon(),a=void 0;;)if((a=i.eat(R.bracketL))||i.eat(R.dot)){var o=i.startNodeAt(e,n);o.object=t,o.property=a?i.parseExpression():i.parseIdent(!0),o.computed=!!a,a&&i.expect(R.bracketR),t=i.finishNode(o,"MemberExpression")}else if(!r&&i.eat(R.parenL)){var u=new c,h=i.yieldPos,l=i.awaitPos;i.yieldPos=0,i.awaitPos=0;var p=i.parseExprList(R.parenR,i.options.ecmaVersion>=8,!1,u);if(s&&!i.canInsertSemicolon()&&i.eat(R.arrow))return i.checkPatternErrors(u,!1),i.checkYieldAwaitInDefaultParams(),i.yieldPos=h,i.awaitPos=l,i.parseArrowExpression(i.startNodeAt(e,n),p,!0);i.checkExpressionErrors(u,!0),i.yieldPos=h||i.yieldPos,i.awaitPos=l||i.awaitPos;var f=i.startNodeAt(e,n);f.callee=t,f.arguments=p,t=i.finishNode(f,"CallExpression")}else{if(i.type!==R.backQuote)return t;var d=i.startNodeAt(e,n);d.tag=t,d.quasi=i.parseTemplate({isTagged:!0}),t=i.finishNode(d,"TaggedTemplateExpression")}},tt.parseExprAtom=function(t){var e,n=this.potentialArrowAt==this.start;switch(this.type){case R._super:this.inFunction||this.raise(this.start,"'super' outside of function or class");case R._this:var r=this.type===R._this?"ThisExpression":"Super";return e=this.startNode(),this.next(),this.finishNode(e,r);case R.name:var i=this.start,s=this.startLoc,a=this.parseIdent(this.type!==R.name);if(this.options.ecmaVersion>=8&&"async"===a.name&&!this.canInsertSemicolon()&&this.eat(R._function))return this.parseFunction(this.startNodeAt(i,s),!1,!1,!0);if(n&&!this.canInsertSemicolon()){if(this.eat(R.arrow))return this.parseArrowExpression(this.startNodeAt(i,s),[a],!1);if(this.options.ecmaVersion>=8&&"async"===a.name&&this.type===R.name)return a=this.parseIdent(),!this.canInsertSemicolon()&&this.eat(R.arrow)||this.unexpected(),this.parseArrowExpression(this.startNodeAt(i,s),[a],!0)}return a;case R.regexp:var o=this.value;return e=this.parseLiteral(o.value),e.regex={pattern:o.pattern,flags:o.flags},e;case R.num:case R.string:return this.parseLiteral(this.value);case R._null:case R._true:case R._false:return e=this.startNode(),e.value=this.type===R._null?null:this.type===R._true,e.raw=this.type.keyword,this.next(),this.finishNode(e,"Literal");case R.parenL:var u=this.start,h=this.parseParenAndDistinguishExpression(n);return t&&(t.parenthesizedAssign<0&&!this.isSimpleAssignTarget(h)&&(t.parenthesizedAssign=u),t.parenthesizedBind<0&&(t.parenthesizedBind=u)),h;case R.bracketL:return e=this.startNode(),this.next(),e.elements=this.parseExprList(R.bracketR,!0,!0,t),this.finishNode(e,"ArrayExpression");case R.braceL:return this.parseObj(!1,t);case R._function:return e=this.startNode(),this.next(),this.parseFunction(e,!1);case R._class:return this.parseClass(this.startNode(),!1);case R._new:return this.parseNew();case R.backQuote:return this.parseTemplate();default:this.unexpected()}},tt.parseLiteral=function(t){var e=this.startNode();return e.value=t,e.raw=this.input.slice(this.start,this.end),this.next(),this.finishNode(e,"Literal")},tt.parseParenExpression=function(){this.expect(R.parenL);var t=this.parseExpression();return this.expect(R.parenR),t},tt.parseParenAndDistinguishExpression=function(t){var e,n=this,r=this.start,i=this.startLoc,s=this.options.ecmaVersion>=8;if(this.options.ecmaVersion>=6){this.next();var a,o,u=this.start,h=this.startLoc,l=[],p=!0,f=!1,d=new c,m=this.yieldPos,g=this.awaitPos;for(this.yieldPos=0,this.awaitPos=0;this.type!==R.parenR;){if(p?p=!1:n.expect(R.comma),s&&n.afterTrailingComma(R.parenR,!0)){f=!0;break}if(n.type===R.ellipsis){a=n.start,l.push(n.parseParenItem(n.parseRestBinding())),n.type===R.comma&&n.raise(n.start,"Comma is not permitted after the rest element");break}n.type!==R.parenL||o||(o=n.start),l.push(n.parseMaybeAssign(!1,d,n.parseParenItem))}var y=this.start,v=this.startLoc;if(this.expect(R.parenR),t&&!this.canInsertSemicolon()&&this.eat(R.arrow))return this.checkPatternErrors(d,!1),this.checkYieldAwaitInDefaultParams(),o&&this.unexpected(o),this.yieldPos=m,this.awaitPos=g,this.parseParenArrowList(r,i,l);l.length&&!f||this.unexpected(this.lastTokStart),a&&this.unexpected(a),this.checkExpressionErrors(d,!0),this.yieldPos=m||this.yieldPos,this.awaitPos=g||this.awaitPos,l.length>1?(e=this.startNodeAt(u,h),e.expressions=l,this.finishNodeAt(e,"SequenceExpression",y,v)):e=l[0]}else e=this.parseParenExpression();if(this.options.preserveParens){var b=this.startNodeAt(r,i);return b.expression=e,this.finishNode(b,"ParenthesizedExpression")}return e},tt.parseParenItem=function(t){return t},tt.parseParenArrowList=function(t,e,n){return this.parseArrowExpression(this.startNodeAt(t,e),n)};var et=[];tt.parseNew=function(){var t=this.startNode(),e=this.parseIdent(!0);if(this.options.ecmaVersion>=6&&this.eat(R.dot))return t.meta=e,t.property=this.parseIdent(!0),"target"!==t.property.name&&this.raiseRecoverable(t.property.start,"The only valid meta property for new is new.target"),this.inFunction||this.raiseRecoverable(t.start,"new.target can only be used in functions"),this.finishNode(t,"MetaProperty");var n=this.start,r=this.startLoc;return t.callee=this.parseSubscripts(this.parseExprAtom(),n,r,!0),this.eat(R.parenL)?t.arguments=this.parseExprList(R.parenR,this.options.ecmaVersion>=8,!1):t.arguments=et,this.finishNode(t,"NewExpression")},tt.parseTemplateElement=function(t){var e=t.isTagged,n=this.startNode();return this.type===R.invalidTemplate?(e||this.raiseRecoverable(this.start,"Bad escape sequence in untagged template literal"),n.value={raw:this.value,cooked:null}):n.value={raw:this.input.slice(this.start,this.end).replace(/\r\n?/g,"\n"),cooked:this.value},this.next(),n.tail=this.type===R.backQuote,this.finishNode(n,"TemplateElement")},tt.parseTemplate=function(t){var e=this;void 0===t&&(t={});var n=t.isTagged;void 0===n&&(n=!1);var r=this.startNode();this.next(),r.expressions=[];var i=this.parseTemplateElement({isTagged:n});for(r.quasis=[i];!i.tail;)e.expect(R.dollarBraceL),r.expressions.push(e.parseExpression()),e.expect(R.braceR),r.quasis.push(i=e.parseTemplateElement({isTagged:n}));return this.next(),this.finishNode(r,"TemplateLiteral")},tt.isAsyncProp=function(t){return!(t.computed||"Identifier"!==t.key.type||"async"!==t.key.name||this.type!==R.name&&this.type!==R.num&&this.type!==R.string&&this.type!==R.bracketL||L.test(this.input.slice(this.lastTokEnd,this.start)))},tt.parseObj=function(t,e){var n=this,r=this.startNode(),i=!0,s={};for(r.properties=[],this.next();!this.eat(R.braceR);){if(i)i=!1;else if(n.expect(R.comma),n.afterTrailingComma(R.braceR))break;var a=n.startNode(),o=void 0,u=void 0,h=void 0,l=void 0;n.options.ecmaVersion>=6&&(a.method=!1,a.shorthand=!1,(t||e)&&(h=n.start,l=n.startLoc),t||(o=n.eat(R.star))),n.parsePropertyName(a),!t&&n.options.ecmaVersion>=8&&!o&&n.isAsyncProp(a)?(u=!0,n.parsePropertyName(a,e)):u=!1,n.parsePropertyValue(a,t,o,u,h,l,e),n.checkPropClash(a,s),r.properties.push(n.finishNode(a,"Property"))}return this.finishNode(r,t?"ObjectPattern":"ObjectExpression")},tt.parsePropertyValue=function(t,e,n,r,i,s,a){if((n||r)&&this.type===R.colon&&this.unexpected(),this.eat(R.colon))t.value=e?this.parseMaybeDefault(this.start,this.startLoc):this.parseMaybeAssign(!1,a),t.kind="init";else if(this.options.ecmaVersion>=6&&this.type===R.parenL)e&&this.unexpected(),t.kind="init",t.method=!0,t.value=this.parseMethod(n,r);else if(this.options.ecmaVersion>=5&&!t.computed&&"Identifier"===t.key.type&&("get"===t.key.name||"set"===t.key.name)&&this.type!=R.comma&&this.type!=R.braceR){(n||r||e)&&this.unexpected(),t.kind=t.key.name,this.parsePropertyName(t),t.value=this.parseMethod(!1);var o="get"===t.kind?0:1;if(t.value.params.length!==o){var u=t.value.start;"get"===t.kind?this.raiseRecoverable(u,"getter should have no params"):this.raiseRecoverable(u,"setter should have exactly one param")}else"set"===t.kind&&"RestElement"===t.value.params[0].type&&this.raiseRecoverable(t.value.params[0].start,"Setter cannot use rest params")}else this.options.ecmaVersion>=6&&!t.computed&&"Identifier"===t.key.type?(this.checkUnreserved(t.key),t.kind="init",e?t.value=this.parseMaybeDefault(i,s,t.key):this.type===R.eq&&a?(a.shorthandAssign<0&&(a.shorthandAssign=this.start),t.value=this.parseMaybeDefault(i,s,t.key)):t.value=t.key,t.shorthand=!0):this.unexpected()},tt.parsePropertyName=function(t){if(this.options.ecmaVersion>=6){if(this.eat(R.bracketL))return t.computed=!0,t.key=this.parseMaybeAssign(),this.expect(R.bracketR),t.key;t.computed=!1}return t.key=this.type===R.num||this.type===R.string?this.parseExprAtom():this.parseIdent(!0)},tt.initFunction=function(t){t.id=null,this.options.ecmaVersion>=6&&(t.generator=!1,t.expression=!1),this.options.ecmaVersion>=8&&(t.async=!1)},tt.parseMethod=function(t,e){var n=this.startNode(),r=this.inGenerator,i=this.inAsync,s=this.yieldPos,a=this.awaitPos,o=this.inFunction;return this.initFunction(n),this.options.ecmaVersion>=6&&(n.generator=t),this.options.ecmaVersion>=8&&(n.async=!!e),this.inGenerator=n.generator,this.inAsync=n.async,this.yieldPos=0,this.awaitPos=0,this.inFunction=!0,this.enterFunctionScope(),this.expect(R.parenL),n.params=this.parseBindingList(R.parenR,!1,this.options.ecmaVersion>=8),this.checkYieldAwaitInDefaultParams(),this.parseFunctionBody(n,!1),this.inGenerator=r,this.inAsync=i,this.yieldPos=s,this.awaitPos=a,this.inFunction=o,this.finishNode(n,"FunctionExpression")},tt.parseArrowExpression=function(t,e,n){var r=this.inGenerator,i=this.inAsync,s=this.yieldPos,a=this.awaitPos,o=this.inFunction;return this.enterFunctionScope(),this.initFunction(t),this.options.ecmaVersion>=8&&(t.async=!!n),this.inGenerator=!1,this.inAsync=t.async,this.yieldPos=0,this.awaitPos=0,this.inFunction=!0,t.params=this.toAssignableList(e,!0),this.parseFunctionBody(t,!0),this.inGenerator=r,this.inAsync=i,this.yieldPos=s,this.awaitPos=a,this.inFunction=o,this.finishNode(t,"ArrowFunctionExpression")},tt.parseFunctionBody=function(t,e){var n=e&&this.type!==R.braceL,r=this.strict,i=!1;if(n)t.body=this.parseMaybeAssign(),t.expression=!0,this.checkParams(t,!1);else{var s=this.options.ecmaVersion>=7&&!this.isSimpleParamList(t.params);r&&!s||(i=this.strictDirective(this.end),i&&s&&this.raiseRecoverable(t.start,"Illegal 'use strict' directive in function with non-simple parameter list"));var a=this.labels;this.labels=[],i&&(this.strict=!0),this.checkParams(t,!r&&!i&&!e&&this.isSimpleParamList(t.params)),t.body=this.parseBlock(!1),t.expression=!1,this.labels=a}this.exitFunctionScope(),this.strict&&t.id&&this.checkLVal(t.id,"none"),this.strict=r},tt.isSimpleParamList=function(t){for(var e=0,n=t;e0;)e[n]=arguments[n+1];for(var r=0,i=e;r=1;e--){var n=t.context[e];if("function"===n.token)return n.generator}return!1},ht.updateContext=function(t){var e,n=this.type;n.keyword&&t==R.dot?this.exprAllowed=!1:(e=n.updateContext)?e.call(this,t):this.exprAllowed=n.beforeExpr},R.parenR.updateContext=R.braceR.updateContext=function(){if(1==this.context.length)return void(this.exprAllowed=!0);var t=this.context.pop();t===ut.b_stat&&"function"===this.curContext().token&&(t=this.context.pop()),this.exprAllowed=!t.isExpr},R.braceL.updateContext=function(t){this.context.push(this.braceIsBlock(t)?ut.b_stat:ut.b_expr),this.exprAllowed=!0},R.dollarBraceL.updateContext=function(){this.context.push(ut.b_tmpl),this.exprAllowed=!0},R.parenL.updateContext=function(t){var e=t===R._if||t===R._for||t===R._with||t===R._while;this.context.push(e?ut.p_stat:ut.p_expr),this.exprAllowed=!0},R.incDec.updateContext=function(){},R._function.updateContext=R._class.updateContext=function(t){t.beforeExpr&&t!==R.semi&&t!==R._else&&(t!==R.colon&&t!==R.braceL||this.curContext()!==ut.b_stat)?this.context.push(ut.f_expr):this.context.push(ut.f_stat),this.exprAllowed=!1},R.backQuote.updateContext=function(){this.curContext()===ut.q_tmpl?this.context.pop():this.context.push(ut.q_tmpl),this.exprAllowed=!1},R.star.updateContext=function(t){if(t==R._function){var e=this.context.length-1;this.context[e]===ut.f_expr?this.context[e]=ut.f_expr_gen:this.context[e]=ut.f_gen}this.exprAllowed=!0},R.name.updateContext=function(t){var e=!1;this.options.ecmaVersion>=6&&("of"==this.value&&!this.exprAllowed||"yield"==this.value&&this.inGeneratorContext())&&(e=!0),this.exprAllowed=e};var lt=function(t){this.type=t.type,this.value=t.value,this.start=t.start,this.end=t.end,t.options.locations&&(this.loc=new K(t,t.startLoc,t.endLoc)),t.options.ranges&&(this.range=[t.start,t.end])},pt=X.prototype,ct="object"==typeof Packages&&"[object JavaPackage]"==Object.prototype.toString.call(Packages);pt.next=function(){this.options.onToken&&this.options.onToken(new lt(this)),this.lastTokEnd=this.end,this.lastTokStart=this.start,this.lastTokEndLoc=this.endLoc,this.lastTokStartLoc=this.startLoc,this.nextToken()},pt.getToken=function(){return this.next(),new lt(this)},"undefined"!=typeof Symbol&&(pt[Symbol.iterator]=function(){var t=this;return{next:function(){var e=t.getToken();return{done:e.type===R.eof,value:e}}}}),pt.curContext=function(){return this.context[this.context.length-1]},pt.nextToken=function(){var t=this.curContext();return t&&t.preserveSpace||this.skipSpace(),this.start=this.pos,this.options.locations&&(this.startLoc=this.curPosition()),this.pos>=this.input.length?this.finishToken(R.eof):t.override?t.override(this):void this.readToken(this.fullCharCodeAtPos())},pt.readToken=function(t){return n(t,this.options.ecmaVersion>=6)||92===t?this.readWord():this.getTokenFromCode(t)},pt.fullCharCodeAtPos=function(){var t=this.input.charCodeAt(this.pos);if(t<=55295||t>=57344)return t;var e=this.input.charCodeAt(this.pos+1);return(t<<10)+e-56613888},pt.skipBlockComment=function(){var t=this,e=this.options.onComment&&this.curPosition(),n=this.pos,r=this.input.indexOf("*/",this.pos+=2);if(r===-1&&this.raise(this.pos-2,"Unterminated comment"),this.pos=r+2,this.options.locations){I.lastIndex=n;for(var i;(i=I.exec(this.input))&&i.index8&&e<14||e>=5760&&D.test(String.fromCharCode(e))))break t;++t.pos}}},pt.finishToken=function(t,e){this.end=this.pos,this.options.locations&&(this.endLoc=this.curPosition());var n=this.type;this.type=t,this.value=e,this.updateContext(n)},pt.readToken_dot=function(){var t=this.input.charCodeAt(this.pos+1);if(t>=48&&t<=57)return this.readNumber(!0);var e=this.input.charCodeAt(this.pos+2);return this.options.ecmaVersion>=6&&46===t&&46===e?(this.pos+=3,this.finishToken(R.ellipsis)):(++this.pos,this.finishToken(R.dot))},pt.readToken_slash=function(){var t=this.input.charCodeAt(this.pos+1);return this.exprAllowed?(++this.pos,this.readRegexp()):61===t?this.finishOp(R.assign,2):this.finishOp(R.slash,1)},pt.readToken_mult_modulo_exp=function(t){var e=this.input.charCodeAt(this.pos+1),n=1,r=42===t?R.star:R.modulo;return this.options.ecmaVersion>=7&&42===e&&(++n,r=R.starstar,e=this.input.charCodeAt(this.pos+2)),61===e?this.finishOp(R.assign,n+1):this.finishOp(r,n)},pt.readToken_pipe_amp=function(t){var e=this.input.charCodeAt(this.pos+1);return e===t?this.finishOp(124===t?R.logicalOR:R.logicalAND,2):61===e?this.finishOp(R.assign,2):this.finishOp(124===t?R.bitwiseOR:R.bitwiseAND,1)},pt.readToken_caret=function(){var t=this.input.charCodeAt(this.pos+1);return 61===t?this.finishOp(R.assign,2):this.finishOp(R.bitwiseXOR,1)},pt.readToken_plus_min=function(t){var e=this.input.charCodeAt(this.pos+1);return e===t?45!=e||62!=this.input.charCodeAt(this.pos+2)||0!==this.lastTokEnd&&!L.test(this.input.slice(this.lastTokEnd,this.pos))?this.finishOp(R.incDec,2):(this.skipLineComment(3),this.skipSpace(),this.nextToken()):61===e?this.finishOp(R.assign,2):this.finishOp(R.plusMin,1)},pt.readToken_lt_gt=function(t){var e=this.input.charCodeAt(this.pos+1),n=1;return e===t?(n=62===t&&62===this.input.charCodeAt(this.pos+2)?3:2,61===this.input.charCodeAt(this.pos+n)?this.finishOp(R.assign,n+1):this.finishOp(R.bitShift,n)):33==e&&60==t&&45==this.input.charCodeAt(this.pos+2)&&45==this.input.charCodeAt(this.pos+3)?(this.inModule&&this.unexpected(),this.skipLineComment(4),this.skipSpace(),this.nextToken()):(61===e&&(n=2),this.finishOp(R.relational,n))},pt.readToken_eq_excl=function(t){var e=this.input.charCodeAt(this.pos+1);return 61===e?this.finishOp(R.equality,61===this.input.charCodeAt(this.pos+2)?3:2):61===t&&62===e&&this.options.ecmaVersion>=6?(this.pos+=2,this.finishToken(R.arrow)):this.finishOp(61===t?R.eq:R.prefix,1)},pt.getTokenFromCode=function(t){switch(t){case 46:return this.readToken_dot();case 40:return++this.pos,this.finishToken(R.parenL);case 41:return++this.pos,this.finishToken(R.parenR);case 59:return++this.pos,this.finishToken(R.semi);case 44:return++this.pos,this.finishToken(R.comma);case 91:return++this.pos,this.finishToken(R.bracketL);case 93:return++this.pos,this.finishToken(R.bracketR);case 123:return++this.pos,this.finishToken(R.braceL);case 125:return++this.pos,this.finishToken(R.braceR);case 58:return++this.pos,this.finishToken(R.colon);case 63:return++this.pos,this.finishToken(R.question);case 96:if(this.options.ecmaVersion<6)break;return++this.pos,this.finishToken(R.backQuote);case 48:var e=this.input.charCodeAt(this.pos+1);if(120===e||88===e)return this.readRadixNumber(16);if(this.options.ecmaVersion>=6){if(111===e||79===e)return this.readRadixNumber(8);if(98===e||66===e)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(t);case 47:return this.readToken_slash();case 37:case 42:return this.readToken_mult_modulo_exp(t);case 124:case 38:return this.readToken_pipe_amp(t);case 94:return this.readToken_caret();case 43:case 45:return this.readToken_plus_min(t);case 60:case 62:return this.readToken_lt_gt(t);case 61:case 33:return this.readToken_eq_excl(t);case 126:return this.finishOp(R.prefix,1)}this.raise(this.pos,"Unexpected character '"+m(t)+"'")},pt.finishOp=function(t,e){var n=this.input.slice(this.pos,this.pos+e);return this.pos+=e,this.finishToken(t,n)};var ft=!!d("","u");pt.readRegexp=function(){for(var t,e,n=this,r=this.pos;;){n.pos>=n.input.length&&n.raise(r,"Unterminated regular expression");var i=n.input.charAt(n.pos);if(L.test(i)&&n.raise(r,"Unterminated regular expression"),t)t=!1;else{if("["===i)e=!0;else if("]"===i&&e)e=!1;else if("/"===i&&!e)break;t="\\"===i}++n.pos}var s=this.input.slice(r,this.pos);++this.pos;var a=this.readWord1(),o=s,u="";if(a){var h=/^[gim]*$/;this.options.ecmaVersion>=6&&(h=/^[gimuy]*$/),h.test(a)||this.raise(r,"Invalid regular expression flag"),a.indexOf("u")>=0&&(ft?u="u":(o=o.replace(/\\u\{([0-9a-fA-F]+)\}/g,function(t,e,i){return e=Number("0x"+e),e>1114111&&n.raise(r+i+3,"Code point out of bounds"),"x"}),o=o.replace(/\\u([a-fA-F0-9]{4})|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,"x"),u=u.replace("u","")))}var l=null;return ct||(d(o,u,r,this),l=d(s,a)),this.finishToken(R.regexp,{pattern:s,flags:a,value:l})},pt.readInt=function(t,e){for(var n=this,r=this.pos,i=0,s=0,a=null==e?1/0:e;s=97?o-97+10:o>=65?o-65+10:o>=48&&o<=57?o-48:1/0,u>=t)break;++n.pos,i=i*t+u}return this.pos===r||null!=e&&this.pos-r!==e?null:i},pt.readRadixNumber=function(t){this.pos+=2;var e=this.readInt(t);return null==e&&this.raise(this.start+2,"Expected number in radix "+t),n(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number"),this.finishToken(R.num,e)},pt.readNumber=function(t){var e=this.pos,r=!1,i=48===this.input.charCodeAt(this.pos);t||null!==this.readInt(10)||this.raise(e,"Invalid number"),i&&this.pos==e+1&&(i=!1);var s=this.input.charCodeAt(this.pos);46!==s||i||(++this.pos,this.readInt(10),r=!0,s=this.input.charCodeAt(this.pos)),69!==s&&101!==s||i||(s=this.input.charCodeAt(++this.pos),43!==s&&45!==s||++this.pos,null===this.readInt(10)&&this.raise(e,"Invalid number"),r=!0),n(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number");var a,o=this.input.slice(e,this.pos);return r?a=parseFloat(o):i&&1!==o.length?this.strict?this.raise(e,"Invalid number"):a=/[89]/.test(o)?parseInt(o,10):parseInt(o,8):a=parseInt(o,10),this.finishToken(R.num,a)},pt.readCodePoint=function(){var t,e=this.input.charCodeAt(this.pos);if(123===e){this.options.ecmaVersion<6&&this.unexpected();var n=++this.pos;t=this.readHexChar(this.input.indexOf("}",this.pos)-this.pos),++this.pos,t>1114111&&this.invalidStringToken(n,"Code point out of bounds")}else t=this.readHexChar(4);return t},pt.readString=function(t){for(var e=this,n="",r=++this.pos;;){e.pos>=e.input.length&&e.raise(e.start,"Unterminated string constant");var i=e.input.charCodeAt(e.pos);if(i===t)break;92===i?(n+=e.input.slice(r,e.pos),n+=e.readEscapedChar(!1),r=e.pos):(a(i)&&e.raise(e.start,"Unterminated string constant"),++e.pos)}return n+=this.input.slice(r,this.pos++),this.finishToken(R.string,n)};var dt={};pt.tryReadTemplateToken=function(){this.inTemplateElement=!0;try{this.readTmplToken()}catch(t){if(t!==dt)throw t;this.readInvalidTemplateToken()}this.inTemplateElement=!1},pt.invalidStringToken=function(t,e){if(this.inTemplateElement&&this.options.ecmaVersion>=9)throw dt;this.raise(t,e)},pt.readTmplToken=function(){for(var t=this,e="",n=this.pos;;){t.pos>=t.input.length&&t.raise(t.start,"Unterminated template");var r=t.input.charCodeAt(t.pos);if(96===r||36===r&&123===t.input.charCodeAt(t.pos+1))return t.pos!==t.start||t.type!==R.template&&t.type!==R.invalidTemplate?(e+=t.input.slice(n,t.pos),t.finishToken(R.template,e)):36===r?(t.pos+=2,t.finishToken(R.dollarBraceL)):(++t.pos,t.finishToken(R.backQuote));if(92===r)e+=t.input.slice(n,t.pos),e+=t.readEscapedChar(!0),n=t.pos;else if(a(r)){switch(e+=t.input.slice(n,t.pos),++t.pos,r){case 13:10===t.input.charCodeAt(t.pos)&&++t.pos;case 10:e+="\n";break;default:e+=String.fromCharCode(r)}t.options.locations&&(++t.curLine,t.lineStart=t.pos),n=t.pos}else++t.pos}},pt.readInvalidTemplateToken=function(){for(var t=this;this.pos=48&&e<=55){var n=this.input.substr(this.pos-1,3).match(/^[0-7]+/)[0],r=parseInt(n,8);return r>255&&(n=n.slice(0,-1),r=parseInt(n,8)),"0"!==n&&(this.strict||t)&&this.invalidStringToken(this.pos-2,"Octal literal in strict mode"),this.pos+=n.length-1,String.fromCharCode(r)}return String.fromCharCode(e)}},pt.readHexChar=function(t){var e=this.pos,n=this.readInt(16,t);return null===n&&this.invalidStringToken(e,"Bad character escape sequence"),n},pt.readWord1=function(){var t=this;this.containsEsc=!1;for(var e="",i=!0,s=this.pos,a=this.options.ecmaVersion>=6;this.posThis handles all the raw state, converted state, etc. Of a single function.
- *
- * @prop functionName - {String} Name of the function
- * @prop jsFunction - {Function} The JS Function the node represents
- * @prop jsFunctionString - {String} jsFunction.toString()
- * @prop paramNames - {String[]} Parameter names of the function
- * @prop paramTypes - {String[]} Shader land parameters type assumption
- * @prop isRootKernel - {Boolean} Special indicator, for kernel function
- * @prop webglFunctionString - {String} webgl converted function string
- * @prop openglFunctionString - {String} opengl converted function string
- * @prop calledFunctions - {String[]} List of all the functions called
- * @prop initVariables - {String[]} List of variables initialized in the function
- * @prop readVariables - {String[]} List of variables read operations occur
- * @prop writeVariables - {String[]} List of variables write operations occur
- *
- */
-module.exports = function (_BaseFunctionNode) {
- _inherits(CPUFunctionNode, _BaseFunctionNode);
-
- function CPUFunctionNode() {
- _classCallCheck(this, CPUFunctionNode);
-
- return _possibleConstructorReturn(this, (CPUFunctionNode.__proto__ || Object.getPrototypeOf(CPUFunctionNode)).apply(this, arguments));
- }
-
- _createClass(CPUFunctionNode, [{
- key: 'generate',
- value: function generate() {
- if (this.debug) {
- console.log(this);
- }
- this.functionStringArray = this.astGeneric(this.getJsAST(), [], this);
- this.functionString = this.functionStringArray.join('').trim();
- return this.functionString;
- }
-
- /**
- * @memberOf CPUFunctionNode#
- * @function
- * @name getFunctionPrototypeString
- *
- * @desc Returns the converted JS function
- *
- * @returns {String} function string, result is cached under this.getFunctionPrototypeString
- *
- */
-
- }, {
- key: 'getFunctionPrototypeString',
- value: function getFunctionPrototypeString() {
- if (this.webGlFunctionPrototypeString) {
- return this.webGlFunctionPrototypeString;
- }
- return this.webGlFunctionPrototypeString = this.generate();
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astGeneric
- *
- * @desc Parses the abstract syntax tree for generically to its respective function
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {String} the prased openclgl string array
- */
-
- }, {
- key: 'astGeneric',
- value: function astGeneric(ast, retArr, funcParam) {
- if (ast === null) {
- throw this.astErrorOutput('NULL ast', ast, funcParam);
- } else {
- if (Array.isArray(ast)) {
- for (var i = 0; i < ast.length; i++) {
- this.astGeneric(ast[i], retArr, funcParam);
- }
- return retArr;
- }
-
- switch (ast.type) {
- case 'FunctionDeclaration':
- return this.astFunctionDeclaration(ast, retArr, funcParam);
- case 'FunctionExpression':
- return this.astFunctionExpression(ast, retArr, funcParam);
- case 'ReturnStatement':
- return this.astReturnStatement(ast, retArr, funcParam);
- case 'Literal':
- return this.astLiteral(ast, retArr, funcParam);
- case 'BinaryExpression':
- return this.astBinaryExpression(ast, retArr, funcParam);
- case 'Identifier':
- return this.astIdentifierExpression(ast, retArr, funcParam);
- case 'AssignmentExpression':
- return this.astAssignmentExpression(ast, retArr, funcParam);
- case 'ExpressionStatement':
- return this.astExpressionStatement(ast, retArr, funcParam);
- case 'EmptyStatement':
- return this.astEmptyStatement(ast, retArr, funcParam);
- case 'BlockStatement':
- return this.astBlockStatement(ast, retArr, funcParam);
- case 'IfStatement':
- return this.astIfStatement(ast, retArr, funcParam);
- case 'BreakStatement':
- return this.astBreakStatement(ast, retArr, funcParam);
- case 'ContinueStatement':
- return this.astContinueStatement(ast, retArr, funcParam);
- case 'ForStatement':
- return this.astForStatement(ast, retArr, funcParam);
- case 'WhileStatement':
- return this.astWhileStatement(ast, retArr, funcParam);
- case 'VariableDeclaration':
- return this.astVariableDeclaration(ast, retArr, funcParam);
- case 'VariableDeclarator':
- return this.astVariableDeclarator(ast, retArr, funcParam);
- case 'ThisExpression':
- return this.astThisExpression(ast, retArr, funcParam);
- case 'SequenceExpression':
- return this.astSequenceExpression(ast, retArr, funcParam);
- case 'UnaryExpression':
- return this.astUnaryExpression(ast, retArr, funcParam);
- case 'UpdateExpression':
- return this.astUpdateExpression(ast, retArr, funcParam);
- case 'LogicalExpression':
- return this.astLogicalExpression(ast, retArr, funcParam);
- case 'MemberExpression':
- return this.astMemberExpression(ast, retArr, funcParam);
- case 'CallExpression':
- return this.astCallExpression(ast, retArr, funcParam);
- case 'ArrayExpression':
- return this.astArrayExpression(ast, retArr, funcParam);
- case 'DebuggerStatement':
- return this.astDebuggerStatement(ast, retArr, funcParam);
- }
-
- throw this.astErrorOutput('Unknown ast type : ' + ast.type, ast, funcParam);
- }
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astFunctionDeclaration
- *
- * @desc Parses the abstract syntax tree for to its *named function declaration*
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astFunctionDeclaration',
- value: function astFunctionDeclaration(ast, retArr, funcParam) {
- if (this.addFunction) {
- this.addFunction(null, utils.getAstString(this.jsFunctionString, ast));
- }
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astFunctionPrototype
- * @static
- *
- * @desc Parses the abstract syntax tree for to its *named function prototype*
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astFunctionExpression',
-
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astFunctionExpression
- *
- * @desc Parses the abstract syntax tree for to its *named function*
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- value: function astFunctionExpression(ast, retArr, funcParam) {
-
- // Setup function return type and name
- if (!funcParam.isRootKernel) {
- retArr.push('function');
- funcParam.kernalAst = ast;
- retArr.push(' ');
- retArr.push(funcParam.functionName);
- retArr.push('(');
-
- // Arguments handling
- for (var i = 0; i < funcParam.paramNames.length; ++i) {
- var paramName = funcParam.paramNames[i];
-
- if (i > 0) {
- retArr.push(', ');
- }
-
- retArr.push(' ');
- retArr.push('user_');
- retArr.push(paramName);
- }
-
- // Function opening
- retArr.push(') {\n');
- }
-
- // Body statement iteration
- for (var _i = 0; _i < ast.body.body.length; ++_i) {
- this.astGeneric(ast.body.body[_i], retArr, funcParam);
- retArr.push('\n');
- }
-
- if (!funcParam.isRootKernel) {
- // Function closing
- retArr.push('}\n');
- }
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astReturnStatement
- *
- * @desc Parses the abstract syntax tree for to *return* statement
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Object} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astReturnStatement',
- value: function astReturnStatement(ast, retArr, funcParam) {
- if (funcParam.isRootKernel) {
- retArr.push('kernelResult = ');
- this.astGeneric(ast.argument, retArr, funcParam);
- retArr.push(';');
- } else if (funcParam.isSubKernel) {
- retArr.push(funcParam.functionName + 'Result = ');
- this.astGeneric(ast.argument, retArr, funcParam);
- retArr.push(';');
- retArr.push('return ' + funcParam.functionName + 'Result;');
- } else {
- retArr.push('return ');
- this.astGeneric(ast.argument, retArr, funcParam);
- retArr.push(';');
- }
-
- //throw this.astErrorOutput(
- // 'Non main function return, is not supported : '+funcParam.currentFunctionNamespace,
- // ast, funcParam
- //);
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astLiteral
- *
- * @desc Parses the abstract syntax tree for *literal value*
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astLiteral',
- value: function astLiteral(ast, retArr, funcParam) {
-
- // Reject non numeric literals
- if (isNaN(ast.value)) {
- throw this.astErrorOutput('Non-numeric literal not supported : ' + ast.value, ast, funcParam);
- }
-
- retArr.push(ast.value);
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astBinaryExpression
- *
- * @desc Parses the abstract syntax tree for *binary* expression
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astBinaryExpression',
- value: function astBinaryExpression(ast, retArr, funcParam) {
- retArr.push('(');
- this.astGeneric(ast.left, retArr, funcParam);
- retArr.push(ast.operator);
- this.astGeneric(ast.right, retArr, funcParam);
- retArr.push(')');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astIdentifierExpression
- *
- * @desc Parses the abstract syntax tree for *identifier* expression
- *
- * @param {Object} idtNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astIdentifierExpression',
- value: function astIdentifierExpression(idtNode, retArr, funcParam) {
- if (idtNode.type !== 'Identifier') {
- throw this.astErrorOutput('IdentifierExpression - not an Identifier', ast, funcParam);
- }
-
- switch (idtNode.name) {
- case 'gpu_threadX':
- retArr.push('threadId.x');
- break;
- case 'gpu_threadY':
- retArr.push('threadId.y');
- break;
- case 'gpu_threadZ':
- retArr.push('threadId.z');
- break;
- case 'gpu_outputX':
- retArr.push('uOutputDim.x');
- break;
- case 'gpu_outputY':
- retArr.push('uOutputDim.y');
- break;
- case 'gpu_outputZ':
- retArr.push('uOutputDim.z');
- break;
- default:
- if (this.constants && this.constants.hasOwnProperty(idtNode.name)) {
- retArr.push('constants_' + idtNode.name);
- } else {
- var userParamName = funcParam.getUserParamName(idtNode.name);
- if (userParamName !== null) {
- retArr.push('user_' + userParamName);
- } else {
- retArr.push('user_' + idtNode.name);
- }
- }
- }
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astForStatement
- *
- * @desc Parses the abstract syntax tree forfor *for-loop* expression
- *
- * @param {Object} forNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {String} the prased openclgl string
- */
-
- }, {
- key: 'astForStatement',
- value: function astForStatement(forNode, retArr, funcParam) {
- if (forNode.type !== 'ForStatement') {
- throw this.astErrorOutput('Invalid for statment', ast, funcParam);
- }
-
- if (forNode.test && forNode.test.type === 'BinaryExpression') {
- if ((forNode.test.right.type === 'Identifier' || forNode.test.right.type === 'Literal') && forNode.test.operator === '<' && this.isIdentifierConstant(forNode.test.right.name) === false) {
-
- if (!this.loopMaxIterations) {
- console.warn('Warning: loopMaxIterations is not set! Using default of 1000 which may result in unintended behavior.');
- console.warn('Set loopMaxIterations or use a for loop of fixed length to silence this message.');
- }
-
- retArr.push('for (');
- this.astGeneric(forNode.init, retArr, funcParam);
- if (retArr[retArr.length - 1] !== ';') {
- retArr.push(';');
- }
- this.astGeneric(forNode.test.left, retArr, funcParam);
- retArr.push(forNode.test.operator);
- retArr.push('LOOP_MAX');
- retArr.push(';');
- this.astGeneric(forNode.update, retArr, funcParam);
- retArr.push(')');
-
- retArr.push('{\n');
- retArr.push('if (');
- this.astGeneric(forNode.test.left, retArr, funcParam);
- retArr.push(forNode.test.operator);
- this.astGeneric(forNode.test.right, retArr, funcParam);
- retArr.push(') {\n');
- if (forNode.body.type === 'BlockStatement') {
- for (var i = 0; i < forNode.body.body.length; i++) {
- this.astGeneric(forNode.body.body[i], retArr, funcParam);
- }
- } else {
- this.astGeneric(forNode.body, retArr, funcParam);
- }
- retArr.push('} else {\n');
- retArr.push('break;\n');
- retArr.push('}\n');
- retArr.push('}\n');
-
- return retArr;
- } else if (forNode.init.declarations) {
- var declarations = JSON.parse(JSON.stringify(forNode.init.declarations));
- var updateArgument = forNode.update.argument;
- if (!Array.isArray(declarations) || declarations.length < 1) {
- console.log(this.jsFunctionString);
- throw new Error('Error: Incompatible for loop declaration');
- }
-
- if (declarations.length > 1) {
- var initArgument = null;
- for (var _i2 = 0; _i2 < declarations.length; _i2++) {
- var declaration = declarations[_i2];
- if (declaration.id.name === updateArgument.name) {
- initArgument = declaration;
- declarations.splice(_i2, 1);
- } else {
- retArr.push('var ');
- this.astGeneric(declaration, retArr, funcParam);
- retArr.push(';');
- }
- }
-
- retArr.push('for (let ');
- this.astGeneric(initArgument, retArr, funcParam);
- retArr.push(';');
- } else {
- retArr.push('for (');
- this.astGeneric(forNode.init, retArr, funcParam);
- }
-
- this.astGeneric(forNode.test, retArr, funcParam);
- retArr.push(';');
- this.astGeneric(forNode.update, retArr, funcParam);
- retArr.push(')');
- this.astGeneric(forNode.body, retArr, funcParam);
- return retArr;
- }
- }
-
- throw this.astErrorOutput('Invalid for statement', forNode, funcParam);
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astWhileStatement
- *
- * @desc Parses the abstract syntax tree for *while* loop
- *
- *
- * @param {Object} whileNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {String} the parsed openclgl string
- */
-
- }, {
- key: 'astWhileStatement',
- value: function astWhileStatement(whileNode, retArr, funcParam) {
- if (whileNode.type !== 'WhileStatement') {
- throw this.astErrorOutput('Invalid while statment', ast, funcParam);
- }
-
- retArr.push('for (let i = 0; i < LOOP_MAX; i++) {');
- retArr.push('if (');
- this.astGeneric(whileNode.test, retArr, funcParam);
- retArr.push(') {\n');
- this.astGeneric(whileNode.body, retArr, funcParam);
- retArr.push('} else {\n');
- retArr.push('break;\n');
- retArr.push('}\n');
- retArr.push('}\n');
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astAssignmentExpression
- *
- * @desc Parses the abstract syntax tree for *Assignment* Expression
- *
- * @param {Object} assNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astAssignmentExpression',
- value: function astAssignmentExpression(assNode, retArr, funcParam) {
- this.astGeneric(assNode.left, retArr, funcParam);
- retArr.push(assNode.operator);
- this.astGeneric(assNode.right, retArr, funcParam);
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astEmptyStatement
- *
- * @desc Parses the abstract syntax tree for an *Empty* Statement
- *
- * @param {Object} eNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astEmptyStatement',
- value: function astEmptyStatement(eNode, retArr, funcParam) {
- //retArr.push(';\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astBlockStatement
- *
- * @desc Parses the abstract syntax tree for *Block* statement
- *
- * @param {Object} bnode - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astBlockStatement',
- value: function astBlockStatement(bNode, retArr, funcParam) {
- retArr.push('{\n');
- for (var i = 0; i < bNode.body.length; i++) {
- this.astGeneric(bNode.body[i], retArr, funcParam);
- }
- retArr.push('}\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astExpressionStatement
- *
- * @desc Parses the abstract syntax tree for *generic expression* statement
- *
- * @param {Object} esNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astExpressionStatement',
- value: function astExpressionStatement(esNode, retArr, funcParam) {
- this.astGeneric(esNode.expression, retArr, funcParam);
- retArr.push(';\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astVariableDeclaration
- *
- * @desc Parses the abstract syntax tree for *Variable Declaration*
- *
- * @param {Object} vardecNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astVariableDeclaration',
- value: function astVariableDeclaration(vardecNode, retArr, funcParam) {
- retArr.push('var ');
- for (var i = 0; i < vardecNode.declarations.length; i++) {
- if (i > 0) {
- retArr.push(',');
- }
- this.astGeneric(vardecNode.declarations[i], retArr, funcParam);
- }
- retArr.push(';');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astVariableDeclarator
- *
- * @desc Parses the abstract syntax tree for *Variable Declarator*
- *
- * @param {Object} ivardecNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astVariableDeclarator',
- value: function astVariableDeclarator(ivardecNode, retArr, funcParam) {
- this.astGeneric(ivardecNode.id, retArr, funcParam);
- if (ivardecNode.init !== null) {
- retArr.push('=');
- this.astGeneric(ivardecNode.init, retArr, funcParam);
- }
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astIfStatement
- *
- * @desc Parses the abstract syntax tree for *If* Statement
- *
- * @param {Object} ifNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astIfStatement',
- value: function astIfStatement(ifNode, retArr, funcParam) {
- retArr.push('if (');
- this.astGeneric(ifNode.test, retArr, funcParam);
- retArr.push(')');
- if (ifNode.consequent.type === 'BlockStatement') {
- this.astGeneric(ifNode.consequent, retArr, funcParam);
- } else {
- retArr.push(' {\n');
- this.astGeneric(ifNode.consequent, retArr, funcParam);
- retArr.push('\n}\n');
- }
-
- if (ifNode.alternate) {
- retArr.push('else ');
- if (ifNode.alternate.type === 'BlockStatement') {
- this.astGeneric(ifNode.alternate, retArr, funcParam);
- } else {
- retArr.push(' {\n');
- this.astGeneric(ifNode.alternate, retArr, funcParam);
- retArr.push('\n}\n');
- }
- }
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astBreakStatement
- *
- * @desc Parses the abstract syntax tree for *Break* Statement
- *
- * @param {Object} brNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astBreakStatement',
- value: function astBreakStatement(brNode, retArr, funcParam) {
- retArr.push('break;\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astContinueStatement
- *
- * @desc Parses the abstract syntax tree for *Continue* Statement
- *
- * @param {Object} crNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astContinueStatement',
- value: function astContinueStatement(crNode, retArr, funcParam) {
- retArr.push('continue;\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astLogicalExpression
- *
- * @desc Parses the abstract syntax tree for *Logical* Expression
- *
- * @param {Object} logNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astLogicalExpression',
- value: function astLogicalExpression(logNode, retArr, funcParam) {
- retArr.push('(');
- this.astGeneric(logNode.left, retArr, funcParam);
- retArr.push(logNode.operator);
- this.astGeneric(logNode.right, retArr, funcParam);
- retArr.push(')');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astUpdateExpression
- *
- * @desc Parses the abstract syntax tree for *Update* Expression
- *
- * @param {Object} uNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astUpdateExpression',
- value: function astUpdateExpression(uNode, retArr, funcParam) {
- if (uNode.prefix) {
- retArr.push(uNode.operator);
- this.astGeneric(uNode.argument, retArr, funcParam);
- } else {
- this.astGeneric(uNode.argument, retArr, funcParam);
- retArr.push(uNode.operator);
- }
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astUnaryExpression
- *
- * @desc Parses the abstract syntax tree for *Unary* Expression
- *
- * @param {Object} uNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astUnaryExpression',
- value: function astUnaryExpression(uNode, retArr, funcParam) {
- if (uNode.prefix) {
- retArr.push(uNode.operator);
- this.astGeneric(uNode.argument, retArr, funcParam);
- } else {
- this.astGeneric(uNode.argument, retArr, funcParam);
- retArr.push(uNode.operator);
- }
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astThisExpression
- *
- * @desc Parses the abstract syntax tree for *This* expression
- *
- * @param {Object} tNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astThisExpression',
- value: function astThisExpression(tNode, retArr, funcParam) {
- retArr.push('_this');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astMemberExpression
- *
- * @desc Parses the abstract syntax tree for *Member* Expression
- *
- * @param {Object} mNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astMemberExpression',
- value: function astMemberExpression(mNode, retArr, funcParam) {
- if (mNode.computed) {
- if (mNode.object.type === 'Identifier') {
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push('[');
- this.astGeneric(mNode.property, retArr, funcParam);
- retArr.push(']');
- } else {
- this.astGeneric(mNode.object, retArr, funcParam);
- var last = retArr.pop();
- retArr.push('][');
- this.astGeneric(mNode.property, retArr, funcParam);
- retArr.push(last);
- }
- } else {
- var unrolled = this.astMemberExpressionUnroll(mNode);
- if (mNode.property.type === 'Identifier' && mNode.computed) {
- unrolled = 'user_' + unrolled;
- }
-
- // Its a reference to `this`, add '_' before
- if (unrolled.indexOf('this') === 0) {
- unrolled = '_' + unrolled;
- }
-
- switch (unrolled) {
- case '_this.output.x':
- retArr.push(this.output[0]);
- break;
- case '_this.output.y':
- retArr.push(this.output[1]);
- break;
- case '_this.output.z':
- retArr.push(this.output[2]);
- break;
- default:
- retArr.push(unrolled);
- }
- }
- return retArr;
- }
- }, {
- key: 'astSequenceExpression',
- value: function astSequenceExpression(sNode, retArr, funcParam) {
- for (var i = 0; i < sNode.expressions.length; i++) {
- if (i > 0) {
- retArr.push(',');
- }
- this.astGeneric(sNode.expressions, retArr, funcParam);
- }
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astCallExpression
- *
- * @desc Parses the abstract syntax tree for *call* expression
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astCallExpression',
- value: function astCallExpression(ast, retArr, funcParam) {
- if (ast.callee) {
- // Get the full function call, unrolled
- var funcName = this.astMemberExpressionUnroll(ast.callee);
-
- // Register the function into the called registry
- if (funcParam.calledFunctions.indexOf(funcName) < 0) {
- funcParam.calledFunctions.push(funcName);
- }
- if (!funcParam.hasOwnProperty('funcName')) {
- funcParam.calledFunctionsArguments[funcName] = [];
- }
-
- var functionArguments = [];
- funcParam.calledFunctionsArguments[funcName].push(functionArguments);
-
- // Call the function
- retArr.push(funcName);
-
- // Open arguments space
- retArr.push('(');
-
- // Add the vars
- for (var i = 0; i < ast.arguments.length; ++i) {
- var argument = ast.arguments[i];
- if (i > 0) {
- retArr.push(', ');
- }
- this.astGeneric(argument, retArr, funcParam);
- if (argument.type === 'Identifier') {
- var paramIndex = funcParam.paramNames.indexOf(argument.name);
- if (paramIndex === -1) {
- functionArguments.push(null);
- } else {
- functionArguments.push({
- name: argument.name,
- type: funcParam.paramTypes[paramIndex]
- });
- }
- } else {
- functionArguments.push(null);
- }
- }
-
- // Close arguments space
- retArr.push(')');
-
- return retArr;
- }
-
- // Failure, unknown expression
- throw this.astErrorOutput('Unknown CallExpression', ast, funcParam);
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astArrayExpression
- *
- * @desc Parses the abstract syntax tree for *Array* Expression
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astArrayExpression',
- value: function astArrayExpression(arrNode, retArr, funcParam) {
- var arrLen = arrNode.elements.length;
-
- retArr.push('new Float32Array(');
- for (var i = 0; i < arrLen; ++i) {
- if (i > 0) {
- retArr.push(', ');
- }
- var subNode = arrNode.elements[i];
- this.astGeneric(subNode, retArr, funcParam);
- }
- retArr.push(')');
-
- return retArr;
-
- // // Failure, unknown expression
- // throw this.astErrorOutput(
- // 'Unknown ArrayExpression',
- // arrNode, funcParam
- //);
- }
- }, {
- key: 'astDebuggerStatement',
- value: function astDebuggerStatement(arrNode, retArr, funcParam) {
- retArr.push('debugger;');
- return retArr;
- }
- }], [{
- key: 'astFunctionPrototype',
- value: function astFunctionPrototype(ast, retArr, funcParam) {
- // Setup function return type and name
- if (funcParam.isRootKernel || funcParam.isSubKernel) {
- return retArr;
- }
-
- retArr.push(funcParam.returnType);
- retArr.push(' ');
- retArr.push(funcParam.functionName);
- retArr.push('(');
-
- // Arguments handling
- for (var i = 0; i < funcParam.paramNames.length; ++i) {
- if (i > 0) {
- retArr.push(', ');
- }
-
- retArr.push(funcParam.paramTypes[i]);
- retArr.push(' ');
- retArr.push('user_');
- retArr.push(funcParam.paramNames[i]);
- }
-
- retArr.push(');\n');
-
- return retArr;
- }
- }]);
-
- return CPUFunctionNode;
-}(BaseFunctionNode);
\ No newline at end of file
diff --git a/dist/backend/cpu/kernel-string.js b/dist/backend/cpu/kernel-string.js
deleted file mode 100644
index 102cb5fe..00000000
--- a/dist/backend/cpu/kernel-string.js
+++ /dev/null
@@ -1,8 +0,0 @@
-'use strict';
-
-var utils = require('../../core/utils');
-var kernelRunShortcut = require('../kernel-run-shortcut');
-
-module.exports = function (cpuKernel, name) {
- return '() => {\n ' + kernelRunShortcut.toString() + ';\n const utils = {\n allPropertiesOf: function ' + utils.allPropertiesOf.toString() + ',\n clone: function ' + utils.clone.toString() + ',\n /*splitArray: function ' + utils.splitArray.toString() + ',\n getArgumentType: function ' + utils.getArgumentType.toString() + ',\n getOutput: function ' + utils.getOutput.toString() + ',\n dimToTexSize: function ' + utils.dimToTexSize.toString() + ',\n copyFlatten: function ' + utils.copyFlatten.toString() + ',\n flatten: function ' + utils.flatten.toString() + ',\n systemEndianness: \'' + utils.systemEndianness() + '\',\n initWebGl: function ' + utils.initWebGl.toString() + ',\n isArray: function ' + utils.isArray.toString() + '*/\n };\n class ' + (name || 'Kernel') + ' {\n constructor() { \n this.argumentsLength = 0;\n this._canvas = null;\n this._webGl = null;\n this.built = false;\n this.program = null;\n this.paramNames = ' + JSON.stringify(cpuKernel.paramNames) + ';\n this.paramTypes = ' + JSON.stringify(cpuKernel.paramTypes) + ';\n this.texSize = ' + JSON.stringify(cpuKernel.texSize) + ';\n this.output = ' + JSON.stringify(cpuKernel.output) + ';\n this._kernelString = `' + cpuKernel._kernelString + '`;\n this.output = ' + JSON.stringify(cpuKernel.output) + ';\n\t\t this.run = function() {\n this.run = null;\n this.build();\n return this.run.apply(this, arguments);\n }.bind(this);\n this.thread = {\n x: 0,\n y: 0,\n z: 0\n };\n }\n setCanvas(canvas) { this._canvas = canvas; return this; }\n setWebGl(webGl) { this._webGl = webGl; return this; }\n ' + cpuKernel.build.toString() + '\n run () { ' + cpuKernel.kernelString + ' }\n getKernelString() { return this._kernelString; }\n };\n return kernelRunShortcut(new Kernel());\n };';
-};
\ No newline at end of file
diff --git a/dist/backend/cpu/kernel.js b/dist/backend/cpu/kernel.js
deleted file mode 100644
index 255e186f..00000000
--- a/dist/backend/cpu/kernel.js
+++ /dev/null
@@ -1,340 +0,0 @@
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var KernelBase = require('../kernel-base');
-var utils = require('../../core/utils');
-var kernelString = require('./kernel-string');
-
-module.exports = function (_KernelBase) {
- _inherits(CPUKernel, _KernelBase);
-
- /**
- * @constructor CPUKernel
- *
- * @desc Kernel Implementation for CPU.
- *
- * Instantiates properties to the CPU Kernel.
- *
- * @extends KernelBase
- *
- * @prop {Object} thread - The thread dimensions, x, y and z
- * @prop {Object} output - The canvas dimensions
- * @prop {Object} functionBuilder - Function Builder instance bound to this Kernel
- * @prop {Function} run - Method to run the kernel
- *
- */
- function CPUKernel(fnString, settings) {
- _classCallCheck(this, CPUKernel);
-
- var _this = _possibleConstructorReturn(this, (CPUKernel.__proto__ || Object.getPrototypeOf(CPUKernel)).call(this, fnString, settings));
-
- _this._fnBody = utils.getFunctionBodyFromString(fnString);
- _this._fn = null;
- _this.run = null;
- _this._canvasCtx = null;
- _this._imageData = null;
- _this._colorData = null;
- _this._kernelString = null;
- _this.thread = {
- x: 0,
- y: 0,
- z: 0
- };
-
- _this.run = function () {
- this.run = null;
- this.build.apply(this, arguments);
- return this.run.apply(this, arguments);
- }.bind(_this);
- return _this;
- }
-
- /**
- * @memberOf CPUKernel#
- * @function
- * @name validateOptions
- *
- * @desc Validate options related to CPU Kernel, such as
- * dimensions size, and auto dimension support.
- *
- */
-
-
- _createClass(CPUKernel, [{
- key: 'validateOptions',
- value: function validateOptions() {
- if (!this.output || this.output.length === 0) {
- if (arguments.length !== 1) {
- throw 'Auto dimensions only supported for kernels with only one input';
- }
-
- var argType = utils.getArgumentType(arguments[0]);
- if (argType === 'Array') {
- this.output = utils.getDimensions(argType);
- } else if (argType === 'Texture') {
- this.output = arguments[0].output;
- } else {
- throw 'Auto dimensions not supported for input type: ' + argType;
- }
- }
- }
-
- /**
- * @memberOf CPUKernel#
- * @function
- * @name build
- *
- * @desc Builds the Kernel, by generating the kernel
- * string using thread dimensions, and arguments
- * supplied to the kernel.
- *
- * If the graphical flag is enabled, canvas is used.
- *
- */
-
- }, {
- key: 'build',
- value: function build() {
- this.setupParams(arguments);
- var threadDim = this.threadDim = utils.clone(this.output);
-
- while (threadDim.length < 3) {
- threadDim.push(1);
- }
-
- if (this.graphical) {
- var canvas = this.getCanvas();
- canvas.width = threadDim[0];
- canvas.height = threadDim[1];
- this._canvasCtx = canvas.getContext('2d');
- this._imageData = this._canvasCtx.createImageData(threadDim[0], threadDim[1]);
- this._colorData = new Uint8ClampedArray(threadDim[0] * threadDim[1] * 4);
- }
-
- var kernelString = this.getKernelString();
-
- if (this.debug) {
- console.log('Options:');
- console.dir(this);
- console.log('Function output:');
- console.log(kernelString);
- }
-
- this.kernelString = kernelString;
- this.run = new Function([], kernelString).bind(this)();
- }
- }, {
- key: 'color',
- value: function color(r, g, b, a) {
- if (typeof a === 'undefined') {
- a = 1;
- }
-
- r = Math.floor(r * 255);
- g = Math.floor(g * 255);
- b = Math.floor(b * 255);
- a = Math.floor(a * 255);
-
- var width = this.output[0];
- var height = this.output[1];
-
- var x = this.thread.x;
- var y = height - this.thread.y - 1;
-
- var index = x + y * width;
-
- this._colorData[index * 4 + 0] = r;
- this._colorData[index * 4 + 1] = g;
- this._colorData[index * 4 + 2] = b;
- this._colorData[index * 4 + 3] = a;
- }
-
- /**
- * @memberOf CPUKernel#
- * @function
- * @name getKernelString
- *
- * @desc Generates kernel string for this kernel program.
- *
- * If sub-kernels are supplied, they are also factored in.
- * This string can be saved by calling the `toString` method
- * and then can be reused later.
- *
- * @returns {String} result
- *
- */
-
- }, {
- key: 'getKernelString',
- value: function getKernelString() {
- var _this2 = this;
-
- if (this._kernelString !== null) return this._kernelString;
-
- var builder = this.functionBuilder;
-
- // Thread dim fix (to make compilable)
- var threadDim = this.threadDim || (this.threadDim = utils.clone(this.output));
- while (threadDim.length < 3) {
- threadDim.push(1);
- }
-
- builder.addKernel(this.fnString, {
- prototypeOnly: false,
- constants: this.constants,
- output: this.output,
- debug: this.debug,
- loopMaxIterations: this.loopMaxIterations
- }, this.paramNames, this.paramTypes);
-
- builder.addFunctions(this.functions, {
- constants: this.constants,
- output: this.output
- });
-
- if (this.subKernels !== null) {
- this.subKernelOutputTextures = [];
- this.subKernelOutputVariableNames = [];
- for (var i = 0; i < this.subKernels.length; i++) {
- var subKernel = this.subKernels[i];
- builder.addSubKernel(subKernel, {
- prototypeOnly: false,
- constants: this.constants,
- output: this.output,
- debug: this.debug,
- loopMaxIterations: this.loopMaxIterations
- });
- this.subKernelOutputVariableNames.push(subKernel.name + 'Result');
- }
- } else if (this.subKernelProperties !== null) {
- this.subKernelOutputVariableNames = [];
- var _i = 0;
- for (var p in this.subKernelProperties) {
- if (!this.subKernelProperties.hasOwnProperty(p)) continue;
- var _subKernel = this.subKernelProperties[p];
- builder.addSubKernel(_subKernel);
- this.subKernelOutputVariableNames.push(_subKernel.name + 'Result');
- _i++;
- }
- }
-
- var prototypes = builder.getPrototypes();
- var kernel = prototypes.shift();
- var kernelString = this._kernelString = '\n\t\tvar LOOP_MAX = ' + this._getLoopMaxString() + ';\n\t\tvar _this = this;\n ' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) {
- return ' var ' + name + ' = null;\n';
- }).join('')) + '\n return function (' + this.paramNames.map(function (paramName) {
- return 'user_' + paramName;
- }).join(', ') + ') {\n var ret = new Array(' + threadDim[2] + ');\n ' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) {
- return ' ' + name + 'Z = new Array(' + threadDim[2] + ');\n';
- }).join('')) + '\n for (this.thread.z = 0; this.thread.z < ' + threadDim[2] + '; this.thread.z++) {\n ret[this.thread.z] = new Array(' + threadDim[1] + ');\n ' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) {
- return ' ' + name + 'Z[this.thread.z] = new Array(' + threadDim[1] + ');\n';
- }).join('')) + '\n for (this.thread.y = 0; this.thread.y < ' + threadDim[1] + '; this.thread.y++) {\n ret[this.thread.z][this.thread.y] = new Array(' + threadDim[0] + ');\n ' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) {
- return ' ' + name + 'Z[this.thread.z][this.thread.y] = new Array(' + threadDim[0] + ');\n';
- }).join('')) + '\n for (this.thread.x = 0; this.thread.x < ' + threadDim[0] + '; this.thread.x++) {\n var kernelResult;\n ' + kernel + '\n ret[this.thread.z][this.thread.y][this.thread.x] = kernelResult;\n' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) {
- return ' ' + name + 'Z[this.thread.z][this.thread.y][this.thread.x] = ' + name + ';\n';
- }).join('')) + '\n }\n }\n }\n \n if (this.graphical) {\n this._imageData.data.set(this._colorData);\n this._canvasCtx.putImageData(this._imageData, 0, 0);\n return;\n }\n \n if (this.output.length === 1) {\n ret = ret[0][0];\n' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) {
- return ' ' + name + ' = ' + name + 'Z[0][0];\n';
- }).join('')) + '\n \n } else if (this.output.length === 2) {\n ret = ret[0];\n ' + (this.subKernelOutputVariableNames === null ? '' : this.subKernelOutputVariableNames.map(function (name) {
- return ' ' + name + ' = ' + name + 'Z[0];\n';
- }).join('')) + '\n }\n \n ' + (this.subKernelOutputVariableNames === null ? 'return ret;\n' : this.subKernels !== null ? 'var result = [\n ' + this.subKernelOutputVariableNames.map(function (name) {
- return '' + name;
- }).join(',\n') + '\n ];\n result.result = ret;\n return result;\n' : 'return {\n result: ret,\n ' + Object.keys(this.subKernelProperties).map(function (name, i) {
- return name + ': ' + _this2.subKernelOutputVariableNames[i];
- }).join(',\n') + '\n };') + '\n ' + (prototypes.length > 0 ? prototypes.join('\n') : '') + '\n }.bind(this);';
- return kernelString;
- }
-
- /**
- * @memberOf CPUKernel#
- * @function
- * @name toString
- *
- * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused.
- *
- */
-
- }, {
- key: 'toString',
- value: function toString() {
- return kernelString(this);
- }
-
- /**
- * @memberOf CPUKernel#
- * @function
- * @name precompileKernelObj
- *
- * @desc Precompile the kernel into a single object,
- * that can be used for building the execution kernel subsequently.
- *
- * @param {Array} argTypes - Array of argument types
- *
- * Return:
- * Compiled kernel {Object}
- *
- */
-
- }, {
- key: 'precompileKernelObj',
- value: function precompileKernelObj(argTypes) {
-
- var threadDim = this.threadDim || (this.threadDim = utils.clone(this.output));
-
- return {
- threadDim: threadDim
- };
- }
-
- /**
- * @memberOf CPUKernel
- * @function
- * @name compileKernel
- * @static
- *
- * @desc Takes a previously precompiled kernel object,
- * and complete compilation into a full kernel
- *
- * @returns {Function} Compiled kernel
- *
- */
-
- }, {
- key: '_getLoopMaxString',
-
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getLoopMaxString
- *
- * @desc Get the maximum loop size String.
- *
- * @returns {String} result
- *
- */
- value: function _getLoopMaxString() {
- return this.loopMaxIterations ? ' ' + parseInt(this.loopMaxIterations) + ';\n' : ' 1000;\n';
- }
- }], [{
- key: 'compileKernel',
- value: function compileKernel(precompileObj) {
-
- // Extract values from precompiled obj
- var threadDim = precompileObj.threadDim;
-
- // Normalize certain values : For actual build
- while (threadDim.length < 3) {
- threadDim.push(1);
- }
- }
- }]);
-
- return CPUKernel;
-}(KernelBase);
\ No newline at end of file
diff --git a/dist/backend/cpu/runner.js b/dist/backend/cpu/runner.js
deleted file mode 100644
index 7532e4c8..00000000
--- a/dist/backend/cpu/runner.js
+++ /dev/null
@@ -1,60 +0,0 @@
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var utils = require('../../core/utils');
-var RunnerBase = require('../runner-base');
-var CPUKernel = require('./kernel');
-var CPUFunctionBuilder = require('./function-builder');
-
-module.exports = function (_RunnerBase) {
- _inherits(CPURunner, _RunnerBase);
-
- /**
- * @constructor CPURunner
- *
- * @desc Instantiates a Runner instance for the kernel.
- *
- * @extends RunnerBase
- *
- * @param {Object} settings - Settings to instantiate properties in RunnerBase, with given values
- *
- */
-
- function CPURunner(settings) {
- _classCallCheck(this, CPURunner);
-
- var _this = _possibleConstructorReturn(this, (CPURunner.__proto__ || Object.getPrototypeOf(CPURunner)).call(this, new CPUFunctionBuilder(), settings));
-
- _this.Kernel = CPUKernel;
- _this.kernel = null;
- return _this;
- }
-
- /**
- * @memberOf CPURunner#
- * @function
- * @name getMode()
- *
- * Return the current mode in which gpu.js is executing.
- *
- * @returns {String} The current mode; "cpu".
- *
- */
-
-
- _createClass(CPURunner, [{
- key: 'getMode',
- value: function getMode() {
- return 'cpu';
- }
- }]);
-
- return CPURunner;
-}(RunnerBase);
\ No newline at end of file
diff --git a/dist/backend/function-builder-base.js b/dist/backend/function-builder-base.js
deleted file mode 100644
index bfd59e15..00000000
--- a/dist/backend/function-builder-base.js
+++ /dev/null
@@ -1,364 +0,0 @@
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-module.exports = function () {
-
- /**
- * @constructor FunctionBuilderBase
- *
- * @desc This handles all the raw state, converted state, etc. of a single function.
- * [INTERNAL] A collection of functionNodes.
- *
- * @prop {Object} nodeMap - Object map, where nodeMap[function] = new FunctionNode;
- * @prop {Object} gpu - The current gpu instance bound to this builder
- * @prop {Object} rootKernel - The root kernel object, contains the paramNames, dimensions etc.
- *
- */
- function FunctionBuilderBase(gpu) {
- _classCallCheck(this, FunctionBuilderBase);
-
- this.nodeMap = {};
- this.nativeFunctions = {};
- this.gpu = gpu;
- this.rootKernel = null;
- this.Node = null;
- }
-
- _createClass(FunctionBuilderBase, [{
- key: 'addNativeFunction',
- value: function addNativeFunction(functionName, glslFunctionString) {
- this.nativeFunctions[functionName] = glslFunctionString;
- }
-
- /**
- * @memberOf FunctionBuilderBase#
- * @function
- * @name addFunction
- *
- * @desc Instantiates a FunctionNode, and add it to the nodeMap
- *
- * @param {String} functionName - Function name to assume, if its null, it attempts to extract from the function
- * @param {Function} jsFunction - JS Function to do conversion
- * @param {Object} [options]
- * @param {String[]|Object} [paramTypes] - Parameter type array, assumes all parameters are 'float' if falsey
- * @param {String} [returnType] - The return type, assumes 'float' if falsey
- *
- */
-
- }, {
- key: 'addFunction',
- value: function addFunction(functionName, jsFunction, options, paramTypes, returnType) {
- this.addFunctionNode(new this.Node(functionName, jsFunction, options, paramTypes, returnType).setAddFunction(this.addFunction.bind(this)));
- }
- }, {
- key: 'addFunctions',
- value: function addFunctions(functions, options) {
- if (functions) {
- if (Array.isArray(functions)) {
- for (var i = 0; i < functions.length; i++) {
- this.addFunction(null, functions[i], options);
- }
- } else {
- for (var p in functions) {
- this.addFunction(p, functions[p], options);
- }
- }
- }
- }
- }, {
- key: 'addNativeFunctions',
- value: function addNativeFunctions(nativeFunctions) {
- for (var functionName in nativeFunctions) {
- if (!nativeFunctions.hasOwnProperty(functionName)) continue;
- this.addNativeFunction(functionName, nativeFunctions[functionName]);
- }
- }
-
- /**
- * @memberOf FunctionBuilderBase#
- * @function
- * @name addFunctionNode
- *
- * @desc Add the function node directly
- *
- * @param {functionNode} inNode - functionNode to add
- *
- */
-
- }, {
- key: 'addFunctionNode',
- value: function addFunctionNode(inNode) {
- this.nodeMap[inNode.functionName] = inNode;
- if (inNode.isRootKernel) {
- this.rootKernel = inNode;
- }
- }
-
- /**
- * @memberOf FunctionBuilderBase#
- * @function
- * @name traceFunctionCalls
- *
- * @desc Trace all the depending functions being called, from a single function
- *
- * This allow for 'unneeded' functions to be automatically optimized out.
- * Note that the 0-index, is the starting function trace.
- *
- * @param {String} functionName - Function name to trace from, default to 'kernel'
- * @param {String[]} retList - Returning list of function names that is traced. Including itself.
- * @param {Object} [parent] - Parent node
- *
- * @returns {String[]} Returning list of function names that is traced. Including itself.
- */
-
- }, {
- key: 'traceFunctionCalls',
- value: function traceFunctionCalls(functionName, retList, parent) {
- functionName = functionName || 'kernel';
- retList = retList || [];
-
- var fNode = this.nodeMap[functionName];
- if (fNode) {
- // Check if function already exists
- var functionIndex = retList.indexOf(functionName);
- if (functionIndex === -1) {
- retList.push(functionName);
- if (parent) {
- fNode.parent = parent;
- }
- fNode.getFunctionString(); //ensure JS trace is done
- for (var i = 0; i < fNode.calledFunctions.length; ++i) {
- this.traceFunctionCalls(fNode.calledFunctions[i], retList, fNode);
- }
- } else {
- /**
- * https://github.com/gpujs/gpu.js/issues/207
- * if dependent function is already in the list, because a function depends on it, and because it has
- * already been traced, we know that we must move the dependent function to the end of the the retList.
- * */
- var dependantFunctionName = retList.splice(functionIndex, 1)[0];
- retList.push(dependantFunctionName);
- }
- }
-
- if (this.nativeFunctions[functionName]) {
- if (retList.indexOf(functionName) >= 0) {
- // Does nothing if already traced
- } else {
- retList.push(functionName);
- }
- }
-
- return retList;
- }
-
- /**
- * @memberOf FunctionBuilderBase#
- * @function
- * @name addKernel
- *
- * @desc Add a new kernel to this instance
- *
- * @param {String} fnString - Kernel function as a String
- * @param {Object} options - Settings object to set constants, debug mode, etc.
- * @param {Array} paramNames - Parameters of the kernel
- * @param {Array} paramTypes - Types of the parameters
- *
- *
- * @returns {Object} The inserted kernel as a Kernel Node
- *
- */
-
- }, {
- key: 'addKernel',
- value: function addKernel(fnString, options, paramNames, paramTypes) {
- var kernelNode = new this.Node('kernel', fnString, options, paramTypes);
- kernelNode.setAddFunction(this.addFunction.bind(this));
- kernelNode.paramNames = paramNames;
- kernelNode.paramTypes = paramTypes;
- kernelNode.isRootKernel = true;
- this.addFunctionNode(kernelNode);
- return kernelNode;
- }
-
- /**
- * @memberOf FunctionBuilderBase#
- * @function
- * @name addSubKernel
- *
- * @desc Add a new sub-kernel to the current kernel instance
- *
- * @param {Function} jsFunction - Sub-kernel function (JavaScript)
- * @param {Object} options - Settings object to set constants, debug mode, etc.
- * @param {Array} paramNames - Parameters of the sub-kernel
- * @param {Array} returnType - Return type of the subKernel
- *
- * @returns {Object} The inserted sub-kernel as a Kernel Node
- *
- */
-
- }, {
- key: 'addSubKernel',
- value: function addSubKernel(jsFunction, options, paramTypes, returnType) {
- var kernelNode = new this.Node(null, jsFunction, options, paramTypes, returnType);
- kernelNode.setAddFunction(this.addFunction.bind(this));
- kernelNode.isSubKernel = true;
- this.addFunctionNode(kernelNode);
- return kernelNode;
- }
-
- /**
- * @memberOf CPUFunctionBuilder#
- * @name getPrototypeString
- * @function
- *
- * @desc Return the string for a function
- *
- * @param {String} functionName - Function name to trace from. If null, it returns the WHOLE builder stack
- *
- * @returns {String} The full string, of all the various functions. Trace optimized if functionName given
- *
- */
-
- }, {
- key: 'getPrototypeString',
- value: function getPrototypeString(functionName) {
- return this.getPrototypes(functionName).join('\n');
- }
-
- /**
- * @memberOf CPUFunctionBuilder#
- * @name getPrototypeString
- * @function
- *
- * @desc Return the string for a function
- *
- * @param {String} [functionName] - Function name to trace from. If null, it returns the WHOLE builder stack
- *
- * @returns {Array} The full string, of all the various functions. Trace optimized if functionName given
- *
- */
-
- }, {
- key: 'getPrototypes',
- value: function getPrototypes(functionName) {
- this.rootKernel.generate();
- if (functionName) {
- return this.getPrototypesFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse());
- }
- return this.getPrototypesFromFunctionNames(Object.keys(this.nodeMap));
- }
-
- /**
- * @memberOf FunctionBuilderBase#
- * @function
- * @name getStringFromFunctionNames
- *
- * @desc Get string from function names
- *
- * @param {String[]} functionList - List of function to build string
- *
- * @returns {String} The string, of all the various functions. Trace optimized if functionName given
- *
- */
-
- }, {
- key: 'getStringFromFunctionNames',
- value: function getStringFromFunctionNames(functionList) {
- var ret = [];
- for (var i = 0; i < functionList.length; ++i) {
- var node = this.nodeMap[functionList[i]];
- if (node) {
- ret.push(this.nodeMap[functionList[i]].getFunctionString());
- }
- }
- return ret.join('\n');
- }
-
- /**
- * @memberOf FunctionBuilderBase#
- * @function
- * @name getPrototypeStringFromFunctionNames
- *
- * @desc Return string of all functions converted
- *
- * @param {String[]} functionList - List of function names to build the string.
- * @param {Object} [opt - Settings object passed to functionNode. See functionNode for more details.
- *
- * @returns {Array} Prototypes of all functions converted
- *
- */
-
- }, {
- key: 'getPrototypesFromFunctionNames',
- value: function getPrototypesFromFunctionNames(functionList, opt) {
- var ret = [];
- for (var i = 0; i < functionList.length; ++i) {
- var functionName = functionList[i];
- var node = this.nodeMap[functionName];
- if (node) {
- ret.push(node.getFunctionPrototypeString(opt));
- } else if (this.nativeFunctions[functionName]) {
- ret.push(this.nativeFunctions[functionName]);
- }
- }
- return ret;
- }
-
- /**
- * @memberOf FunctionBuilderBase#
- * @function
- * @name getPrototypeStringFromFunctionNames
- *
- * @desc Return string of all functions converted
- *
- * @param {String[]} functionList - List of function names to build the string.
- * @param {Object} opt - Settings object passed to functionNode. See functionNode for more details.
- *
- * @returns {String} Prototype string of all functions converted
- *
- */
-
- }, {
- key: 'getPrototypeStringFromFunctionNames',
- value: function getPrototypeStringFromFunctionNames(functionList, opt) {
- return this.getPrototypesFromFunctionNames(functionList, opt).toString();
- }
-
- /**
- * @memberOf FunctionBuilderBase#
- * @function
- * @name getString
- *
- * Get string for a particular function name
- *
- * @param {String} functionName - Function name to trace from. If null, it returns the WHOLE builder stack
- *
- * @returns {String} The string, of all the various functions. Trace optimized if functionName given
- *
- */
-
- }, {
- key: 'getString',
- value: function getString(functionName, opt) {
- if (opt === undefined) {
- opt = {};
- }
-
- if (functionName) {
- return this.getStringFromFunctionNames(this.traceFunctionCalls(functionName, [], opt).reverse(), opt);
- }
- return this.getStringFromFunctionNames(Object.keys(this.nodeMap), opt);
- }
- }, {
- key: 'polyfillStandardFunctions',
- value: function polyfillStandardFunctions() {
- throw new Error('polyfillStandardFunctions not defined on base function builder');
- }
- }]);
-
- return FunctionBuilderBase;
-}();
\ No newline at end of file
diff --git a/dist/backend/function-node-base.js b/dist/backend/function-node-base.js
deleted file mode 100644
index 1e2a2195..00000000
--- a/dist/backend/function-node-base.js
+++ /dev/null
@@ -1,415 +0,0 @@
-'use strict';
-
-var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var utils = require('../core/utils');
-var acorn = require('acorn');
-
-module.exports = function () {
-
- /**
- * @constructor FunctionNodeBase
- *
- * @desc Represents a single function, inside JS, webGL, or openGL.
- *
- * This handles all the raw state, converted state, etc. Of a single function.
- *
- * @prop {String} functionName - Name of the function
- * @prop {Function} jsFunction - The JS Function the node represents
- * @prop {String} jsFunctionString - jsFunction.toString()
- * @prop {String[]} paramNames - Parameter names of the function
- * @prop {String[]} paramTypes - Shader land parameters type assumption
- * @prop {Boolean} isRootKernel - Special indicator, for kernel function
- * @prop {String} webglFunctionString - webgl converted function string
- * @prop {String} openglFunctionString - opengl converted function string
- * @prop {String[]} calledFunctions - List of all the functions called
- * @prop {String[]} initVariables - List of variables initialized in the function
- * @prop {String[]} readVariables - List of variables read operations occur
- * @prop {String[]} writeVariables - List of variables write operations occur
- *
- * @param {GPU} gpu - The GPU instance
- * @param {String} functionName - Function name to assume, if its null, it attempts to extract from the function
- * @param {Function|String} jsFunction - JS Function to do conversion
- * @param {String[]|Object} paramTypes - Parameter type array, assumes all parameters are 'float' if null
- * @param {String} returnType - The return type, assumes 'float' if null
- *
- */
- function BaseFunctionNode(functionName, jsFunction, options, paramTypes, returnType) {
- _classCallCheck(this, BaseFunctionNode);
-
- //
- // Internal vars setup
- //
- this.calledFunctions = [];
- this.calledFunctionsArguments = {};
- this.initVariables = [];
- this.readVariables = [];
- this.writeVariables = [];
- this.addFunction = null;
- this.isRootKernel = false;
- this.isSubKernel = false;
- this.parent = null;
- this.debug = null;
- this.prototypeOnly = null;
- this.constants = null;
- this.output = null;
-
- if (options) {
- if (options.hasOwnProperty('debug')) {
- this.debug = options.debug;
- }
- if (options.hasOwnProperty('prototypeOnly')) {
- this.prototypeOnly = options.prototypeOnly;
- }
- if (options.hasOwnProperty('constants')) {
- this.constants = options.constants;
- }
- if (options.hasOwnProperty('output')) {
- this.output = options.output;
- }
- if (options.hasOwnProperty('loopMaxIterations')) {
- this.loopMaxIterations = options.loopMaxIterations;
- }
- }
-
- //
- // Missing jsFunction object exception
- //
- if (!jsFunction) {
- throw 'jsFunction, parameter is missing';
- }
-
- //
- // Setup jsFunction and its string property + validate them
- //
- this.jsFunctionString = jsFunction.toString();
- if (!utils.isFunctionString(this.jsFunctionString)) {
- console.error('jsFunction, to string conversion check failed: not a function?', this.jsFunctionString);
- throw 'jsFunction, to string conversion check failed: not a function?';
- }
-
- if (!utils.isFunction(jsFunction)) {
- //throw 'jsFunction, is not a valid JS Function';
- this.jsFunction = null;
- } else {
- this.jsFunction = jsFunction;
- }
-
- //
- // Setup the function name property
- //
- this.functionName = functionName || jsFunction && jsFunction.name || utils.getFunctionNameFromString(this.jsFunctionString);
-
- if (!this.functionName) {
- throw 'jsFunction, missing name argument or value';
- }
-
- //
- // Extract parameter name, and its argument types
- //
- this.paramNames = utils.getParamNamesFromString(this.jsFunctionString);
- if (paramTypes) {
- if (Array.isArray(paramTypes)) {
- if (paramTypes.length !== this.paramNames.length) {
- throw 'Invalid argument type array length, against function length -> (' + paramTypes.length + ',' + this.paramNames.length + ')';
- }
- this.paramTypes = paramTypes;
- } else if ((typeof paramTypes === 'undefined' ? 'undefined' : _typeof(paramTypes)) === 'object') {
- var paramVariableNames = Object.keys(paramTypes);
- if (paramTypes.hasOwnProperty('returns')) {
- this.returnType = paramTypes.returns;
- paramVariableNames.splice(paramVariableNames.indexOf('returns'), 1);
- }
- if (paramVariableNames.length > 0 && paramVariableNames.length !== this.paramNames.length) {
- throw 'Invalid argument type array length, against function length -> (' + paramVariableNames.length + ',' + this.paramNames.length + ')';
- } else {
- this.paramTypes = this.paramNames.map(function (key) {
- if (paramTypes.hasOwnProperty(key)) {
- return paramTypes[key];
- } else {
- return 'float';
- }
- });
- }
- }
- } else {
- this.paramTypes = [];
- //TODO: Remove when we have proper type detection
- // for (let a = 0; a < this.paramNames.length; ++a) {
- // this.paramTypes.push();
- // }
- }
-
- //
- // Return type handling
- //
- if (!this.returnType) {
- this.returnType = returnType || 'float';
- }
- }
-
- _createClass(BaseFunctionNode, [{
- key: 'isIdentifierConstant',
- value: function isIdentifierConstant(paramName) {
- if (!this.constants) return false;
- return this.constants.hasOwnProperty(paramName);
- }
- }, {
- key: 'setAddFunction',
- value: function setAddFunction(fn) {
- this.addFunction = fn;
- return this;
- }
- /**
- *
- * Core Functions
- *
- */
-
- /**
- * @memberOf FunctionNodeBase#
- * @function
- * @name getJSFunction
- *
- * @desc Gets and return the stored JS Function.
- * Note: that this internally eval the function, if only the string was provided on construction
- *
- * @returns {Function} The function object
- *
- */
-
- }, {
- key: 'getJsFunction',
- value: function getJsFunction() {
- if (this.jsFunction) {
- return this.jsFunction;
- }
-
- if (this.jsFunctionString) {
- this.jsFunction = eval(this.jsFunctionString);
- return this.jsFunction;
- }
-
- throw 'Missing jsFunction, and jsFunctionString parameter';
- }
-
- /**
- * @memberOf FunctionNodeBase#
- * @function
- * @name astMemberExpressionUnroll
- * @desc Parses the abstract syntax tree for binary expression.
- *
- * Utility function for astCallExpression.
- *
- * @param {Object} ast - the AST object to parse
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {String} the function namespace call, unrolled
- */
-
- }, {
- key: 'astMemberExpressionUnroll',
- value: function astMemberExpressionUnroll(ast, funcParam) {
- if (ast.type === 'Identifier') {
- return ast.name;
- } else if (ast.type === 'ThisExpression') {
- return 'this';
- }
-
- if (ast.type === 'MemberExpression') {
- if (ast.object && ast.property) {
- //babel sniffing
- if (ast.object.hasOwnProperty('name') && ast.object.name[0] === '_') {
- return this.astMemberExpressionUnroll(ast.property, funcParam);
- }
-
- return this.astMemberExpressionUnroll(ast.object, funcParam) + '.' + this.astMemberExpressionUnroll(ast.property, funcParam);
- }
- }
-
- //babel sniffing
- if (ast.hasOwnProperty('expressions')) {
- var firstExpression = ast.expressions[0];
- if (firstExpression.type === 'Literal' && firstExpression.value === 0 && ast.expressions.length === 2) {
- return this.astMemberExpressionUnroll(ast.expressions[1]);
- }
- }
-
- // Failure, unknown expression
- throw this.astErrorOutput('Unknown CallExpression_unroll', ast, funcParam);
- }
-
- /**
- * @memberOf FunctionNodeBase#
- * @function
- * @name getJsAST
- *
- * @desc Parses the class function JS, and returns its Abstract Syntax Tree object.
- *
- * This is used internally to convert to shader code
- *
- * @param {JISONParser} inParser - Parser to use, assumes in scope 'parser' if null
- *
- * @returns {ASTObject} The function AST Object, note that result is cached under this.jsFunctionAST;
- *
- */
-
- }, {
- key: 'getJsAST',
- value: function getJsAST(inParser) {
- if (this.jsFunctionAST) {
- return this.jsFunctionAST;
- }
-
- inParser = inParser || acorn;
- if (inParser === null) {
- throw 'Missing JS to AST parser';
- }
-
- var ast = inParser.parse('var ' + this.functionName + ' = ' + this.jsFunctionString + ';', {
- locations: true
- });
- if (ast === null) {
- throw 'Failed to parse JS code';
- }
-
- // take out the function object, outside the var declarations
- var funcAST = ast.body[0].declarations[0].init;
- this.jsFunctionAST = funcAST;
-
- return funcAST;
- }
-
- /**
- * @memberOf FunctionNodeBase#
- * @function
- * @name getFunctionString
- *
- * @desc Returns the converted webgl shader function equivalent of the JS function
- *
- * @returns {String} webgl function string, result is cached under this.webGlFunctionString
- *
- */
-
- }, {
- key: 'getFunctionString',
- value: function getFunctionString() {
- this.generate();
- return this.functionString;
- }
-
- /**
- * @memberOf FunctionNodeBase#
- * @function
- * @name setFunctionString
- *
- * @desc Set the functionString value, overwriting it
- *
- * @param {String} functionString - Shader code string, representing the function
- *
- */
-
- }, {
- key: 'setFunctionString',
- value: function setFunctionString(functionString) {
- this.functionString = functionString;
- }
-
- /**
- * @memberOf FunctionNodeBase#
- * @function
- * @name getParamType
- *
- * @desc Return the type of parameter sent to subKernel/Kernel.
- *
- * @param {String} paramName - Name of the parameter
- *
- * @returns {String} Type of the parameter
- *
- */
-
- }, {
- key: 'getParamType',
- value: function getParamType(paramName) {
- var paramIndex = this.paramNames.indexOf(paramName);
- if (paramIndex === -1) return null;
- if (!this.parent) return null;
- if (this.paramTypes[paramIndex]) return this.paramTypes[paramIndex];
- var calledFunctionArguments = this.parent.calledFunctionsArguments[this.functionName];
- for (var i = 0; i < calledFunctionArguments.length; i++) {
- var calledFunctionArgument = calledFunctionArguments[i];
- if (calledFunctionArgument[paramIndex] !== null) {
- return this.paramTypes[paramIndex] = calledFunctionArgument[paramIndex].type;
- }
- }
- return null;
- }
-
- /**
- * @memberOf FunctionNodeBase#
- * @function
- * @name getUserParamName
- *
- * @desc Return the name of the *user parameter*(subKernel parameter) corresponding
- * to the parameter supplied to the kernel
- *
- * @param {String} paramName - Name of the parameter
- *
- * @returns {String} Name of the parameter
- *
- */
-
- }, {
- key: 'getUserParamName',
- value: function getUserParamName(paramName) {
- var paramIndex = this.paramNames.indexOf(paramName);
- if (paramIndex === -1) return null;
- if (!this.parent) return null;
- var calledFunctionArguments = this.parent.calledFunctionsArguments[this.functionName];
- for (var i = 0; i < calledFunctionArguments.length; i++) {
- var calledFunctionArgument = calledFunctionArguments[i];
- if (calledFunctionArgument[paramIndex] !== null) {
- return calledFunctionArgument[paramIndex].name;
- }
- }
- return null;
- }
- }, {
- key: 'generate',
- value: function generate(options) {
- throw new Error('generate not defined on BaseFunctionNode');
- }
-
- /**
- * @function
- * @name astErrorOutput
- * @ignore
- * @desc To throw the AST error, with its location.
- *
- * @todo add location support fpr the AST error
- *
- * @param {Object} error - the error message output
- * @param {Object} ast - the AST object where the error is
- * @param {Object} funcParam - FunctionNode, that tracks compilation state
- */
-
- }, {
- key: 'astErrorOutput',
- value: function astErrorOutput(error, ast, funcParam) {
- console.error(utils.getAstString(this.jsFunctionString, ast));
- console.error(error, ast, funcParam);
- return error;
- }
- }, {
- key: 'astDebuggerStatement',
- value: function astDebuggerStatement(arrNode, retArr, funcParam) {
- return retArr;
- }
- }]);
-
- return BaseFunctionNode;
-}();
\ No newline at end of file
diff --git a/dist/backend/kernel-base.js b/dist/backend/kernel-base.js
deleted file mode 100644
index e23e5060..00000000
--- a/dist/backend/kernel-base.js
+++ /dev/null
@@ -1,442 +0,0 @@
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var utils = require('../core/utils');
-
-module.exports = function () {
-
- /**
- * @constructor BaseKernel
- *
- * @desc Implements the base class for Kernels, and is used as a
- * parent class for all Kernel implementations.
- *
- * This contains the basic methods needed by all Kernel implementations,
- * like setDimensions, addSubKernel, etc.
- *
- * @prop {Array} paramNames - Name of the parameters of the kernel function
- * @prop {String} fnString - Kernel function as a String
- * @prop {Array} dimensions - Dimensions of the kernel function, this.thread.x, etc.
- * @prop {Boolean} debug - Toggle debug mode
- * @prop {String} graphical - Toggle graphical mode
- * @prop {number} loopMaxIterations - Maximum number of loop iterations
- * @prop {Object} constants - Global constants
- * @prop {Array} subKernels - Sub kernels bound to this kernel instance
- * @prop {Object} subKernelProperties - Sub kernels bound to this kernel instance as key/value pairs
- * @prop {Array} subKernelOutputVariableNames - Names of the variables outputted by the subkerls
- *
- */
- function BaseKernel(fnString, settings) {
- _classCallCheck(this, BaseKernel);
-
- this.paramNames = utils.getParamNamesFromString(fnString);
- this.fnString = fnString;
- this.output = null;
- this.debug = false;
- this.graphical = false;
- this.loopMaxIterations = 0;
- this.constants = null;
- this.wraparound = null;
- this.hardcodeConstants = null;
- this.outputToTexture = null;
- this.texSize = null;
- this._canvas = null;
- this._webGl = null;
- this.threadDim = null;
- this.floatTextures = null;
- this.floatOutput = null;
- this.floatOutputForce = null;
- this.addFunction = null;
- this.functions = null;
- this.nativeFunctions = null;
- this.copyData = true;
- this.subKernels = null;
- this.subKernelProperties = null;
- this.subKernelNames = null;
- this.subKernelOutputVariableNames = null;
- this.functionBuilder = null;
- this.paramTypes = null;
-
- for (var p in settings) {
- if (!settings.hasOwnProperty(p) || !this.hasOwnProperty(p)) continue;
- this[p] = settings[p];
- }
- if (settings.hasOwnProperty('canvas')) {
- this._canvas = settings.canvas;
- }
- if (settings.hasOwnProperty('output')) {
- this.setOutput(settings.output); // Flatten output object
- }
-
- if (!this._canvas) this._canvas = utils.initCanvas();
- }
-
- _createClass(BaseKernel, [{
- key: 'build',
- value: function build() {
- throw new Error('"build" not defined on Base');
- }
-
- /**
- * @memberOf KernelBase#
- * @function
- * @name setupParams
- *
- * @desc Setup the parameter types for the parameters
- * supplied to the Kernel function
- *
- * @param {Array} args - The actual parameters sent to the Kernel
- *
- */
-
- }, {
- key: 'setupParams',
- value: function setupParams(args) {
- var paramTypes = this.paramTypes = [];
- for (var i = 0; i < args.length; i++) {
- var param = args[i];
- var paramType = utils.getArgumentType(param);
- paramTypes.push(paramType);
- }
- }
- }, {
- key: 'setAddFunction',
- value: function setAddFunction(cb) {
- this.addFunction = cb;
- return this;
- }
- }, {
- key: 'setFunctions',
- value: function setFunctions(functions) {
- this.functions = functions;
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name setOutput
- *
- * @desc Set dimensions of the kernel function
- *
- * @param {Array|Object} output - The output array to set the kernel output size to
- *
- */
-
- }, {
- key: 'setOutput',
- value: function setOutput(output) {
- if (output.hasOwnProperty('x')) {
- if (output.hasOwnProperty('y')) {
- if (output.hasOwnProperty('z')) {
- this.output = [output.x, output.y, output.z];
- } else {
- this.output = [output.x, output.y];
- }
- } else {
- this.output = [output.x];
- }
- } else {
- this.output = output;
- }
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name setDebug
- *
- * @desc Toggle debug mode
- *
- * @param {Boolean} flag - true to enable debug
- *
- */
-
- }, {
- key: 'setDebug',
- value: function setDebug(flag) {
- this.debug = flag;
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name setGraphical
- *
- * @desc Toggle graphical output mode
- *
- * @param {Boolean} flag - true to enable graphical output
- *
- */
-
- }, {
- key: 'setGraphical',
- value: function setGraphical(flag) {
- this.graphical = flag;
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name setLoopMaxIterations
- *
- * @desc Set the maximum number of loop iterations
- *
- * @param {number} max - iterations count
- *
- */
-
- }, {
- key: 'setLoopMaxIterations',
- value: function setLoopMaxIterations(max) {
- this.loopMaxIterations = max;
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name setConstants
- * @desc Set Constants
- */
-
- }, {
- key: 'setConstants',
- value: function setConstants(constants) {
- this.constants = constants;
- return this;
- }
- }, {
- key: 'setWraparound',
- value: function setWraparound(flag) {
- console.warn('Wraparound mode is not supported and undocumented.');
- this.wraparound = flag;
- return this;
- }
- }, {
- key: 'setHardcodeConstants',
- value: function setHardcodeConstants(flag) {
- this.hardcodeConstants = flag;
- return this;
- }
- }, {
- key: 'setOutputToTexture',
- value: function setOutputToTexture(flag) {
- this.outputToTexture = flag;
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name setFloatTextures
- *
- * @desc Toggle texture output mode
- *
- * @param {Boolean} flag - true to enable floatTextures
- *
- */
-
- }, {
- key: 'setFloatTextures',
- value: function setFloatTextures(flag) {
- this.floatTextures = flag;
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name setFloatOutput
- *
- * @desc Toggle output mode
- *
- * @param {Boolean} flag - true to enable float
- *
- */
-
- }, {
- key: 'setFloatOutput',
- value: function setFloatOutput(flag) {
- this.floatOutput = flag;
- return this;
- }
- }, {
- key: 'setFloatOutputForce',
- value: function setFloatOutputForce(flag) {
- this.floatOutputForce = flag;
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name setCanvas
- *
- * @desc Bind the canvas to kernel
- *
- * @param {Canvas} canvas - Canvas to bind
- *
- */
-
- }, {
- key: 'setCanvas',
- value: function setCanvas(canvas) {
- this._canvas = canvas;
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name setCanvas
- *
- * @desc Bind the webGL instance to kernel
- *
- * @param {Canvas} webGL - webGL instance to bind
- *
- */
-
- }, {
- key: 'setWebGl',
- value: function setWebGl(webGl) {
- this._webGl = webGl;
- return this;
- }
- }, {
- key: 'setCopyData',
- value: function setCopyData(copyData) {
- this.copyData = copyData;
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name getCanvas()
- *
- * @desc Returns the current canvas instance bound to the kernel
- *
- */
-
- }, {
- key: 'getCanvas',
- value: function getCanvas() {
- return this._canvas;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name getWebGl()
- *
- * @desc Returns the current webGl instance bound to the kernel
- *
- */
-
- }, {
- key: 'getWebGl',
- value: function getWebGl() {
- return this._webGl;
- }
- }, {
- key: 'validateOptions',
- value: function validateOptions() {
- throw new Error('validateOptions not defined');
- }
- }, {
- key: 'exec',
- value: function exec() {
- return this.execute.apply(this, arguments);
- }
- }, {
- key: 'execute',
- value: function execute() {
- var _this = this;
-
- //
- // Prepare the required objects
- //
- var args = arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments);
-
- //
- // Setup and return the promise, and execute the function, in synchronous mode
- //
- return utils.newPromise(function (accept, reject) {
- try {
- accept(_this.run.apply(_this, args));
- } catch (e) {
- //
- // Error : throw rejection
- //
- reject(e);
- }
- });
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name addSubKernel
- *
- * @desc Add a sub kernel to the root kernel instance.
- * This is what `createKernelMap` uses.
- *
- * @param {String} fnString - function (as a String) of the subKernel to add
- *
- */
-
- }, {
- key: 'addSubKernel',
- value: function addSubKernel(fnString) {
- if (this.subKernels === null) {
- this.subKernels = [];
- this.subKernelNames = [];
- }
- this.subKernels.push(fnString);
- this.subKernelNames.push(utils.getFunctionNameFromString(fnString));
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name addSubKernelProperty
- *
- * @desc Add a sub kernel to the root kernel instance, indexed by a property name
- * This is what `createKernelMap` uses.
- *
- * @param {String} property - property key for the subKernel
- * @param {String} fnString - function (as a String) of the subKernel to add
- *
- */
-
- }, {
- key: 'addSubKernelProperty',
- value: function addSubKernelProperty(property, fnString) {
- if (this.subKernelProperties === null) {
- this.subKernelProperties = {};
- this.subKernelNames = [];
- }
- if (this.subKernelProperties.hasOwnProperty(property)) {
- throw new Error('cannot add sub kernel ' + property + ', already defined');
- }
- this.subKernelProperties[property] = fnString;
- this.subKernelNames.push(utils.getFunctionNameFromString(fnString));
- return this;
- }
- }, {
- key: 'addNativeFunction',
- value: function addNativeFunction(name, source) {
- this.functionBuilder.addNativeFunction(name, source);
- }
- }]);
-
- return BaseKernel;
-}();
\ No newline at end of file
diff --git a/dist/backend/kernel-run-shortcut.js b/dist/backend/kernel-run-shortcut.js
deleted file mode 100644
index 1842d06a..00000000
--- a/dist/backend/kernel-run-shortcut.js
+++ /dev/null
@@ -1,34 +0,0 @@
-'use strict';
-
-var utils = require('../core/utils');
-
-module.exports = function kernelRunShortcut(kernel) {
- var shortcut = function shortcut() {
- return kernel.run.apply(kernel, arguments);
- };
-
- utils.allPropertiesOf(kernel).forEach(function (key) {
- if (key[0] === '_' && key[1] === '_') return;
- if (typeof kernel[key] === 'function') {
- if (key.substring(0, 3) === 'add' || key.substring(0, 3) === 'set') {
- shortcut[key] = function () {
- kernel[key].apply(kernel, arguments);
- return shortcut;
- };
- } else {
- shortcut[key] = kernel[key].bind(kernel);
- }
- } else {
- shortcut.__defineGetter__(key, function () {
- return kernel[key];
- });
- shortcut.__defineSetter__(key, function (value) {
- kernel[key] = value;
- });
- }
- });
-
- shortcut.kernel = kernel;
-
- return shortcut;
-};
\ No newline at end of file
diff --git a/dist/backend/runner-base.js b/dist/backend/runner-base.js
deleted file mode 100644
index b99cf1bc..00000000
--- a/dist/backend/runner-base.js
+++ /dev/null
@@ -1,144 +0,0 @@
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var utils = require('../core/utils');
-var kernelRunShortcut = require('./kernel-run-shortcut');
-
-module.exports = function () {
-
- /**
- * @constructor BaseRunner
- *
- * @desc Represents the 'private/protected' namespace of the GPU class
- *
- * I know @private makes more sense, but since the documentation engine state is undetirmined.
- * (See https://github.com/gpujs/gpu.js/issues/19 regarding documentation engine issue)
- * File isolation is currently the best way to go.
- *
- * *base.js* internal functions namespace
- * *gpu.js* PUBLIC function namespace
- *
- * @prop {Object} settings - Settings object used to set Dimensions, etc.
- * @prop {String} kernel - Current kernel instance
- * @prop {Object} canvas - Canvas instance attached to the kernel
- * @prop {Object} webGl - WebGl instance attached to the kernel
- * @prop {Function} fn - Kernel function to run
- * @prop {Object} functionBuilder - FunctionBuilder instance
- * @prop {String} fnString - Kernel function (as a String)
- * @prop {String} endianness - endian information like Little-endian, Big-endian.
- *
- */
-
- function BaseRunner(functionBuilder, settings) {
- _classCallCheck(this, BaseRunner);
-
- settings = settings || {};
- this.kernel = settings.kernel;
- this.canvas = settings.canvas;
- this.webGl = settings.webGl;
- this.fn = null;
- this.functionBuilder = functionBuilder;
- this.fnString = null;
- this.endianness = utils.systemEndianness();
- this.functionBuilder.polyfillStandardFunctions();
- }
-
- /**
- * @memberOf BaseRunner#
- * @function
- * @name textureToArray
- *
- * @desc Converts the provided Texture instance to a JavaScript Array
- *
- * @param {Object} texture - Texture Object
- *
- */
-
-
- _createClass(BaseRunner, [{
- key: 'textureToArray',
- value: function textureToArray(texture) {
- var copy = this.createKernel(function (x) {
- return x[this.thread.z][this.thread.y][this.thread.x];
- });
-
- return copy(texture);
- }
-
- /**
- * @memberOf BaseRunner#
- * @function
- *
- * @name deleteTexture
- *
- * @desc Deletes the provided Texture instance
- *
- * @param {Object} texture - Texture Object
- */
-
- }, {
- key: 'deleteTexture',
- value: function deleteTexture(texture) {
- this.webGl.deleteTexture(texture.texture);
- }
-
- /**
- * @memberOf BaseRunner#
- * @function
- * @name buildPromiseKernel
- *
- * @desc Get and returns the ASYNCHRONOUS executor, of a class and kernel
- * This returns a Promise object from an argument set.
- *
- * Note that there is no current implementation.
- *
- */
-
- }, {
- key: 'buildPromiseKernel',
- value: function buildPromiseKernel() {
- throw new Error('not yet implemented');
- }
- }, {
- key: 'getMode',
- value: function getMode() {
- throw new Error('"mode" not implemented on BaseRunner');
- }
-
- /**
- * @memberOf BaseRunner#
- * @function
- *
- * @name buildKernel
- *
- * @desc Get and returns the Synchronous executor, of a class and kernel
- * Which returns the result directly after passing the arguments.
- *
- */
-
- }, {
- key: 'buildKernel',
- value: function buildKernel(fn, settings) {
- settings = Object.assign({}, settings || {});
- var fnString = fn.toString();
- if (!settings.functionBuilder) {
- settings.functionBuilder = this.functionBuilder;
- }
-
- if (!settings.canvas) {
- settings.canvas = this.canvas;
- }
-
- if (!settings.webGl) {
- settings.webGl = this.webgl;
- }
-
- return kernelRunShortcut(new this.Kernel(fnString, settings));
- }
- }]);
-
- return BaseRunner;
-}();
\ No newline at end of file
diff --git a/dist/backend/web-gl/function-builder.js b/dist/backend/web-gl/function-builder.js
deleted file mode 100644
index 0529d709..00000000
--- a/dist/backend/web-gl/function-builder.js
+++ /dev/null
@@ -1,70 +0,0 @@
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var FunctionBuilderBase = require('../function-builder-base');
-var WebGLFunctionNode = require('./function-node');
-
-/**
- * @class WebGLFunctionBuilder
- *
- * @extends FunctionBuilderBase
- *
- * @desc Builds webGl functions (shaders) from JavaScript function Strings
- *
- */
-module.exports = function (_FunctionBuilderBase) {
- _inherits(WebGLFunctionBuilder, _FunctionBuilderBase);
-
- function WebGLFunctionBuilder() {
- _classCallCheck(this, WebGLFunctionBuilder);
-
- var _this = _possibleConstructorReturn(this, (WebGLFunctionBuilder.__proto__ || Object.getPrototypeOf(WebGLFunctionBuilder)).call(this));
-
- _this.Node = WebGLFunctionNode;
- return _this;
- }
-
- //---------------------------------------------------------
- //
- // Polyfill stuff
- //
- //---------------------------------------------------------
-
- // Round function used in polyfill
-
-
- _createClass(WebGLFunctionBuilder, [{
- key: 'polyfillStandardFunctions',
-
-
- /**
- * @memberOf FunctionBuilderBase#
- * @function
- * @name polyfillStandardFunctions
- *
- * @desc Polyfill in the missing Math functions (round)
- *
- */
- value: function polyfillStandardFunctions() {
- this.addFunction('round', _round);
- }
- }], [{
- key: 'round',
- value: function round(a) {
- return _round(a);
- }
- }]);
-
- return WebGLFunctionBuilder;
-}(FunctionBuilderBase);
-
-function _round(a) {
- return Math.floor(a + 0.5);
-}
\ No newline at end of file
diff --git a/dist/backend/web-gl/function-node.js b/dist/backend/web-gl/function-node.js
deleted file mode 100644
index 29295249..00000000
--- a/dist/backend/web-gl/function-node.js
+++ /dev/null
@@ -1,1223 +0,0 @@
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var FunctionNodeBase = require('../function-node-base');
-var utils = require('../../core/utils');
-// Closure capture for the ast function, prevent collision with existing AST functions
-// The prefixes to use
-var jsMathPrefix = 'Math.';
-var localPrefix = 'this.';
-var constantsPrefix = 'this.constants.';
-
-var DECODE32_ENCODE32 = /decode32\(\s+encode32\(/g;
-var ENCODE32_DECODE32 = /encode32\(\s+decode32\(/g;
-
-/**
- * @class WebGLFunctionNode
- *
- * @desc [INTERNAL] Takes in a function node, and does all the AST voodoo required to generate its respective webGL code.
- *
- * @extends FunctionNodeBase
- *
- * @param {functionNode} inNode - The function node object
- *
- * @returns the converted webGL function string
- *
- */
-module.exports = function (_FunctionNodeBase) {
- _inherits(WebGLFunctionNode, _FunctionNodeBase);
-
- function WebGLFunctionNode() {
- _classCallCheck(this, WebGLFunctionNode);
-
- return _possibleConstructorReturn(this, (WebGLFunctionNode.__proto__ || Object.getPrototypeOf(WebGLFunctionNode)).apply(this, arguments));
- }
-
- _createClass(WebGLFunctionNode, [{
- key: 'generate',
- value: function generate() {
- if (this.debug) {
- console.log(this);
- }
- if (this.prototypeOnly) {
- return WebGLFunctionNode.astFunctionPrototype(this.getJsAST(), [], this).join('').trim();
- } else {
- this.functionStringArray = this.astGeneric(this.getJsAST(), [], this);
- }
- this.functionString = webGlRegexOptimize(this.functionStringArray.join('').trim());
- return this.functionString;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astGeneric
- *
- * @desc Parses the abstract syntax tree for generically to its respective function
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {String} the prased openclgl string array
- */
-
- }, {
- key: 'astGeneric',
- value: function astGeneric(ast, retArr, funcParam) {
- if (ast === null) {
- throw this.astErrorOutput('NULL ast', ast, funcParam);
- } else {
- if (Array.isArray(ast)) {
- for (var i = 0; i < ast.length; i++) {
- this.astGeneric(ast[i], retArr, funcParam);
- }
- return retArr;
- }
-
- switch (ast.type) {
- case 'FunctionDeclaration':
- return this.astFunctionDeclaration(ast, retArr, funcParam);
- case 'FunctionExpression':
- return this.astFunctionExpression(ast, retArr, funcParam);
- case 'ReturnStatement':
- return this.astReturnStatement(ast, retArr, funcParam);
- case 'Literal':
- return this.astLiteral(ast, retArr, funcParam);
- case 'BinaryExpression':
- return this.astBinaryExpression(ast, retArr, funcParam);
- case 'Identifier':
- return this.astIdentifierExpression(ast, retArr, funcParam);
- case 'AssignmentExpression':
- return this.astAssignmentExpression(ast, retArr, funcParam);
- case 'ExpressionStatement':
- return this.astExpressionStatement(ast, retArr, funcParam);
- case 'EmptyStatement':
- return this.astEmptyStatement(ast, retArr, funcParam);
- case 'BlockStatement':
- return this.astBlockStatement(ast, retArr, funcParam);
- case 'IfStatement':
- return this.astIfStatement(ast, retArr, funcParam);
- case 'BreakStatement':
- return this.astBreakStatement(ast, retArr, funcParam);
- case 'ContinueStatement':
- return this.astContinueStatement(ast, retArr, funcParam);
- case 'ForStatement':
- return this.astForStatement(ast, retArr, funcParam);
- case 'WhileStatement':
- return this.astWhileStatement(ast, retArr, funcParam);
- case 'VariableDeclaration':
- return this.astVariableDeclaration(ast, retArr, funcParam);
- case 'VariableDeclarator':
- return this.astVariableDeclarator(ast, retArr, funcParam);
- case 'ThisExpression':
- return this.astThisExpression(ast, retArr, funcParam);
- case 'SequenceExpression':
- return this.astSequenceExpression(ast, retArr, funcParam);
- case 'UnaryExpression':
- return this.astUnaryExpression(ast, retArr, funcParam);
- case 'UpdateExpression':
- return this.astUpdateExpression(ast, retArr, funcParam);
- case 'LogicalExpression':
- return this.astLogicalExpression(ast, retArr, funcParam);
- case 'MemberExpression':
- return this.astMemberExpression(ast, retArr, funcParam);
- case 'CallExpression':
- return this.astCallExpression(ast, retArr, funcParam);
- case 'ArrayExpression':
- return this.astArrayExpression(ast, retArr, funcParam);
- case 'DebuggerStatement':
- return this.astDebuggerStatement(ast, retArr, funcParam);
- }
-
- throw this.astErrorOutput('Unknown ast type : ' + ast.type, ast, funcParam);
- }
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astFunctionDeclaration
- *
- * @desc Parses the abstract syntax tree for to its *named function declaration*
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astFunctionDeclaration',
- value: function astFunctionDeclaration(ast, retArr, funcParam) {
- if (this.addFunction) {
- this.addFunction(null, utils.getAstString(this.jsFunctionString, ast));
- }
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astFunctionPrototype
- * @static
- *
- * @desc Parses the abstract syntax tree for to its *named function prototype*
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astFunctionExpression',
-
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astFunctionExpression
- *
- * @desc Parses the abstract syntax tree for to its *named function*
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- value: function astFunctionExpression(ast, retArr, funcParam) {
-
- // Setup function return type and name
- if (funcParam.isRootKernel) {
- retArr.push('void');
- funcParam.kernalAst = ast;
- } else {
- retArr.push(funcParam.returnType);
- }
- retArr.push(' ');
- retArr.push(funcParam.functionName);
- retArr.push('(');
-
- if (!funcParam.isRootKernel) {
- // Arguments handling
- for (var i = 0; i < funcParam.paramNames.length; ++i) {
- var paramName = funcParam.paramNames[i];
-
- if (i > 0) {
- retArr.push(', ');
- }
- var type = funcParam.getParamType(paramName);
- switch (type) {
- case 'Texture':
- case 'Input':
- case 'Array':
- retArr.push('sampler2D');
- break;
- default:
- retArr.push('float');
- }
-
- retArr.push(' ');
- retArr.push('user_');
- retArr.push(paramName);
- }
- }
-
- // Function opening
- retArr.push(') {\n');
-
- // Body statement iteration
- for (var _i = 0; _i < ast.body.body.length; ++_i) {
- this.astGeneric(ast.body.body[_i], retArr, funcParam);
- retArr.push('\n');
- }
-
- // Function closing
- retArr.push('}\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astReturnStatement
- *
- * @desc Parses the abstract syntax tree for to *return* statement
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Object} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astReturnStatement',
- value: function astReturnStatement(ast, retArr, funcParam) {
- if (funcParam.isRootKernel) {
- retArr.push('kernelResult = ');
- this.astGeneric(ast.argument, retArr, funcParam);
- retArr.push(';');
- retArr.push('return;');
- } else if (funcParam.isSubKernel) {
- retArr.push(funcParam.functionName + 'Result = ');
- this.astGeneric(ast.argument, retArr, funcParam);
- retArr.push(';');
- retArr.push('return ' + funcParam.functionName + 'Result;');
- } else {
- retArr.push('return ');
- this.astGeneric(ast.argument, retArr, funcParam);
- retArr.push(';');
- }
-
- //throw this.astErrorOutput(
- // 'Non main function return, is not supported : '+funcParam.currentFunctionNamespace,
- // ast, funcParam
- //);
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astLiteral
- *
- * @desc Parses the abstract syntax tree for *literal value*
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astLiteral',
- value: function astLiteral(ast, retArr, funcParam) {
-
- // Reject non numeric literals
- if (isNaN(ast.value)) {
- throw this.astErrorOutput('Non-numeric literal not supported : ' + ast.value, ast, funcParam);
- }
-
- // Push the literal value as a float/int
- retArr.push(ast.value);
-
- // If it was an int, node made a float
- if (Number.isInteger(ast.value)) {
- retArr.push('.0');
- }
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astBinaryExpression
- *
- * @desc Parses the abstract syntax tree for *binary* expression
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astBinaryExpression',
- value: function astBinaryExpression(ast, retArr, funcParam) {
- retArr.push('(');
-
- if (ast.operator === '%') {
- retArr.push('mod(');
- this.astGeneric(ast.left, retArr, funcParam);
- retArr.push(',');
- this.astGeneric(ast.right, retArr, funcParam);
- retArr.push(')');
- } else if (ast.operator === '===') {
- this.astGeneric(ast.left, retArr, funcParam);
- retArr.push('==');
- this.astGeneric(ast.right, retArr, funcParam);
- } else if (ast.operator === '!==') {
- this.astGeneric(ast.left, retArr, funcParam);
- retArr.push('!=');
- this.astGeneric(ast.right, retArr, funcParam);
- } else {
- this.astGeneric(ast.left, retArr, funcParam);
- retArr.push(ast.operator);
- this.astGeneric(ast.right, retArr, funcParam);
- }
-
- retArr.push(')');
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astIdentifierExpression
- *
- * @desc Parses the abstract syntax tree for *identifier* expression
- *
- * @param {Object} idtNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astIdentifierExpression',
- value: function astIdentifierExpression(idtNode, retArr, funcParam) {
- if (idtNode.type !== 'Identifier') {
- throw this.astErrorOutput('IdentifierExpression - not an Identifier', ast, funcParam);
- }
-
- switch (idtNode.name) {
- case 'gpu_threadX':
- retArr.push('threadId.x');
- break;
- case 'gpu_threadY':
- retArr.push('threadId.y');
- break;
- case 'gpu_threadZ':
- retArr.push('threadId.z');
- break;
- case 'gpu_outputX':
- retArr.push('uOutputDim.x');
- break;
- case 'gpu_outputY':
- retArr.push('uOutputDim.y');
- break;
- case 'gpu_outputZ':
- retArr.push('uOutputDim.z');
- break;
- default:
- if (this.constants && this.constants.hasOwnProperty(idtNode.name)) {
- retArr.push('constants_' + idtNode.name);
- } else {
- var userParamName = funcParam.getUserParamName(idtNode.name);
- if (userParamName !== null) {
- retArr.push('user_' + userParamName);
- } else {
- retArr.push('user_' + idtNode.name);
- }
- }
- }
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astForStatement
- *
- * @desc Parses the abstract syntax tree forfor *for-loop* expression
- *
- * @param {Object} forNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {String} the prased openclgl string
- */
-
- }, {
- key: 'astForStatement',
- value: function astForStatement(forNode, retArr, funcParam) {
- if (forNode.type !== 'ForStatement') {
- throw this.astErrorOutput('Invalid for statment', ast, funcParam);
- }
-
- if (forNode.test && forNode.test.type === 'BinaryExpression') {
- if (forNode.test.right.type === 'Identifier' && forNode.test.operator === '<' && this.isIdentifierConstant(forNode.test.right.name) === false) {
-
- if (!this.loopMaxIterations) {
- console.warn('Warning: loopMaxIterations is not set! Using default of 1000 which may result in unintended behavior.');
- console.warn('Set loopMaxIterations or use a for loop of fixed length to silence this message.');
- }
-
- retArr.push('for (');
- this.astGeneric(forNode.init, retArr, funcParam);
- this.astGeneric(forNode.test.left, retArr, funcParam);
- retArr.push(forNode.test.operator);
- retArr.push('LOOP_MAX');
- retArr.push(';');
- this.astGeneric(forNode.update, retArr, funcParam);
- retArr.push(')');
-
- retArr.push('{\n');
- retArr.push('if (');
- this.astGeneric(forNode.test.left, retArr, funcParam);
- retArr.push(forNode.test.operator);
- this.astGeneric(forNode.test.right, retArr, funcParam);
- retArr.push(') {\n');
- if (forNode.body.type === 'BlockStatement') {
- for (var i = 0; i < forNode.body.body.length; i++) {
- this.astGeneric(forNode.body.body[i], retArr, funcParam);
- }
- } else {
- this.astGeneric(forNode.body, retArr, funcParam);
- }
- retArr.push('} else {\n');
- retArr.push('break;\n');
- retArr.push('}\n');
- retArr.push('}\n');
-
- return retArr;
- } else {
- var declarations = JSON.parse(JSON.stringify(forNode.init.declarations));
- var updateArgument = forNode.update.argument;
- if (!Array.isArray(declarations) || declarations.length < 1) {
- console.log(this.jsFunctionString);
- throw new Error('Error: Incompatible for loop declaration');
- }
-
- if (declarations.length > 1) {
- var initArgument = null;
- for (var _i2 = 0; _i2 < declarations.length; _i2++) {
- var declaration = declarations[_i2];
- if (declaration.id.name === updateArgument.name) {
- initArgument = declaration;
- declarations.splice(_i2, 1);
- } else {
- retArr.push('float ');
- this.astGeneric(declaration, retArr, funcParam);
- retArr.push(';');
- }
- }
-
- retArr.push('for (float ');
- this.astGeneric(initArgument, retArr, funcParam);
- retArr.push(';');
- } else {
- retArr.push('for (');
- this.astGeneric(forNode.init, retArr, funcParam);
- }
-
- this.astGeneric(forNode.test, retArr, funcParam);
- retArr.push(';');
- this.astGeneric(forNode.update, retArr, funcParam);
- retArr.push(')');
- this.astGeneric(forNode.body, retArr, funcParam);
- return retArr;
- }
- }
-
- throw this.astErrorOutput('Invalid for statement', ast, funcParam);
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astWhileStatement
- *
- * @desc Parses the abstract syntax tree for *while* loop
- *
- *
- * @param {Object} whileNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {String} the parsed openclgl string
- */
-
- }, {
- key: 'astWhileStatement',
- value: function astWhileStatement(whileNode, retArr, funcParam) {
- if (whileNode.type !== 'WhileStatement') {
- throw this.astErrorOutput('Invalid while statment', ast, funcParam);
- }
-
- retArr.push('for (float i = 0.0; i < LOOP_MAX; i++) {');
- retArr.push('if (');
- this.astGeneric(whileNode.test, retArr, funcParam);
- retArr.push(') {\n');
- this.astGeneric(whileNode.body, retArr, funcParam);
- retArr.push('} else {\n');
- retArr.push('break;\n');
- retArr.push('}\n');
- retArr.push('}\n');
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astAssignmentExpression
- *
- * @desc Parses the abstract syntax tree for *Assignment* Expression
- *
- * @param {Object} assNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astAssignmentExpression',
- value: function astAssignmentExpression(assNode, retArr, funcParam) {
- if (assNode.operator === '%=') {
- this.astGeneric(assNode.left, retArr, funcParam);
- retArr.push('=');
- retArr.push('mod(');
- this.astGeneric(assNode.left, retArr, funcParam);
- retArr.push(',');
- this.astGeneric(assNode.right, retArr, funcParam);
- retArr.push(')');
- } else {
- this.astGeneric(assNode.left, retArr, funcParam);
- retArr.push(assNode.operator);
- this.astGeneric(assNode.right, retArr, funcParam);
- return retArr;
- }
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astEmptyStatement
- *
- * @desc Parses the abstract syntax tree for an *Empty* Statement
- *
- * @param {Object} eNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astEmptyStatement',
- value: function astEmptyStatement(eNode, retArr, funcParam) {
- //retArr.push(';\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astBlockStatement
- *
- * @desc Parses the abstract syntax tree for *Block* statement
- *
- * @param {Object} bnode - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astBlockStatement',
- value: function astBlockStatement(bNode, retArr, funcParam) {
- retArr.push('{\n');
- for (var i = 0; i < bNode.body.length; i++) {
- this.astGeneric(bNode.body[i], retArr, funcParam);
- }
- retArr.push('}\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astExpressionStatement
- *
- * @desc Parses the abstract syntax tree for *generic expression* statement
- *
- * @param {Object} esNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astExpressionStatement',
- value: function astExpressionStatement(esNode, retArr, funcParam) {
- this.astGeneric(esNode.expression, retArr, funcParam);
- retArr.push(';\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astVariableDeclaration
- *
- * @desc Parses the abstract syntax tree for *Variable Declaration*
- *
- * @param {Object} vardecNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astVariableDeclaration',
- value: function astVariableDeclaration(vardecNode, retArr, funcParam) {
- retArr.push('float ');
- for (var i = 0; i < vardecNode.declarations.length; i++) {
- if (i > 0) {
- retArr.push(',');
- }
- this.astGeneric(vardecNode.declarations[i], retArr, funcParam);
- }
- retArr.push(';');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astVariableDeclarator
- *
- * @desc Parses the abstract syntax tree for *Variable Declarator*
- *
- * @param {Object} ivardecNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astVariableDeclarator',
- value: function astVariableDeclarator(ivardecNode, retArr, funcParam) {
- this.astGeneric(ivardecNode.id, retArr, funcParam);
- if (ivardecNode.init !== null) {
- retArr.push('=');
- this.astGeneric(ivardecNode.init, retArr, funcParam);
- }
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astIfStatement
- *
- * @desc Parses the abstract syntax tree for *If* Statement
- *
- * @param {Object} ifNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astIfStatement',
- value: function astIfStatement(ifNode, retArr, funcParam) {
- retArr.push('if (');
- this.astGeneric(ifNode.test, retArr, funcParam);
- retArr.push(')');
- if (ifNode.consequent.type === 'BlockStatement') {
- this.astGeneric(ifNode.consequent, retArr, funcParam);
- } else {
- retArr.push(' {\n');
- this.astGeneric(ifNode.consequent, retArr, funcParam);
- retArr.push('\n}\n');
- }
-
- if (ifNode.alternate) {
- retArr.push('else ');
- if (ifNode.alternate.type === 'BlockStatement') {
- this.astGeneric(ifNode.alternate, retArr, funcParam);
- } else {
- retArr.push(' {\n');
- this.astGeneric(ifNode.alternate, retArr, funcParam);
- retArr.push('\n}\n');
- }
- }
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astBreakStatement
- *
- * @desc Parses the abstract syntax tree for *Break* Statement
- *
- * @param {Object} brNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astBreakStatement',
- value: function astBreakStatement(brNode, retArr, funcParam) {
- retArr.push('break;\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astContinueStatement
- *
- * @desc Parses the abstract syntax tree for *Continue* Statement
- *
- * @param {Object} crNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astContinueStatement',
- value: function astContinueStatement(crNode, retArr, funcParam) {
- retArr.push('continue;\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astLogicalExpression
- *
- * @desc Parses the abstract syntax tree for *Logical* Expression
- *
- * @param {Object} logNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astLogicalExpression',
- value: function astLogicalExpression(logNode, retArr, funcParam) {
- retArr.push('(');
- this.astGeneric(logNode.left, retArr, funcParam);
- retArr.push(logNode.operator);
- this.astGeneric(logNode.right, retArr, funcParam);
- retArr.push(')');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astUpdateExpression
- *
- * @desc Parses the abstract syntax tree for *Update* Expression
- *
- * @param {Object} uNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astUpdateExpression',
- value: function astUpdateExpression(uNode, retArr, funcParam) {
- if (uNode.prefix) {
- retArr.push(uNode.operator);
- this.astGeneric(uNode.argument, retArr, funcParam);
- } else {
- this.astGeneric(uNode.argument, retArr, funcParam);
- retArr.push(uNode.operator);
- }
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astUnaryExpression
- *
- * @desc Parses the abstract syntax tree for *Unary* Expression
- *
- * @param {Object} uNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astUnaryExpression',
- value: function astUnaryExpression(uNode, retArr, funcParam) {
- if (uNode.prefix) {
- retArr.push(uNode.operator);
- this.astGeneric(uNode.argument, retArr, funcParam);
- } else {
- this.astGeneric(uNode.argument, retArr, funcParam);
- retArr.push(uNode.operator);
- }
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astThisExpression
- *
- * @desc Parses the abstract syntax tree for *This* expression
- *
- * @param {Object} tNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astThisExpression',
- value: function astThisExpression(tNode, retArr, funcParam) {
- retArr.push('this');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astMemberExpression
- *
- * @desc Parses the abstract syntax tree for *Member* Expression
- *
- * @param {Object} mNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astMemberExpression',
- value: function astMemberExpression(mNode, retArr, funcParam) {
- if (mNode.computed) {
- if (mNode.object.type === 'Identifier') {
- // Working logger
- var reqName = mNode.object.name;
- var funcName = funcParam.functionName || 'kernel';
- var assumeNotTexture = false;
-
- // Possibly an array request - handle it as such
- if (funcParam.paramNames) {
- var idx = funcParam.paramNames.indexOf(reqName);
- if (idx >= 0 && funcParam.paramTypes[idx] === 'float') {
- assumeNotTexture = true;
- }
- }
-
- if (assumeNotTexture) {
- // Get from array
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push('[int(');
- this.astGeneric(mNode.property, retArr, funcParam);
- retArr.push(')]');
- } else {
- // Get from texture
- // This normally refers to the global read only input vars
- retArr.push('get(');
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push(', vec2(');
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push('Size[0],');
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push('Size[1]), vec3(');
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push('Dim[0],');
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push('Dim[1],');
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push('Dim[2]');
- retArr.push('), ');
- this.astGeneric(mNode.property, retArr, funcParam);
- retArr.push(')');
- }
- } else {
- this.astGeneric(mNode.object, retArr, funcParam);
- var last = retArr.pop();
- retArr.push(',');
- this.astGeneric(mNode.property, retArr, funcParam);
- retArr.push(last);
- }
- } else {
-
- // Unroll the member expression
- var unrolled = this.astMemberExpressionUnroll(mNode);
- var unrolled_lc = unrolled.toLowerCase();
-
- // Its a constant, remove this.constants.
- if (unrolled.indexOf(constantsPrefix) === 0) {
- unrolled = 'constants_' + unrolled.slice(constantsPrefix.length);
- }
-
- switch (unrolled_lc) {
- case 'this.thread.x':
- retArr.push('threadId.x');
- break;
- case 'this.thread.y':
- retArr.push('threadId.y');
- break;
- case 'this.thread.z':
- retArr.push('threadId.z');
- break;
- case 'this.output.x':
- retArr.push(this.output[0] + '.0');
- break;
- case 'this.output.y':
- retArr.push(this.output[1] + '.0');
- break;
- case 'this.output.z':
- retArr.push(this.output[2] + '.0');
- break;
- default:
- retArr.push(unrolled);
- }
- }
- return retArr;
- }
- }, {
- key: 'astSequenceExpression',
- value: function astSequenceExpression(sNode, retArr, funcParam) {
- for (var i = 0; i < sNode.expressions.length; i++) {
- if (i > 0) {
- retArr.push(',');
- }
- this.astGeneric(sNode.expressions, retArr, funcParam);
- }
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astCallExpression
- *
- * @desc Parses the abstract syntax tree for *call* expression
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astCallExpression',
- value: function astCallExpression(ast, retArr, funcParam) {
- if (ast.callee) {
- // Get the full function call, unrolled
- var funcName = this.astMemberExpressionUnroll(ast.callee);
-
- // Its a math operator, remove the prefix
- if (funcName.indexOf(jsMathPrefix) === 0) {
- funcName = funcName.slice(jsMathPrefix.length);
- }
-
- // Its a local function, remove this
- if (funcName.indexOf(localPrefix) === 0) {
- funcName = funcName.slice(localPrefix.length);
- }
-
- // Register the function into the called registry
- if (funcParam.calledFunctions.indexOf(funcName) < 0) {
- funcParam.calledFunctions.push(funcName);
- }
- if (!funcParam.hasOwnProperty('funcName')) {
- funcParam.calledFunctionsArguments[funcName] = [];
- }
-
- var functionArguments = [];
- funcParam.calledFunctionsArguments[funcName].push(functionArguments);
-
- // Call the function
- retArr.push(funcName);
-
- // Open arguments space
- retArr.push('(');
-
- // Add the vars
- for (var i = 0; i < ast.arguments.length; ++i) {
- var argument = ast.arguments[i];
- if (i > 0) {
- retArr.push(', ');
- }
- this.astGeneric(argument, retArr, funcParam);
- if (argument.type === 'Identifier') {
- var paramIndex = funcParam.paramNames.indexOf(argument.name);
- if (paramIndex === -1) {
- functionArguments.push(null);
- } else {
- functionArguments.push({
- name: argument.name,
- type: funcParam.paramTypes[paramIndex]
- });
- }
- } else {
- functionArguments.push(null);
- }
- }
-
- // Close arguments space
- retArr.push(')');
-
- return retArr;
- }
-
- // Failure, unknown expression
- throw this.astErrorOutput('Unknown CallExpression', ast, funcParam);
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astArrayExpression
- *
- * @desc Parses the abstract syntax tree for *Array* Expression
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
-
- }, {
- key: 'astArrayExpression',
- value: function astArrayExpression(arrNode, retArr, funcParam) {
- var arrLen = arrNode.elements.length;
-
- retArr.push('float[' + arrLen + '](');
- for (var i = 0; i < arrLen; ++i) {
- if (i > 0) {
- retArr.push(', ');
- }
- var subNode = arrNode.elements[i];
- this.astGeneric(subNode, retArr, funcParam);
- }
- retArr.push(')');
-
- return retArr;
-
- // // Failure, unknown expression
- // throw this.astErrorOutput(
- // 'Unknown ArrayExpression',
- // arrNode, funcParam
- //);
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name getFunctionPrototypeString
- *
- * @desc Returns the converted webgl shader function equivalent of the JS function
- *
- * @returns {String} webgl function string, result is cached under this.getFunctionPrototypeString
- *
- */
-
- }, {
- key: 'getFunctionPrototypeString',
- value: function getFunctionPrototypeString() {
- if (this.webGlFunctionPrototypeString) {
- return this.webGlFunctionPrototypeString;
- }
- return this.webGlFunctionPrototypeString = this.generate();
- }
- }, {
- key: 'build',
- value: function build() {
- return this.getFunctionPrototypeString().length > 0;
- }
- }], [{
- key: 'astFunctionPrototype',
- value: function astFunctionPrototype(ast, retArr, funcParam) {
- // Setup function return type and name
- if (funcParam.isRootKernel || funcParam.isSubKernel) {
- return retArr;
- }
-
- retArr.push(funcParam.returnType);
- retArr.push(' ');
- retArr.push(funcParam.functionName);
- retArr.push('(');
-
- // Arguments handling
- for (var i = 0; i < funcParam.paramNames.length; ++i) {
- if (i > 0) {
- retArr.push(', ');
- }
-
- retArr.push(funcParam.paramTypes[i]);
- retArr.push(' ');
- retArr.push('user_');
- retArr.push(funcParam.paramNames[i]);
- }
-
- retArr.push(');\n');
-
- return retArr;
- }
- }]);
-
- return WebGLFunctionNode;
-}(FunctionNodeBase);
-
-function isIdentifierKernelParam(paramName, ast, funcParam) {
- return funcParam.paramNames.indexOf(paramName) !== -1;
-}
-
-function ensureIndentifierType(paramName, expectedType, ast, funcParam) {
- var start = ast.loc.start;
-
- if (!isIdentifierKernelParam(paramName, funcParam) && expectedType !== 'float') {
- throw 'Error unexpected identifier ' + paramName + ' on line ' + start.line;
- } else {
- var actualType = funcParam.paramTypes[funcParam.paramNames.indexOf(paramName)];
- if (actualType !== expectedType) {
- throw 'Error unexpected identifier ' + paramName + ' on line ' + start.line;
- }
- }
-}
-
-/**
- * @ignore
- * @function
- * @name webgl_regex_optimize
- *
- * @desc [INTERNAL] Takes the near final webgl function string, and do regex search and replacments.
- * For voodoo optimize out the following:
- *
- * - decode32(encode32(
- * - encode32(decode32(
- *
- * @param {String} inStr - The webGl function String
- *
- */
-function webGlRegexOptimize(inStr) {
- return inStr.replace(DECODE32_ENCODE32, '((').replace(ENCODE32_DECODE32, '((');
-}
\ No newline at end of file
diff --git a/dist/backend/web-gl/kernel-string.js b/dist/backend/web-gl/kernel-string.js
deleted file mode 100644
index fe1c2568..00000000
--- a/dist/backend/web-gl/kernel-string.js
+++ /dev/null
@@ -1,8 +0,0 @@
-'use strict';
-
-var utils = require('../../core/utils');
-var kernelRunShortcut = require('../kernel-run-shortcut');
-
-module.exports = function (gpuKernel, name) {
- return '() => {\n ' + kernelRunShortcut.toString() + ';\n const utils = {\n allPropertiesOf: function ' + utils.allPropertiesOf.toString() + ',\n clone: function ' + utils.clone.toString() + ',\n splitArray: function ' + utils.splitArray.toString() + ',\n getArgumentType: function ' + utils.getArgumentType.toString() + ',\n getDimensions: function ' + utils.getDimensions.toString() + ',\n dimToTexSize: function ' + utils.dimToTexSize.toString() + ',\n copyFlatten: function ' + utils.copyFlatten.toString() + ',\n flatten: function ' + utils.flatten.toString() + ',\n systemEndianness: \'' + utils.systemEndianness() + '\',\n initWebGl: function ' + utils.initWebGl.toString() + ',\n isArray: function ' + utils.isArray.toString() + '\n };\n class ' + (name || 'Kernel') + ' {\n constructor() {\n this.argumentsLength = 0;\n this._canvas = null;\n this._webGl = null;\n this.built = false;\n this.program = null;\n this.paramNames = ' + JSON.stringify(gpuKernel.paramNames) + ';\n this.paramTypes = ' + JSON.stringify(gpuKernel.paramTypes) + ';\n this.texSize = ' + JSON.stringify(gpuKernel.texSize) + ';\n this.output = ' + JSON.stringify(gpuKernel.output) + ';\n this.compiledFragShaderString = `' + gpuKernel.compiledFragShaderString + '`;\n\t\t this.compiledVertShaderString = `' + gpuKernel.compiledVertShaderString + '`;\n\t\t this.programUniformLocationCache = {};\n\t\t this.textureCache = {};\n\t\t this.subKernelOutputTextures = null;\n }\n ' + gpuKernel._getFragShaderString.toString() + '\n ' + gpuKernel._getVertShaderString.toString() + '\n validateOptions() {}\n setupParams() {}\n setCanvas(canvas) { this._canvas = canvas; return this; }\n setWebGl(webGl) { this._webGl = webGl; return this; }\n ' + gpuKernel.getUniformLocation.toString() + '\n ' + gpuKernel.setupParams.toString() + '\n ' + gpuKernel.build.toString() + '\n\t\t ' + gpuKernel.run.toString() + '\n\t\t ' + gpuKernel._addArgument.toString() + '\n\t\t ' + gpuKernel.getArgumentTexture.toString() + '\n\t\t ' + gpuKernel.getTextureCache.toString() + '\n\t\t ' + gpuKernel.getOutputTexture.toString() + '\n\t\t ' + gpuKernel.renderOutput.toString() + '\n };\n return kernelRunShortcut(new Kernel());\n };';
-};
\ No newline at end of file
diff --git a/dist/backend/web-gl/kernel.js b/dist/backend/web-gl/kernel.js
deleted file mode 100644
index c8c8112c..00000000
--- a/dist/backend/web-gl/kernel.js
+++ /dev/null
@@ -1,1267 +0,0 @@
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var fs = require('fs');
-var KernelBase = require('../kernel-base');
-var utils = require('../../core/utils');
-var Texture = require('../../core/texture');
-var fragShaderString = require('./shader-frag');
-var vertShaderString = require('./shader-vert');
-var kernelString = require('./kernel-string');
-var canvases = [];
-var maxTexSizes = {};
-module.exports = function (_KernelBase) {
- _inherits(WebGLKernel, _KernelBase);
-
- /**
- * @constructor WebGLKernel
- *
- * @desc Kernel Implementation for WebGL.
- * This builds the shaders and runs them on the GPU,
- * the outputs the result back as float(enabled by default) and Texture.
- *
- * @extends KernelBase
- *
- * @prop {Object} textureCache - webGl Texture cache
- * @prop {Object} threadDim - The thread dimensions, x, y and z
- * @prop {Object} programUniformLocationCache - Location of program variables in memory
- * @prop {Object} framebuffer - Webgl frameBuffer
- * @prop {Object} buffer - WebGL buffer
- * @prop {Object} program - The webGl Program
- * @prop {Object} functionBuilder - Function Builder instance bound to this Kernel
- * @prop {Boolean} outputToTexture - Set output type to Texture, instead of float
- * @prop {String} endianness - Endian information like Little-endian, Big-endian.
- * @prop {Array} paramTypes - Types of parameters sent to the Kernel
- * @prop {number} argumentsLength - Number of parameters sent to the Kernel
- * @prop {String} compiledFragShaderString - Compiled fragment shader string
- * @prop {String} compiledVertShaderString - Compiled Vertical shader string
- */
- function WebGLKernel(fnString, settings) {
- _classCallCheck(this, WebGLKernel);
-
- var _this = _possibleConstructorReturn(this, (WebGLKernel.__proto__ || Object.getPrototypeOf(WebGLKernel)).call(this, fnString, settings));
-
- _this.textureCache = {};
- _this.threadDim = {};
- _this.programUniformLocationCache = {};
- _this.framebuffer = null;
-
- _this.buffer = null;
- _this.program = null;
- _this.outputToTexture = settings.outputToTexture;
- _this.endianness = utils.systemEndianness();
- _this.subKernelOutputTextures = null;
- _this.subKernelOutputVariableNames = null;
- _this.argumentsLength = 0;
- _this.ext = null;
- _this.compiledFragShaderString = null;
- _this.compiledVertShaderString = null;
- _this.extDrawBuffersMap = null;
- _this.outputTexture = null;
- _this.maxTexSize = null;
- if (!_this._webGl) _this._webGl = utils.initWebGl(_this.getCanvas());
- return _this;
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name validateOptions
- *
- * @desc Validate options related to Kernel, such as
- * floatOutputs and Textures, texSize, output,
- * graphical output.
- *
- */
-
-
- _createClass(WebGLKernel, [{
- key: 'validateOptions',
- value: function validateOptions() {
- var isReadPixel = utils.isFloatReadPixelsSupported();
- if (this.floatTextures === true && !utils.OES_texture_float) {
- throw 'Float textures are not supported on this browser';
- } else if (this.floatOutput === true && this.floatOutputForce !== true && !isReadPixel) {
- throw 'Float texture outputs are not supported on this browser';
- } else if (this.floatTextures === null && !isReadPixel && !this.graphical) {
- //NOTE: handle
- this.floatTextures = true;
- this.floatOutput = false;
- }
-
- if (!this.output || this.output.length === 0) {
- if (arguments.length !== 1) {
- throw 'Auto output only supported for kernels with only one input';
- }
-
- var argType = utils.getArgumentType(arguments[0]);
- if (argType === 'Array') {
- this.output = utils.getDimensions(argType);
- } else if (argType === 'Texture') {
- this.output = arguments[0].output;
- } else {
- throw 'Auto output not supported for input type: ' + argType;
- }
- }
-
- this.texSize = utils.dimToTexSize({
- floatTextures: this.floatTextures,
- floatOutput: this.floatOutput
- }, this.output, true);
-
- if (this.graphical) {
- if (this.output.length !== 2) {
- throw 'Output must have 2 dimensions on graphical mode';
- }
-
- if (this.floatOutput) {
- throw 'Cannot use graphical mode and float output at the same time';
- }
-
- this.texSize = utils.clone(this.output);
- } else if (this.floatOutput === undefined && utils.OES_texture_float) {
- this.floatOutput = true;
- }
- }
- }, {
- key: 'updateMaxTexSize',
- value: function updateMaxTexSize() {
- var texSize = this.texSize;
- var canvas = this._canvas;
- if (this.maxTexSize === null) {
- var canvasIndex = canvases.indexOf(canvas);
- if (canvasIndex === -1) {
- canvasIndex = canvases.length;
- canvases.push(canvas);
- maxTexSizes[canvasIndex] = [texSize[0], texSize[1]];
- }
- this.maxTexSize = maxTexSizes[canvasIndex];
- }
- if (this.maxTexSize[0] < texSize[0]) {
- this.maxTexSize[0] = texSize[0];
- }
- if (this.maxTexSize[1] < texSize[1]) {
- this.maxTexSize[1] = texSize[1];
- }
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name build
- *
- * @desc Builds the Kernel, by compiling Fragment and Vertical Shaders,
- * and instantiates the program.
- *
- */
-
- }, {
- key: 'build',
- value: function build() {
- this.validateOptions();
- this.setupParams(arguments);
- this.updateMaxTexSize();
- var texSize = this.texSize;
- var gl = this._webGl;
- var canvas = this._canvas;
- gl.enable(gl.SCISSOR_TEST);
- gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);
- canvas.width = this.maxTexSize[0];
- canvas.height = this.maxTexSize[1];
- var threadDim = this.threadDim = utils.clone(this.output);
- while (threadDim.length < 3) {
- threadDim.push(1);
- }
-
- if (this.functionBuilder) this._addKernels();
-
- var compiledVertShaderString = this._getVertShaderString(arguments);
- var vertShader = gl.createShader(gl.VERTEX_SHADER);
- gl.shaderSource(vertShader, compiledVertShaderString);
- gl.compileShader(vertShader);
-
- var compiledFragShaderString = this._getFragShaderString(arguments);
- var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
- gl.shaderSource(fragShader, compiledFragShaderString);
- gl.compileShader(fragShader);
-
- if (!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) {
- console.log(compiledVertShaderString);
- console.error('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(vertShader));
- throw 'Error compiling vertex shader';
- }
- if (!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) {
- console.log(compiledFragShaderString);
- console.error('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(fragShader));
- throw 'Error compiling fragment shader';
- }
-
- if (this.debug) {
- console.log('Options:');
- console.dir(this);
- console.log('GLSL Shader Output:');
- console.log(compiledFragShaderString);
- }
-
- var program = this.program = gl.createProgram();
- gl.attachShader(program, vertShader);
- gl.attachShader(program, fragShader);
- gl.linkProgram(program);
- this.framebuffer = gl.createFramebuffer();
- this.framebuffer.width = texSize[0];
- this.framebuffer.height = texSize[1];
-
- var vertices = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
- var texCoords = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);
-
- var texCoordOffset = vertices.byteLength;
-
- var buffer = this.buffer;
- if (!buffer) {
- buffer = this.buffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
- gl.bufferData(gl.ARRAY_BUFFER, vertices.byteLength + texCoords.byteLength, gl.STATIC_DRAW);
- } else {
- gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
- }
-
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices);
- gl.bufferSubData(gl.ARRAY_BUFFER, texCoordOffset, texCoords);
-
- var aPosLoc = gl.getAttribLocation(this.program, 'aPos');
- gl.enableVertexAttribArray(aPosLoc);
- gl.vertexAttribPointer(aPosLoc, 2, gl.FLOAT, gl.FALSE, 0, 0);
- var aTexCoordLoc = gl.getAttribLocation(this.program, 'aTexCoord');
- gl.enableVertexAttribArray(aTexCoordLoc);
- gl.vertexAttribPointer(aTexCoordLoc, 2, gl.FLOAT, gl.FALSE, 0, texCoordOffset);
-
- this.setupOutputTexture();
-
- if (this.subKernelOutputTextures !== null) {
- var extDrawBuffersMap = this.extDrawBuffersMap = [gl.COLOR_ATTACHMENT0];
- for (var i = 0; i < this.subKernelOutputTextures.length; i++) {
- var subKernelOutputTexture = this.subKernelOutputTextures[i];
- extDrawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1);
- gl.activeTexture(gl.TEXTURE0 + arguments.length + i);
- gl.bindTexture(gl.TEXTURE_2D, subKernelOutputTexture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
- if (this.floatOutput) {
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);
- } else {
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
- }
- }
- }
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name run
- *
- * @desc Run the kernel program, and send the output to renderOutput
- *
- * This method calls a helper method *renderOutput* to return the result.
- *
- * @returns {Object} Result The final output of the program, as float, and as Textures for reuse.
- *
- *
- */
-
- }, {
- key: 'run',
- value: function run() {
- if (this.program === null) {
- this.build.apply(this, arguments);
- }
- var paramNames = this.paramNames;
- var paramTypes = this.paramTypes;
- var texSize = this.texSize;
- var gl = this._webGl;
-
- gl.useProgram(this.program);
- gl.scissor(0, 0, texSize[0], texSize[1]);
-
- if (!this.hardcodeConstants) {
- var uOutputDimLoc = this.getUniformLocation('uOutputDim');
- gl.uniform3fv(uOutputDimLoc, this.threadDim);
- var uTexSizeLoc = this.getUniformLocation('uTexSize');
- gl.uniform2fv(uTexSizeLoc, texSize);
- }
-
- var ratioLoc = this.getUniformLocation('ratio');
- gl.uniform2f(ratioLoc, texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]);
-
- this.argumentsLength = 0;
- for (var texIndex = 0; texIndex < paramNames.length; texIndex++) {
- this._addArgument(arguments[texIndex], paramTypes[texIndex], paramNames[texIndex]);
- }
-
- if (this.graphical) {
- gl.bindRenderbuffer(gl.RENDERBUFFER, null);
- gl.bindFramebuffer(gl.FRAMEBUFFER, null);
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
- return;
- }
-
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
- //the call to this._addArgument may rewrite the outputTexture, keep this here
- var outputTexture = this.outputTexture;
- gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, outputTexture, 0);
-
- if (this.subKernelOutputTextures !== null) {
- for (var i = 0; i < this.subKernelOutputTextures.length; i++) {
- var subKernelOutputTexture = this.subKernelOutputTextures[i];
- gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, subKernelOutputTexture, 0);
- }
- this.ext.drawBuffersWEBGL(this.extDrawBuffersMap);
- }
-
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
-
- if (this.subKernelOutputTextures !== null) {
- if (this.subKernels !== null) {
- var output = [];
- output.result = this.renderOutput(outputTexture);
- for (var _i = 0; _i < this.subKernels.length; _i++) {
- output.push(new Texture(this.subKernelOutputTextures[_i], texSize, this.output, this._webGl));
- }
- return output;
- } else if (this.subKernelProperties !== null) {
- var _output = {
- result: this.renderOutput(outputTexture)
- };
- var _i2 = 0;
- for (var p in this.subKernelProperties) {
- if (!this.subKernelProperties.hasOwnProperty(p)) continue;
- _output[p] = new Texture(this.subKernelOutputTextures[_i2], texSize, this.output, this._webGl);
- _i2++;
- }
- return _output;
- }
- }
-
- return this.renderOutput(outputTexture);
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name renderOutput
- *
- *
- * @desc Helper function to return webGl function's output.
- * Since the program runs on GPU, we need to get the
- * output of the program back to CPU and then return them.
- *
- * *Note*: This should not be called directly.
- *
- * @param {Object} outputTexture - Output Texture returned by webGl program
- *
- * @returns {Object|Array} result
- *
- *
- */
-
- }, {
- key: 'renderOutput',
- value: function renderOutput(outputTexture) {
- var texSize = this.texSize;
- var gl = this._webGl;
- var threadDim = this.threadDim;
- var output = this.output;
- if (this.outputToTexture) {
- return new Texture(outputTexture, texSize, output, this._webGl);
- } else {
- var result = void 0;
- if (this.floatOutput) {
- result = new Float32Array(texSize[0] * texSize[1] * 4);
- gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.FLOAT, result);
- } else {
- var bytes = new Uint8Array(texSize[0] * texSize[1] * 4);
- gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, bytes);
- result = new Float32Array(bytes.buffer);
- }
-
- result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]);
-
- if (output.length === 1) {
- return result;
- } else if (output.length === 2) {
- return utils.splitArray(result, output[0]);
- } else if (output.length === 3) {
- var cube = utils.splitArray(result, output[0] * output[1]);
- return cube.map(function (x) {
- return utils.splitArray(x, output[0]);
- });
- }
- }
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name getOutputTexture
- *
- * @desc This uses *getTextureCache* to get the Texture Cache of the Output
- *
- * @returns {Object} Ouptut Texture Cache
- *
- */
-
- }, {
- key: 'getOutputTexture',
- value: function getOutputTexture() {
- return this.getTextureCache('OUTPUT');
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name detachOutputTexture
- *
- * @desc Detaches output texture
- *
- *
- */
-
- }, {
- key: 'detachOutputTexture',
- value: function detachOutputTexture() {
- this.detachTextureCache('OUTPUT');
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name setupOutputTexture
- *
- * @desc Detaches a texture from cache if exists, and sets up output texture
- */
-
- }, {
- key: 'setupOutputTexture',
- value: function setupOutputTexture() {
- var gl = this._webGl;
- var texSize = this.texSize;
- this.detachOutputTexture();
- this.outputTexture = this.getOutputTexture();
- gl.activeTexture(gl.TEXTURE0 + this.paramNames.length);
- gl.bindTexture(gl.TEXTURE_2D, this.outputTexture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
- if (this.floatOutput) {
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);
- } else {
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
- }
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name getArgumentTexture
- *
- * @desc This uses *getTextureCache** to get the Texture Cache of the argument supplied
- *
- * @param {String} name - Name of the argument
- *
- * Texture cache for the supplied argument
- *
- */
-
- }, {
- key: 'getArgumentTexture',
- value: function getArgumentTexture(name) {
- return this.getTextureCache('ARGUMENT_' + name);
- }
-
- /**
- * @memberOf WebGLKernel#
- * @name getSubKernelTexture
- * @function
- *
- * @desc This uses *getTextureCache* to get the Texture Cache of the sub-kernel
- *
- * @param {String} name - Name of the subKernel
- *
- * @returns {Object} Texture cache for the subKernel
- *
- */
-
- }, {
- key: 'getSubKernelTexture',
- value: function getSubKernelTexture(name) {
- return this.getTextureCache('SUB_KERNEL_' + name);
- }
-
- /**
- * @memberOf WebGLKernel#
- * @name getTextureCache
- * @function
- *
- * @desc Returns the Texture Cache of the supplied parameter (can be kernel, sub-kernel or argument)
- *
- * @param {String} name - Name of the subkernel, argument, or kernel.
- *
- * @returns {Object} Texture cache
- *
- */
-
- }, {
- key: 'getTextureCache',
- value: function getTextureCache(name) {
- if (this.outputToTexture) {
- // Don't retain a handle on the output texture, we might need to render on the same texture later
- return this._webGl.createTexture();
- }
- if (this.textureCache.hasOwnProperty(name)) {
- return this.textureCache[name];
- }
- return this.textureCache[name] = this._webGl.createTexture();
- }
-
- /**
- * @memberOf WebGLKernel#
- * @name detachTextureCache
- * @function
- * @desc removes a texture from the kernel's cache
- * @param {String} name - Name of texture
- */
-
- }, {
- key: 'detachTextureCache',
- value: function detachTextureCache(name) {
- delete this.textureCache[name];
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name getUniformLocation
- *
- * @desc Return WebGlUniformLocation for various variables
- * related to webGl program, such as user-defiend variables,
- * as well as, dimension sizes, etc.
- *
- */
-
- }, {
- key: 'getUniformLocation',
- value: function getUniformLocation(name) {
- var location = this.programUniformLocationCache[name];
- if (!location) {
- location = this._webGl.getUniformLocation(this.program, name);
- this.programUniformLocationCache[name] = location;
- }
- return location;
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getFragShaderArtifactMap
- *
- * @desc Generate Shader artifacts for the kernel program.
- * The final object contains HEADER, KERNEL, MAIN_RESULT, and others.
- *
- * @param {Array} args - The actual parameters sent to the Kernel
- *
- * @returns {Object} An object containing the Shader Artifacts(CONSTANTS, HEADER, KERNEL, etc.)
- *
- */
-
- }, {
- key: '_getFragShaderArtifactMap',
- value: function _getFragShaderArtifactMap(args) {
- return {
- HEADER: this._getHeaderString(),
- LOOP_MAX: this._getLoopMaxString(),
- CONSTANTS: this._getConstantsString(),
- DECODE32_ENDIANNESS: this._getDecode32EndiannessString(),
- ENCODE32_ENDIANNESS: this._getEncode32EndiannessString(),
- GET_WRAPAROUND: this._getGetWraparoundString(),
- GET_TEXTURE_CHANNEL: this._getGetTextureChannelString(),
- GET_TEXTURE_INDEX: this._getGetTextureIndexString(),
- GET_RESULT: this._getGetResultString(),
- MAIN_PARAMS: this._getMainParamsString(args),
- MAIN_CONSTANTS: this._getMainConstantsString(),
- KERNEL: this._getKernelString(),
- MAIN_RESULT: this._getMainResultString()
- };
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _addArgument
- *
- * @desc Adds kernel parameters to the Argument Texture,
- * binding it to the webGl instance, etc.
- *
- * @param {Array|Texture|Number} value - The actual argument supplied to the kernel
- * @param {String} type - Type of the argument
- * @param {String} name - Name of the argument
- *
- */
-
- }, {
- key: '_addArgument',
- value: function _addArgument(value, type, name) {
- var gl = this._webGl;
- var argumentTexture = this.getArgumentTexture(name);
- if (value instanceof Texture) {
- type = 'Texture';
- }
- switch (type) {
- case 'Array':
- {
- var dim = utils.getDimensions(value, true);
- var size = utils.dimToTexSize({
- floatTextures: this.floatTextures,
- floatOutput: this.floatOutput
- }, dim);
- gl.activeTexture(gl.TEXTURE0 + this.argumentsLength);
- gl.bindTexture(gl.TEXTURE_2D, argumentTexture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
-
- var length = size[0] * size[1];
- if (this.floatTextures) {
- length *= 4;
- }
-
- var valuesFlat = new Float32Array(length);
- utils.flattenTo(value, valuesFlat);
-
- var buffer = void 0;
- if (this.floatTextures) {
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size[0], size[1], 0, gl.RGBA, gl.FLOAT, valuesFlat);
- } else {
- buffer = new Uint8Array(valuesFlat.buffer);
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size[0], size[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, buffer);
- }
-
- var loc = this.getUniformLocation('user_' + name);
- var locSize = this.getUniformLocation('user_' + name + 'Size');
- var dimLoc = this.getUniformLocation('user_' + name + 'Dim');
-
- if (!this.hardcodeConstants) {
- gl.uniform3fv(dimLoc, dim);
- gl.uniform2fv(locSize, size);
- }
- gl.uniform1i(loc, this.argumentsLength);
- break;
- }
- case 'Number':
- {
- var _loc = this.getUniformLocation('user_' + name);
- gl.uniform1f(_loc, value);
- break;
- }
- case 'Input':
- {
- var input = value;
- var _dim = input.size;
- var _size = utils.dimToTexSize({
- floatTextures: this.floatTextures,
- floatOutput: this.floatOutput
- }, _dim);
- gl.activeTexture(gl.TEXTURE0 + this.argumentsLength);
- gl.bindTexture(gl.TEXTURE_2D, argumentTexture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
-
- var _length = _size[0] * _size[1];
- var inputArray = void 0;
- if (this.floatTextures) {
- _length *= 4;
- inputArray = new Float32Array(_length);
- inputArray.set(input.value);
- } else {
- inputArray = input.value;
- }
-
- if (this.floatTextures) {
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, _size[0], _size[1], 0, gl.RGBA, gl.FLOAT, inputArray);
- } else {
- var _buffer = new Uint8Array(inputArray.buffer);
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, _size[0], _size[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, _buffer);
- }
-
- var _loc2 = this.getUniformLocation('user_' + name);
- var _locSize = this.getUniformLocation('user_' + name + 'Size');
- var _dimLoc = this.getUniformLocation('user_' + name + 'Dim');
-
- if (!this.hardcodeConstants) {
- gl.uniform3fv(_dimLoc, _dim);
- gl.uniform2fv(_locSize, _size);
- }
- gl.uniform1i(_loc2, this.argumentsLength);
- break;
- }
- case 'Texture':
- {
- var inputTexture = value;
- var _dim2 = utils.getDimensions(inputTexture, true);
-
- var _size2 = inputTexture.size;
-
- if (inputTexture.texture === this.outputTexture) {
- this.setupOutputTexture();
- }
-
- gl.activeTexture(gl.TEXTURE0 + this.argumentsLength);
- gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture);
-
- var _loc3 = this.getUniformLocation('user_' + name);
- var _locSize2 = this.getUniformLocation('user_' + name + 'Size');
- var _dimLoc2 = this.getUniformLocation('user_' + name + 'Dim');
-
- gl.uniform3fv(_dimLoc2, _dim2);
- gl.uniform2fv(_locSize2, _size2);
- gl.uniform1i(_loc3, this.argumentsLength);
- break;
- }
- default:
- throw 'Input type not supported (WebGL): ' + value;
- }
- this.argumentsLength++;
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getHeaderString
- *
- * @desc Get the header string for the program.
- * This returns an empty string if no sub-kernels are defined.
- *
- * @returns {String} result
- *
- */
-
- }, {
- key: '_getHeaderString',
- value: function _getHeaderString() {
- return this.subKernels !== null || this.subKernelProperties !== null ?
- //webgl2 '#version 300 es\n' :
- '#extension GL_EXT_draw_buffers : require\n' : '';
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getLoopMaxString
- *
- * @desc Get the maximum loop size String.
- *
- * @returns {String} result
- *
- */
-
- }, {
- key: '_getLoopMaxString',
- value: function _getLoopMaxString() {
- return this.loopMaxIterations ? ' ' + parseInt(this.loopMaxIterations) + '.0;\n' : ' 1000.0;\n';
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getConstantsString
- *
- * @desc Generate transpiled glsl Strings for constant parameters sent to a kernel
- *
- * They can be defined by *hardcodeConstants*
- *
- * @returns {String} result
- *
- */
-
- }, {
- key: '_getConstantsString',
- value: function _getConstantsString() {
- var result = [];
- var threadDim = this.threadDim;
- var texSize = this.texSize;
- if (this.hardcodeConstants) {
- result.push('highp vec3 uOutputDim = vec3(' + threadDim[0] + ',' + threadDim[1] + ', ' + threadDim[2] + ')', 'highp vec2 uTexSize = vec2(' + texSize[0] + ', ' + texSize[1] + ')');
- } else {
- result.push('uniform highp vec3 uOutputDim', 'uniform highp vec2 uTexSize');
- }
-
- return this._linesToString(result);
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getTextureCoordinate
- *
- * @desc Get texture coordinate string for the program
- *
- * @returns {String} result
- *
- */
-
- }, {
- key: '_getTextureCoordinate',
- value: function _getTextureCoordinate() {
- var names = this.subKernelOutputVariableNames;
- if (names === null || names.length < 1) {
- return 'varying highp vec2 vTexCoord;\n';
- } else {
- return 'out highp vec2 vTexCoord;\n';
- }
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getDecode32EndiannessString
- *
- * @desc Get Decode32 endianness string for little-endian and big-endian
- *
- * @returns {String} result
- *
- */
-
- }, {
- key: '_getDecode32EndiannessString',
- value: function _getDecode32EndiannessString() {
- return this.endianness === 'LE' ? '' : ' rgba.rgba = rgba.abgr;\n';
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getEncode32EndiannessString
- *
- * @desc Get Encode32 endianness string for little-endian and big-endian
- *
- * @returns {String} result
- *
- */
-
- }, {
- key: '_getEncode32EndiannessString',
- value: function _getEncode32EndiannessString() {
- return this.endianness === 'LE' ? '' : ' rgba.rgba = rgba.abgr;\n';
- }
-
- /**
- * @function
- * @memberOf WebGLKernel#
- * @name _getGetWraparoundString
- *
- * @returns {String} wraparound string
- */
-
- }, {
- key: '_getGetWraparoundString',
- value: function _getGetWraparoundString() {
- return this.wraparound ? ' xyz = mod(xyz, texDim);\n' : '';
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getGetTextureChannelString
- *
- */
-
- }, {
- key: '_getGetTextureChannelString',
- value: function _getGetTextureChannelString() {
- if (!this.floatTextures) return '';
-
- return this._linesToString([' int channel = int(integerMod(index, 4.0))', ' index = float(int(index) / 4)']);
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getGetTextureIndexString
- *
- * @desc Get generic texture index string, if floatTextures flag is true.
- *
- * @example
- * ' index = float(int(index)/4);\n'
- *
- */
-
- }, {
- key: '_getGetTextureIndexString',
- value: function _getGetTextureIndexString() {
- return this.floatTextures ? ' index = float(int(index)/4);\n' : '';
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getGetResultString
- *
- */
-
- }, {
- key: '_getGetResultString',
- value: function _getGetResultString() {
- if (!this.floatTextures) return ' return decode32(texel);\n';
- return this._linesToString([' if (channel == 0) return texel.r', ' if (channel == 1) return texel.g', ' if (channel == 2) return texel.b', ' if (channel == 3) return texel.a']);
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getMainParamsString
- *
- * @desc Generate transpiled glsl Strings for user-defined parameters sent to a kernel
- *
- * @param {Array} args - The actual parameters sent to the Kernel
- *
- * @returns {String} result
- *
- */
-
- }, {
- key: '_getMainParamsString',
- value: function _getMainParamsString(args) {
- var result = [];
- var paramTypes = this.paramTypes;
- var paramNames = this.paramNames;
- for (var i = 0; i < paramNames.length; i++) {
- var param = args[i];
- var paramName = paramNames[i];
- var paramType = paramTypes[i];
- if (this.hardcodeConstants) {
- if (paramType === 'Array' || paramType === 'Texture') {
- var paramDim = utils.getDimensions(param, true);
- var paramSize = utils.dimToTexSize({
- floatTextures: this.floatTextures,
- floatOutput: this.floatOutput
- }, paramDim);
-
- result.push('uniform highp sampler2D user_' + paramName, 'highp vec2 user_' + paramName + 'Size = vec2(' + paramSize[0] + '.0, ' + paramSize[1] + '.0)', 'highp vec3 user_' + paramName + 'Dim = vec3(' + paramDim[0] + '.0, ' + paramDim[1] + '.0, ' + paramDim[2] + '.0)');
- } else if (paramType === 'Number' && Number.isInteger(param)) {
- result.push('highp float user_' + paramName + ' = ' + param + '.0');
- } else if (paramType === 'Number') {
- result.push('highp float user_' + paramName + ' = ' + param);
- }
- } else {
- if (paramType === 'Array' || paramType === 'Texture' || paramType === 'Input') {
- result.push('uniform highp sampler2D user_' + paramName, 'uniform highp vec2 user_' + paramName + 'Size', 'uniform highp vec3 user_' + paramName + 'Dim');
- } else if (paramType === 'Number') {
- result.push('uniform highp float user_' + paramName);
- }
- }
- }
- return this._linesToString(result);
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getMainConstantsString
- *
- */
-
- }, {
- key: '_getMainConstantsString',
- value: function _getMainConstantsString() {
- var result = [];
- if (this.constants) {
- for (var name in this.constants) {
- if (!this.constants.hasOwnProperty(name)) continue;
- var value = parseFloat(this.constants[name]);
-
- if (Number.isInteger(value)) {
- result.push('const float constants_' + name + ' = ' + parseInt(value) + '.0');
- } else {
- result.push('const float constants_' + name + ' = ' + parseFloat(value));
- }
- }
- }
- return this._linesToString(result);
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getKernelString
- *
- * @desc Get Kernel program string (in *glsl*) for a kernel.
- *
- * @returns {String} result
- *
- */
-
- }, {
- key: '_getKernelString',
- value: function _getKernelString() {
- var result = [];
- var names = this.subKernelOutputVariableNames;
- if (names !== null) {
- result.push('highp float kernelResult = 0.0');
- for (var i = 0; i < names.length; i++) {
- result.push('highp float ' + names[i] + ' = 0.0');
- }
-
- /* this is v2 prep
- result.push('highp float kernelResult = 0.0');
- result.push('layout(location = 0) out highp float fradData0 = 0.0');
- for (let i = 0; i < names.length; i++) {
- result.push(
- `highp float ${ names[i] } = 0.0`,
- `layout(location = ${ i + 1 }) out highp float fragData${ i + 1 } = 0.0`
- );
- }*/
- } else {
- result.push('highp float kernelResult = 0.0');
- }
-
- return this._linesToString(result) + this.functionBuilder.getPrototypeString('kernel');
- }
-
- /**
- *
- * @memberOf WebGLKernel#
- * @function
- * @name _getMainResultString
- *
- * @desc Get main result string with checks for floatOutput, graphical, subKernelsOutputs, etc.
- *
- * @returns {String} result
- *
- */
-
- }, {
- key: '_getMainResultString',
- value: function _getMainResultString() {
- var names = this.subKernelOutputVariableNames;
- var result = [];
- if (this.floatOutput) {
- result.push(' index *= 4.0');
- }
-
- if (this.graphical) {
- result.push(' threadId = indexTo3D(index, uOutputDim)', ' kernel()', ' gl_FragColor = actualColor');
- } else if (this.floatOutput) {
- result.push(' threadId = indexTo3D(index, uOutputDim)', ' kernel()', ' gl_FragColor.r = kernelResult', ' index += 1.0', ' threadId = indexTo3D(index, uOutputDim)', ' kernel()', ' gl_FragColor.g = kernelResult', ' index += 1.0', ' threadId = indexTo3D(index, uOutputDim)', ' kernel()', ' gl_FragColor.b = kernelResult', ' index += 1.0', ' threadId = indexTo3D(index, uOutputDim)', ' kernel()', ' gl_FragColor.a = kernelResult');
- } else if (names !== null) {
- result.push(' threadId = indexTo3D(index, uOutputDim)');
- result.push(' kernel()');
- result.push(' gl_FragData[0] = encode32(kernelResult)');
- for (var i = 0; i < names.length; i++) {
- result.push(' gl_FragData[' + (i + 1) + '] = encode32(' + names[i] + ')');
- }
- /* this is v2 prep
- * result.push(' kernel()');
- result.push(' fragData0 = encode32(kernelResult)');
- for (let i = 0; i < names.length; i++) {
- result.push(` fragData${ i + 1 } = encode32(${ names[i] })`);
- }*/
- } else {
- result.push(' threadId = indexTo3D(index, uOutputDim)', ' kernel()', ' gl_FragColor = encode32(kernelResult)');
- }
-
- return this._linesToString(result);
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _linesToString
- *
- * @param {Array} lines - An Array of strings
- *
- * @returns {String} Single combined String, seperated by *\n*
- *
- */
-
- }, {
- key: '_linesToString',
- value: function _linesToString(lines) {
- if (lines.length > 0) {
- return lines.join(';\n') + ';\n';
- } else {
- return '\n';
- }
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _replaceArtifacts
- *
- * @param {String} src - Shader string
- * @param {Array} map - Variables/Constants associated with shader
- *
- */
-
- }, {
- key: '_replaceArtifacts',
- value: function _replaceArtifacts(src, map) {
- return src.replace(/[ ]*__([A-Z]+[0-9]*([_]?[A-Z])*)__;\n/g, function (match, artifact) {
- if (map.hasOwnProperty(artifact)) {
- return map[artifact];
- }
- throw 'unhandled artifact ' + artifact;
- });
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _addKernels
- *
- * @desc Adds all the sub-kernels supplied with this Kernel instance.
- *
- */
-
- }, {
- key: '_addKernels',
- value: function _addKernels() {
- var builder = this.functionBuilder;
- var gl = this._webGl;
-
- builder.addFunctions(this.functions, {
- constants: this.constants,
- output: this.output
- });
- builder.addNativeFunctions(this.nativeFunctions);
-
- builder.addKernel(this.fnString, {
- prototypeOnly: false,
- constants: this.constants,
- output: this.output,
- debug: this.debug,
- loopMaxIterations: this.loopMaxIterations
- }, this.paramNames, this.paramTypes);
-
- if (this.subKernels !== null) {
- var ext = this.ext = gl.getExtension('WEBGL_draw_buffers');
- if (!ext) throw new Error('could not instantiate draw buffers extension');
- this.subKernelOutputTextures = [];
- this.subKernelOutputVariableNames = [];
- for (var i = 0; i < this.subKernels.length; i++) {
- var subKernel = this.subKernels[i];
- builder.addSubKernel(subKernel, {
- prototypeOnly: false,
- constants: this.constants,
- output: this.output,
- debug: this.debug,
- loopMaxIterations: this.loopMaxIterations
- });
- this.subKernelOutputTextures.push(this.getSubKernelTexture(i));
- this.subKernelOutputVariableNames.push(subKernel.name + 'Result');
- }
- } else if (this.subKernelProperties !== null) {
- var _ext = this.ext = gl.getExtension('WEBGL_draw_buffers');
- if (!_ext) throw new Error('could not instantiate draw buffers extension');
- this.subKernelOutputTextures = [];
- this.subKernelOutputVariableNames = [];
- var _i3 = 0;
- for (var p in this.subKernelProperties) {
- if (!this.subKernelProperties.hasOwnProperty(p)) continue;
- var _subKernel = this.subKernelProperties[p];
- builder.addSubKernel(_subKernel, {
- prototypeOnly: false,
- constants: this.constants,
- output: this.output,
- debug: this.debug,
- loopMaxIterations: this.loopMaxIterations
- });
- this.subKernelOutputTextures.push(this.getSubKernelTexture(p));
- this.subKernelOutputVariableNames.push(_subKernel.name + 'Result');
- _i3++;
- }
- }
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getFragShaderString
- *
- * @desc Get the fragment shader String.
- * If the String hasn't been compiled yet,
- * then this method compiles it as well
- *
- * @param {Array} args - The actual parameters sent to the Kernel
- *
- * @returns {String} Fragment Shader string
- *
- */
-
- }, {
- key: '_getFragShaderString',
- value: function _getFragShaderString(args) {
- if (this.compiledFragShaderString !== null) {
- return this.compiledFragShaderString;
- }
- return this.compiledFragShaderString = this._replaceArtifacts(fragShaderString, this._getFragShaderArtifactMap(args));
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getVertShaderString
- *
- * @desc Get the vertical shader String
- *
- * @param {Array} args - The actual parameters sent to the Kernel
- *
- * @returns {String} Vertical Shader string
- *
- */
-
- }, {
- key: '_getVertShaderString',
- value: function _getVertShaderString(args) {
- if (this.compiledVertShaderString !== null) {
- return this.compiledVertShaderString;
- }
- //TODO: webgl2 compile like frag shader
- return this.compiledVertShaderString = vertShaderString;
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name toString
- *
- * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused.
- *
- */
-
- }, {
- key: 'toString',
- value: function toString() {
- return kernelString(this);
- }
- }, {
- key: 'addFunction',
- value: function addFunction(fn) {
- this.functionBuilder.addFunction(null, fn);
- }
- }]);
-
- return WebGLKernel;
-}(KernelBase);
\ No newline at end of file
diff --git a/dist/backend/web-gl/runner.js b/dist/backend/web-gl/runner.js
deleted file mode 100644
index 127ae551..00000000
--- a/dist/backend/web-gl/runner.js
+++ /dev/null
@@ -1,58 +0,0 @@
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var RunnerBase = require('../runner-base');
-var WebGLKernel = require('./kernel');
-var utils = require('../../core/utils');
-var WebGLFunctionBuilder = require('./function-builder');
-
-module.exports = function (_RunnerBase) {
- _inherits(WebGLRunner, _RunnerBase);
-
- /**
- * @constructor WebGLRunner
- *
- * @extends RunnerBase
- * @desc Instantiates a Runner instance for the kernel.
- *
- * @param {Object} settings - Settings to instantiate properties in RunnerBase, with given values
- *
- */
- function WebGLRunner(settings) {
- _classCallCheck(this, WebGLRunner);
-
- var _this = _possibleConstructorReturn(this, (WebGLRunner.__proto__ || Object.getPrototypeOf(WebGLRunner)).call(this, new WebGLFunctionBuilder(), settings));
-
- _this.Kernel = WebGLKernel;
- _this.kernel = null;
- return _this;
- }
-
- /**
- * @memberOf WebGLRunner#
- * @function
- * @name getMode
- *
- * @desc Return the current mode in which gpu.js is executing.
- *
- * @returns {String} The current mode; "cpu".
- *
- */
-
-
- _createClass(WebGLRunner, [{
- key: 'getMode',
- value: function getMode() {
- return 'gpu';
- }
- }]);
-
- return WebGLRunner;
-}(RunnerBase);
\ No newline at end of file
diff --git a/dist/backend/web-gl/shader-frag.js b/dist/backend/web-gl/shader-frag.js
deleted file mode 100644
index 8f22dc2b..00000000
--- a/dist/backend/web-gl/shader-frag.js
+++ /dev/null
@@ -1,3 +0,0 @@
-"use strict";
-
-module.exports = "__HEADER__;\nprecision highp float;\nprecision highp int;\nprecision highp sampler2D;\n\nconst float LOOP_MAX = __LOOP_MAX__;\n#define EPSILON 0.0000001;\n\n__CONSTANTS__;\n\nvarying highp vec2 vTexCoord;\n\nvec4 round(vec4 x) {\n return floor(x + 0.5);\n}\n\nhighp float round(highp float x) {\n return floor(x + 0.5);\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\nhighp float integerMod(highp float x, highp float y) {\n highp float res = floor(mod(x, y));\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nhighp int integerMod(highp int x, highp int y) {\n return int(integerMod(float(x), float(y)));\n}\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\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\nhighp float decode32(highp vec4 rgba) {\n __DECODE32_ENDIANNESS__;\n rgba *= 255.0;\n vec2 gte128;\n gte128.x = rgba.b >= 128.0 ? 1.0 : 0.0;\n gte128.y = rgba.a >= 128.0 ? 1.0 : 0.0;\n float exponent = 2.0 * rgba.a - 127.0 + dot(gte128, MAGIC_VEC);\n float res = exp2(round(exponent));\n rgba.b = rgba.b - 128.0 * gte128.x;\n res = dot(rgba, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;\n res *= gte128.y * -2.0 + 1.0;\n return res;\n}\n\nhighp vec4 encode32(highp float f) {\n highp float F = abs(f);\n highp float sign = f < 0.0 ? 1.0 : 0.0;\n highp float exponent = floor(log2(F));\n highp float mantissa = (exp2(-exponent) * F);\n // exponent += floor(log2(mantissa));\n vec4 rgba = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n rgba.rg = integerMod(rgba.rg, 256.0);\n rgba.b = integerMod(rgba.b, 128.0);\n rgba.a = exponent*0.5 + 63.5;\n rgba.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n rgba = floor(rgba);\n rgba *= 0.003921569; // 1/255\n __ENCODE32_ENDIANNESS__;\n return rgba;\n}\n// Dragons end here\n\nhighp float index;\nhighp vec3 threadId;\n\nhighp vec3 indexTo3D(highp float idx, highp vec3 texDim) {\n highp float z = floor(idx / (texDim.x * texDim.y));\n idx -= z * texDim.x * texDim.y;\n highp float y = floor(idx / texDim.x);\n highp float x = integerMod(idx, texDim.x);\n return vec3(x, y, z);\n}\n\nhighp float get(highp sampler2D tex, highp vec2 texSize, highp vec3 texDim, highp float z, highp float y, highp float x) {\n highp vec3 xyz = vec3(x, y, z);\n xyz = floor(xyz + 0.5);\n __GET_WRAPAROUND__;\n highp float index = round(xyz.x + texDim.x * (xyz.y + texDim.y * xyz.z));\n __GET_TEXTURE_CHANNEL__;\n highp float w = round(texSize.x);\n vec2 st = vec2(integerMod(index, w), float(int(index) / int(w))) + 0.5;\n __GET_TEXTURE_INDEX__;\n highp vec4 texel = texture2D(tex, st / texSize);\n __GET_RESULT__;\n}\n\nhighp float get(highp sampler2D tex, highp vec2 texSize, highp vec3 texDim, highp float y, highp float x) {\n return get(tex, texSize, texDim, 0.0, y, x);\n}\n\nhighp float get(highp sampler2D tex, highp vec2 texSize, highp vec3 texDim, highp float x) {\n return get(tex, texSize, texDim, 0.0, 0.0, x);\n}\n\nhighp vec4 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\n__MAIN_PARAMS__;\n__MAIN_CONSTANTS__;\n__KERNEL__;\n\nvoid main(void) {\n index = floor(vTexCoord.s * float(uTexSize.x)) + floor(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n __MAIN_RESULT__;\n}";
\ No newline at end of file
diff --git a/dist/backend/web-gl/shader-vert.js b/dist/backend/web-gl/shader-vert.js
deleted file mode 100644
index cf329703..00000000
--- a/dist/backend/web-gl/shader-vert.js
+++ /dev/null
@@ -1,3 +0,0 @@
-"use strict";
-
-module.exports = "precision highp float;\nprecision highp int;\nprecision highp sampler2D;\n\nattribute highp vec2 aPos;\nattribute highp vec2 aTexCoord;\n\nvarying highp 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}";
\ No newline at end of file
diff --git a/dist/backend/web-gl/validator-kernel.js b/dist/backend/web-gl/validator-kernel.js
deleted file mode 100644
index 3ebfc38d..00000000
--- a/dist/backend/web-gl/validator-kernel.js
+++ /dev/null
@@ -1,48 +0,0 @@
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var WebGLKernel = require('./kernel');
-var utils = require('../../core/utils');
-
-/**
- * @class WebGLValidatorKernel
- *
- * @desc Helper class for WebGLKernel to validate texture size and dimensions.
- *
- */
-module.exports = function (_WebGLKernel) {
- _inherits(WebGLValidatorKernel, _WebGLKernel);
-
- function WebGLValidatorKernel() {
- _classCallCheck(this, WebGLValidatorKernel);
-
- return _possibleConstructorReturn(this, (WebGLValidatorKernel.__proto__ || Object.getPrototypeOf(WebGLValidatorKernel)).apply(this, arguments));
- }
-
- _createClass(WebGLValidatorKernel, [{
- key: 'validateOptions',
-
-
- /**
- * @memberOf WebGLValidatorKernel#
- * @function
- * @name validateOptions
- *
- */
- value: function validateOptions() {
- this.texSize = utils.dimToTexSize({
- floatTextures: this.floatTextures,
- floatOutput: this.floatOutput
- }, this.output, true);
- }
- }]);
-
- return WebGLValidatorKernel;
-}(WebGLKernel);
\ No newline at end of file
diff --git a/dist/core/alias.js b/dist/core/alias.js
deleted file mode 100644
index 31c0b75b..00000000
--- a/dist/core/alias.js
+++ /dev/null
@@ -1,7 +0,0 @@
-'use strict';
-
-var utils = require('./utils');
-module.exports = function alias(name, fn) {
- var fnString = fn.toString();
- return new Function('return function ' + name + ' (' + utils.getParamNamesFromString(fnString).join(', ') + ') {' + utils.getFunctionBodyFromString(fnString) + '}')();
-};
\ No newline at end of file
diff --git a/dist/core/gpu-core.js b/dist/core/gpu-core.js
deleted file mode 100644
index 8309969f..00000000
--- a/dist/core/gpu-core.js
+++ /dev/null
@@ -1,105 +0,0 @@
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var UtilsCore = require("./utils-core");
-
-/**
- * This is a minimalistic version of GPU.js used
- * to run precompiled GPU.JS code.
- *
- * This intentionally excludes the JS AST compiller : which is 400kb alone/
- *
- * @class GPUCore
- */
-module.exports = function () {
- function GPUCore() {
- _classCallCheck(this, GPUCore);
- }
-
- _createClass(GPUCore, null, [{
- key: "validateKernelObj",
-
-
- /**
- * @name validateKernelObj
- * @function
- * @static
- * @memberOf GPUCore
- *
- * @description Validates the KernelObj to comply with the defined format
- * Note that this does only a limited sanity check, and does not
- * guarantee a full working validation.
- *
- * For the kernel object format see :
- *
- * @param {Object|String} kernelObj - KernelObj used to validate
- *
- * @returns {Object} The validated kernel object, converted from JSON if needed
- *
- */
- value: function validateKernelObj(kernelObj) {
-
- // NULL validation
- if (kernelObj === null) {
- throw "KernelObj being validated is NULL";
- }
-
- // String JSON conversion
- if (typeof kernelObj === "string") {
- try {
- kernelObj = JSON.parse(kernelObj);
- } catch (e) {
- console.error(e);
- throw "Failed to convert KernelObj from JSON string";
- }
-
- // NULL validation
- if (kernelObj === null) {
- throw "Invalid (NULL) KernelObj JSON string representation";
- }
- }
-
- // Check for kernel obj flag
- if (kernelObj.isKernelObj !== true) {
- throw "Failed missing isKernelObj flag check";
- }
-
- // Return the validated kernelObj
- return kernelObj;
- }
-
- /**
- * @name loadKernelObj
- * @function
- * @static
- * @memberOf GPUCore
- *
- * @description Loads the precompiled kernel object. For GPUCore this is the ONLY way to create the kernel.
- * To generate the kernelObj use
- *
- * Note that this function calls internally, and throws an exception if it fails.
- *
- * @see GPUCore.validateKernelObj
- * @see Kernel.exportKernelObj
- *
- * @param {Object} kernelObj - The precompiled kernel object
- * @param {Object} inOpt - [Optional] the option overrides to use
- *
- * @returns {Function} The kernel function
- *
- */
-
- }, {
- key: "loadKernelObj",
- value: function loadKernelObj(kernelObj, inOpt) {
-
- // Validates the kernelObj, throws an exception if it fails
- kernelObj = validateKernelObj(kernelObj);
- }
- }]);
-
- return GPUCore;
-}();
\ No newline at end of file
diff --git a/dist/core/gpu.js b/dist/core/gpu.js
deleted file mode 100644
index 90aa4d68..00000000
--- a/dist/core/gpu.js
+++ /dev/null
@@ -1,389 +0,0 @@
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var utils = require('./utils');
-var WebGLRunner = require('../backend/web-gl/runner');
-var CPURunner = require('../backend/cpu/runner');
-var WebGLValidatorKernel = require('../backend/web-gl/validator-kernel');
-var GPUCore = require("./gpu-core");
-
-/**
- * Initialises the GPU.js library class which manages the webGlContext for the created functions.
- * @class
- * @extends GPUCore
- */
-
-var GPU = function (_GPUCore) {
- _inherits(GPU, _GPUCore);
-
- /**
- * Creates an instance of GPU.
- * @param {any} settings - Settings to set mode, andother properties. See #GPUCore
- * @memberOf GPU#
- */
- function GPU(settings) {
- _classCallCheck(this, GPU);
-
- var _this = _possibleConstructorReturn(this, (GPU.__proto__ || Object.getPrototypeOf(GPU)).call(this, settings));
-
- settings = settings || {};
- _this._canvas = settings.canvas || null;
- _this._webGl = settings.webGl || null;
- var mode = settings.mode || 'webgl';
- if (!utils.isWebGlSupported()) {
- console.warn('Warning: gpu not supported, falling back to cpu support');
- mode = 'cpu';
- }
-
- _this.kernels = [];
-
- var runnerSettings = {
- canvas: _this._canvas,
- webGl: _this._webGl
- };
-
- if (mode) {
- switch (mode.toLowerCase()) {
- case 'cpu':
- _this._runner = new CPURunner(runnerSettings);
- break;
- case 'gpu':
- case 'webgl':
- _this._runner = new WebGLRunner(runnerSettings);
- break;
- case 'webgl-validator':
- _this._runner = new WebGLRunner(runnerSettings);
- _this._runner.Kernel = WebGLValidatorKernel;
- break;
- default:
- throw new Error('"' + mode + '" mode is not defined');
- }
- }
- return _this;
- }
- /**
- *
- * This creates a callable function object to call the kernel function with the argument parameter set
- *
- * @name createKernel
- * @function
- * @memberOf GPU##
- *
- * @param {Function} inputFunction - The calling to perform the conversion
- * @param {Object} settings - The parameter configuration object
- * @property {String} settings.dimensions - Thread dimension array (Defeaults to [1024])
- * @property {String} settings.mode - CPU / GPU configuration mode (Defaults to null)
- *
- * The following modes are supported
- * *null* / *'auto'* : Attempts to build GPU mode, else fallbacks
- * *'gpu'* : Attempts to build GPU mode, else fallbacks
- * *'cpu'* : Forces JS fallback mode only
- *
- *
- * @returns {Function} callable function to run
- *
- */
-
-
- _createClass(GPU, [{
- key: 'createKernel',
- value: function createKernel(fn, settings) {
- //
- // basic parameters safety checks
- //
- if (typeof fn === 'undefined') {
- throw 'Missing fn parameter';
- }
- if (!utils.isFunction(fn) && typeof fn !== 'string') {
- throw 'fn parameter not a function';
- }
-
- var kernel = this._runner.buildKernel(fn, settings || {});
-
- //if canvas didn't come from this, propagate from kernel
- if (!this._canvas) {
- this._canvas = kernel.getCanvas();
- }
- if (!this._runner.canvas) {
- this._runner.canvas = kernel.getCanvas();
- }
-
- this.kernels.push(kernel);
-
- return kernel;
- }
-
- /**
- *
- * Create a super kernel which executes sub kernels
- * and saves their output to be used with the next sub kernel.
- * This can be useful if we want to save the output on one kernel,
- * and then use it as an input to another kernel. *Machine Learning*
- *
- * @name createKernelMap
- * @function
- * @memberOf GPU#
- *
- * @param {Object|Array} subKernels - Sub kernels for this kernel
- * @param {Function} rootKernel - Root kernel
- *
- * @returns {Function} callable kernel function
- *
- * @example
- * const megaKernel = gpu.createKernelMap({
- * addResult: function add(a, b) {
- * return a[this.thread.x] + b[this.thread.x];
- * },
- * multiplyResult: function multiply(a, b) {
- * return a[this.thread.x] * b[this.thread.x];
- * },
- * }, function(a, b, c) {
- * return multiply(add(a, b), c);
- * });
- *
- * megaKernel(a, b, c);
- *
- * Note: You can also define subKernels as an array of functions.
- * > [add, multiply]
- *
- */
-
- }, {
- key: 'createKernelMap',
- value: function createKernelMap() {
- var fn = void 0;
- var settings = void 0;
- if (typeof arguments[arguments.length - 2] === 'function') {
- fn = arguments[arguments.length - 2];
- settings = arguments[arguments.length - 1];
- } else {
- fn = arguments[arguments.length - 1];
- }
-
- if (!utils.isWebGlDrawBuffersSupported()) {
- this._runner = new CPURunner(settings);
- }
-
- var kernel = this.createKernel(fn, settings);
- if (Array.isArray(arguments[0])) {
- var functions = arguments[0];
- for (var i = 0; i < functions.length; i++) {
- kernel.addSubKernel(functions[i]);
- }
- } else {
- var _functions = arguments[0];
- for (var p in _functions) {
- if (!_functions.hasOwnProperty(p)) continue;
- kernel.addSubKernelProperty(p, _functions[p]);
- }
- }
-
- return kernel;
- }
-
- /**
- *
- * Combine different kernels into one super Kernel,
- * useful to perform multiple operations inside one
- * kernel without the penalty of data transfer between
- * cpu and gpu.
- *
- * The number of kernel functions sent to this method can be variable.
- * You can send in one, two, etc.
- *
- * @name combineKernels
- * @function
- * @memberOf GPU#
- *
- * @param {Function} subKernels - Kernel function(s) to combine.
- * @param {Function} rootKernel - Root kernel to combine kernels into
- *
- * @example
- * combineKernels(add, multiply, function(a,b,c){
- * return add(multiply(a,b), c)
- * })
- *
- * @returns {Function} Callable kernel function
- *
- */
-
- }, {
- key: 'combineKernels',
- value: function combineKernels() {
- var lastKernel = arguments[arguments.length - 2];
- var combinedKernel = arguments[arguments.length - 1];
- if (this.getMode() === 'cpu') return combinedKernel;
-
- var canvas = arguments[0].getCanvas();
- var webGl = arguments[0].getWebGl();
-
- for (var i = 0; i < arguments.length - 1; i++) {
- arguments[i].setCanvas(canvas).setWebGl(webGl).setOutputToTexture(true);
- }
-
- return function () {
- combinedKernel.apply(null, arguments);
- var texSize = lastKernel.texSize;
- var gl = lastKernel.getWebGl();
- var threadDim = lastKernel.threadDim;
- var result = void 0;
- if (lastKernel.floatOutput) {
- result = new Float32Array(texSize[0] * texSize[1] * 4);
- gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.FLOAT, result);
- } else {
- var bytes = new Uint8Array(texSize[0] * texSize[1] * 4);
- gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, bytes);
- result = new Float32Array(bytes.buffer);
- }
-
- result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]);
-
- if (lastKernel.output.length === 1) {
- return result;
- } else if (lastKernel.output.length === 2) {
- return utils.splitArray(result, lastKernel.output[0]);
- } else if (lastKernel.output.length === 3) {
- var cube = utils.splitArray(result, lastKernel.output[0] * lastKernel.output[1]);
- return cube.map(function (x) {
- return utils.splitArray(x, lastKernel.output[0]);
- });
- }
- };
- }
-
- /**
- *
- * Adds additional functions, that the kernel may call.
- *
- * @name addFunction
- * @function
- * @memberOf GPU#
- *
- * @param {Function|String} fn - JS Function to do conversion
- * @param {String[]|Object} paramTypes - Parameter type array, assumes all parameters are 'float' if null
- * @param {String} returnType - The return type, assumes 'float' if null
- *
- * @returns {GPU} returns itself
- *
- */
-
- }, {
- key: 'addFunction',
- value: function addFunction(fn, paramTypes, returnType) {
- this._runner.functionBuilder.addFunction(null, fn, paramTypes, returnType);
- return this;
- }
-
- /**
- *
- * Adds additional native functions, that the kernel may call.
- *
- * @name addNativeFunction
- * @function
- * @memberOf GPU#
- *
- * @param {String} name - native function name, used for reverse lookup
- * @param {String} nativeFunction - the native function implementation, as it would be defined in it's entirety
- *
- * @returns {GPU} returns itself
- *
- */
-
- }, {
- key: 'addNativeFunction',
- value: function addNativeFunction(name, nativeFunction) {
- this._runner.functionBuilder.addNativeFunction(name, nativeFunction);
- return this;
- }
-
- /**
- *
- * Return the current mode in which gpu.js is executing.
- * @name getMode
- * @function
- * @memberOf GPU#
- *
- * @returns {String} The current mode, "cpu", "webgl", etc.
- *
- */
-
- }, {
- key: 'getMode',
- value: function getMode() {
- return this._runner.getMode();
- }
-
- /**
- *
- * Return TRUE, if browser supports WebGl AND Canvas
- *
- * @name get isWebGlSupported
- * @function
- * @memberOf GPU#
- *
- * Note: This function can also be called directly `GPU.isWebGlSupported()`
- *
- * @returns {Boolean} TRUE if browser supports webGl
- *
- */
-
- }, {
- key: 'isWebGlSupported',
- value: function isWebGlSupported() {
- return utils.isWebGlSupported();
- }
-
- /**
- *
- * Return the canvas object bound to this gpu instance.
- *
- * @name getCanvas
- * @function
- * @memberOf GPU#
- *
- * @returns {Object} Canvas object if present
- *
- */
-
- }, {
- key: 'getCanvas',
- value: function getCanvas() {
- return this._canvas;
- }
-
- /**
- *
- * Return the webGl object bound to this gpu instance.
- *
- * @name getWebGl
- * @function
- * @memberOf GPU#
- *
- * @returns {Object} WebGl object if present
- *
- */
-
- }, {
- key: 'getWebGl',
- value: function getWebGl() {
- return this._webGl;
- }
- }]);
-
- return GPU;
-}(GPUCore);
-
-;
-
-// This ensure static methods are "inherited"
-// See: https://stackoverflow.com/questions/5441508/how-to-inherit-static-methods-from-base-class-in-javascript
-Object.assign(GPU, GPUCore);
-
-module.exports = GPU;
\ No newline at end of file
diff --git a/dist/core/input.js b/dist/core/input.js
deleted file mode 100644
index fe8372f3..00000000
--- a/dist/core/input.js
+++ /dev/null
@@ -1,26 +0,0 @@
-"use strict";
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-module.exports = function Input(value, size) {
- _classCallCheck(this, Input);
-
- this.value = value;
- if (Array.isArray(size)) {
- this.size = [];
- for (var i = 0; i < size.length; i++) {
- this.size[i] = size[i];
- }
- while (this.size.length < 3) {
- this.size.push(1);
- }
- } else {
- if (size.z) {
- this.size = [size.x, size.y, size.z];
- } else if (size.y) {
- this.size = [size.x, size.y, 1];
- } else {
- this.size = [size.x, 1, 1];
- }
- }
-};
\ No newline at end of file
diff --git a/dist/core/texture.js b/dist/core/texture.js
deleted file mode 100644
index 97638f56..00000000
--- a/dist/core/texture.js
+++ /dev/null
@@ -1,71 +0,0 @@
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var gpu = null;
-
-module.exports = function () {
-
- /**
- * @desc WebGl Texture implementation in JS
- * @constructor Texture
- * @param {Object} texture
- * @param {Array} size
- * @param {Array} output
- * @param {Object} webGl
- */
- function Texture(texture, size, output, webGl) {
- _classCallCheck(this, Texture);
-
- this.texture = texture;
- this.size = size;
- this.output = output;
- this.webGl = webGl;
- this.kernel = null;
- }
-
- /**
- * @name toArray
- * @function
- * @memberOf Texture#
- *
- * @desc Converts the Texture into a JavaScript Array.
- *
- * @param {Object} The `gpu` Object
- *
- */
-
-
- _createClass(Texture, [{
- key: 'toArray',
- value: function toArray(gpu) {
- if (!gpu) throw new Error('You need to pass the GPU object for toArray to work.');
- if (this.kernel) return this.kernel(this);
-
- this.kernel = gpu.createKernel(function (x) {
- return x[this.thread.z][this.thread.y][this.thread.x];
- }).setOutput(this.output);
-
- return this.kernel(this);
- }
-
- /**
- * @name delete
- * @desc Deletes the Texture.
- * @function
- * @memberOf Texture#
- *
- *
- */
-
- }, {
- key: 'delete',
- value: function _delete() {
- return this.webGl.deleteTexture(this.texture);
- }
- }]);
-
- return Texture;
-}();
\ No newline at end of file
diff --git a/dist/core/utils-core.js b/dist/core/utils-core.js
deleted file mode 100644
index 4d79de26..00000000
--- a/dist/core/utils-core.js
+++ /dev/null
@@ -1,247 +0,0 @@
-'use strict';
-
-/**
- *
- * @desc Reduced subset of Utils, used exclusively in gpu-core.js
- * Various utility functions / snippets of code that GPU.JS uses internally.\
- * This covers various snippets of code that is not entirely gpu.js specific (ie. may find uses elsewhere)
- *
- * Note that all methods in this class is 'static' by nature `UtilsCore.functionName()`
- *
- * @class UtilsCore
- *
- */
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var UtilsCore = function () {
- function UtilsCore() {
- _classCallCheck(this, UtilsCore);
- }
-
- _createClass(UtilsCore, null, [{
- key: 'isCanvas',
-
-
- /**
- * @typedef {Object} webGlContext
- */
-
- /**
- * @typedef {Object} CanvasDOMObject
- */
-
- //-----------------------------------------------------------------------------
- //
- // Canvas validation and support
- //
- //-----------------------------------------------------------------------------
-
- /**
- * @name isCanvas
- * @static
- * @function
- * @memberOf UtilsCore
- *
- *
- * @desc Return TRUE, on a valid DOM canvas object
- *
- * Note: This does just a VERY simply sanity check. And may give false positives.
- *
- * @param {CanvasDOMObject} canvasObj - Object to validate
- *
- * @returns {Boolean} TRUE if the object is a DOM canvas
- *
- */
- value: function isCanvas(canvasObj) {
- return canvasObj !== null && canvasObj.nodeName && canvasObj.getContext && canvasObj.nodeName.toUpperCase() === 'CANVAS';
- }
-
- /**
- * @name isCanvasSupported
- * @function
- * @static
- * @memberOf UtilsCore
- *
- * @desc Return TRUE, if browser supports canvas
- *
- * @returns {Boolean} TRUE if browser supports canvas
- *
- */
-
- }, {
- key: 'isCanvasSupported',
- value: function isCanvasSupported() {
- return _isCanvasSupported;
- }
-
- /**
- * @name initCanvas
- * @function
- * @static
- * @memberOf UtilsCore
- *
- * @desc Initiate and returns a canvas, for usage in init_webgl.
- * Returns only if canvas is supported by browser.
- *
- * @returns {CanvasDOMObject} CanvasDOMObject if supported by browser, else null
- *
- */
-
- }, {
- key: 'initCanvas',
- value: function initCanvas() {
- // Fail fast if browser previously detected no support
- if (!_isCanvasSupported) {
- return null;
- }
-
- // Create a new canvas DOM
- var canvas = document.createElement('canvas');
-
- // Default width and height, to fix webgl issue in safari
- canvas.width = 2;
- canvas.height = 2;
-
- // Returns the canvas
- return canvas;
- }
-
- //-----------------------------------------------------------------------------
- //
- // Webgl validation and support
- //
- //-----------------------------------------------------------------------------
-
-
- /**
- *
- * @name isWebGl
- * @function
- * @static
- * @memberOf UtilsCore
- *
- * @desc Return TRUE, on a valid webGlContext object
- *
- * Note: This does just a VERY simply sanity check. And may give false positives.
- *
- * @param {webGlContext} webGlObj - Object to validate
- *
- * @returns {Boolean} TRUE if the object is a webGlContext object
- *
- */
-
- }, {
- key: 'isWebGl',
- value: function isWebGl(webGlObj) {
- return webGlObj && typeof webGlObj.getExtension === 'function';
- }
-
- /**
- * @name isWebGlSupported
- * @function
- * @static
- * @memberOf UtilsCore
- *
- * @desc Return TRUE, if browser supports webgl
- *
- * @returns {Boolean} TRUE if browser supports webgl
- *
- */
-
- }, {
- key: 'isWebGlSupported',
- value: function isWebGlSupported() {
- return _isWebGlSupported;
- }
- }, {
- key: 'isWebGlDrawBuffersSupported',
- value: function isWebGlDrawBuffersSupported() {
- return _isWebGlDrawBuffersSupported;
- }
-
- // Default webgl options to use
-
- }, {
- key: 'initWebGlDefaultOptions',
- value: function initWebGlDefaultOptions() {
- return {
- alpha: false,
- depth: false,
- antialias: false
- };
- }
-
- /**
- * @name initWebGl
- * @function
- * @static
- * @memberOf UtilsCore
- *
- * @desc Initiate and returns a webGl, from a canvas object
- * Returns only if webGl is supported by browser.
- *
- * @param {CanvasDOMObject} canvasObj - Object to validate
- *
- * @returns {CanvasDOMObject} CanvasDOMObject if supported by browser, else null
- *
- */
-
- }, {
- key: 'initWebGl',
- value: function initWebGl(canvasObj) {
-
- // First time setup, does the browser support check memorizer
- if (typeof _isCanvasSupported !== 'undefined' || canvasObj === null) {
- if (!_isCanvasSupported) {
- return null;
- }
- }
-
- // Fail fast for invalid canvas object
- if (!UtilsCore.isCanvas(canvasObj)) {
- throw new Error('Invalid canvas object - ' + canvasObj);
- }
-
- // Create a new canvas DOM
- var webGl = canvasObj.getContext('experimental-webgl', UtilsCore.initWebGlDefaultOptions()) || canvasObj.getContext('webgl', UtilsCore.initWebGlDefaultOptions());
-
- if (webGl) {
- // Get the extension that is needed
- webGl.OES_texture_float = webGl.getExtension('OES_texture_float');
- webGl.OES_texture_float_linear = webGl.getExtension('OES_texture_float_linear');
- webGl.OES_element_index_uint = webGl.getExtension('OES_element_index_uint');
- }
-
- // Returns the canvas
- return webGl;
- }
- }]);
-
- return UtilsCore;
-}();
-
-//-----------------------------------------------------------------------------
-//
-// Canvas & Webgl validation and support constants
-//
-//-----------------------------------------------------------------------------
-
-var _isCanvasSupported = typeof document !== 'undefined' ? UtilsCore.isCanvas(document.createElement('canvas')) : false;
-var _testingWebGl = UtilsCore.initWebGl(UtilsCore.initCanvas());
-var _isWebGlSupported = UtilsCore.isWebGl(_testingWebGl);
-var _isWebGlDrawBuffersSupported = _isWebGlSupported && Boolean(_testingWebGl.getExtension('WEBGL_draw_buffers'));
-
-if (_isWebGlSupported) {
- UtilsCore.OES_texture_float = _testingWebGl.OES_texture_float;
- UtilsCore.OES_texture_float_linear = _testingWebGl.OES_texture_float_linear;
- UtilsCore.OES_element_index_uint = _testingWebGl.OES_element_index_uint;
-} else {
- UtilsCore.OES_texture_float = false;
- UtilsCore.OES_texture_float_linear = false;
- UtilsCore.OES_element_index_uint = false;
-}
-
-module.exports = UtilsCore;
\ No newline at end of file
diff --git a/dist/core/utils.js b/dist/core/utils.js
deleted file mode 100644
index 45dd191f..00000000
--- a/dist/core/utils.js
+++ /dev/null
@@ -1,593 +0,0 @@
-'use strict';
-
-/**
- *
- * @classdesc Various utility functions / snippets of code that GPU.JS uses internally.\
- * This covers various snippets of code that is not entirely gpu.js specific (ie. may find uses elsewhere)
- *
- * Note that all methods in this class are *static* by nature `Utils.functionName()`
- *
- * @class Utils
- * @extends UtilsCore
- *
- */
-
-var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var UtilsCore = require("./utils-core");
-var Input = require('./input');
-var Texture = require('./texture');
-// FUNCTION_NAME regex
-var FUNCTION_NAME = /function ([^(]*)/;
-
-// STRIP COMMENTS regex
-var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
-
-// ARGUMENT NAMES regex
-var ARGUMENT_NAMES = /([^\s,]+)/g;
-
-var _systemEndianness = function () {
- var b = new ArrayBuffer(4);
- var a = new Uint32Array(b);
- var c = new Uint8Array(b);
- a[0] = 0xdeadbeef;
- if (c[0] === 0xef) return 'LE';
- if (c[0] === 0xde) return 'BE';
- throw new Error('unknown endianness');
-}();
-
-var _isFloatReadPixelsSupported = null;
-
-var Utils = function (_UtilsCore) {
- _inherits(Utils, _UtilsCore);
-
- function Utils() {
- _classCallCheck(this, Utils);
-
- return _possibleConstructorReturn(this, (Utils.__proto__ || Object.getPrototypeOf(Utils)).apply(this, arguments));
- }
-
- _createClass(Utils, null, [{
- key: 'systemEndianness',
-
-
- //-----------------------------------------------------------------------------
- //
- // System values support (currently only endianness)
- //
- //-----------------------------------------------------------------------------
-
- /**
- * @memberOf Utils
- * @name systemEndianness
- * @function
- * @static
- *
- * Gets the system endianness, and cache it
- *
- * @returns {String} 'LE' or 'BE' depending on system architecture
- *
- * Credit: https://gist.github.com/TooTallNate/4750953
- */
- value: function systemEndianness() {
- return _systemEndianness;
- }
-
- //-----------------------------------------------------------------------------
- //
- // Function and function string validations
- //
- //-----------------------------------------------------------------------------
-
- /**
- * @memberOf Utils
- * @name isFunction
- * @function
- * @static
- *
- * Return TRUE, on a JS function
- *
- * @param {Function} funcObj - Object to validate if its a function
- *
- * @returns {Boolean} TRUE if the object is a JS function
- *
- */
-
- }, {
- key: 'isFunction',
- value: function isFunction(funcObj) {
- return typeof funcObj === 'function';
- }
-
- /**
- * @memberOf Utils
- * @name isFunctionString
- * @function
- * @static
- *
- * Return TRUE, on a valid JS function string
- *
- * Note: This does just a VERY simply sanity check. And may give false positives.
- *
- * @param {String} funcStr - String of JS function to validate
- *
- * @returns {Boolean} TRUE if the string passes basic validation
- *
- */
-
- }, {
- key: 'isFunctionString',
- value: function isFunctionString(funcStr) {
- if (funcStr !== null) {
- return funcStr.toString().slice(0, 'function'.length).toLowerCase() === 'function';
- }
- return false;
- }
-
- /**
- * @memberOf Utils
- * @name getFunctionName_fromString
- * @function
- * @static
- *
- * Return the function name from a JS function string
- *
- * @param {String} funcStr - String of JS function to validate
- *
- * @returns {String} Function name string (if found)
- *
- */
-
- }, {
- key: 'getFunctionNameFromString',
- value: function getFunctionNameFromString(funcStr) {
- return FUNCTION_NAME.exec(funcStr)[1];
- }
- }, {
- key: 'getFunctionBodyFromString',
- value: function getFunctionBodyFromString(funcStr) {
- return funcStr.substring(funcStr.indexOf('{') + 1, funcStr.lastIndexOf('}'));
- }
-
- /**
- * @memberOf Utils
- * @name getParamNames_fromString
- * @function
- * @static
- *
- * Return list of parameter names extracted from the JS function string
- *
- * @param {String} funcStr - String of JS function to validate
- *
- * @returns {String[]} Array representing all the parameter names
- *
- */
-
- }, {
- key: 'getParamNamesFromString',
- value: function getParamNamesFromString(func) {
- var fnStr = func.toString().replace(STRIP_COMMENTS, '');
- var result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
- if (result === null) result = [];
- return result;
- }
-
- //-----------------------------------------------------------------------------
- //
- // Object / function cloning and manipulation
- //
- //-----------------------------------------------------------------------------
-
- /**
- * @memberOf Utils
- * @name clone
- * @function
- * @static
- *
- * Returns a clone
- *
- * @param {Object} obj - Object to clone
- *
- * @returns {Object} Cloned object
- *
- */
-
- }, {
- key: 'clone',
- value: function clone(obj) {
- if (obj === null || (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) !== 'object' || obj.hasOwnProperty('isActiveClone')) return obj;
-
- var temp = obj.constructor(); // changed
-
- for (var key in obj) {
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
- obj.isActiveClone = null;
- temp[key] = Utils.clone(obj[key]);
- delete obj.isActiveClone;
- }
- }
-
- return temp;
- }
-
- /**
- * @memberOf Utils
- * @name newPromise
- * @function
- * @static
- *
- * Returns a `new Promise` object based on the underlying implmentation
- *
- * @param {Function} executor - Promise builder function
- *
- * @returns {Promise} Promise object
- *
- */
-
- }, {
- key: 'newPromise',
- value: function newPromise(executor) {
- var simple = Promise || small_promise;
- if (simple === null) {
- throw TypeError('Browser is missing Promise implementation. Consider adding small_promise.js polyfill');
- }
- return new simple(executor);
- }
-
- /**
- * @memberOf Utils
- * @name functionBinder
- * @function
- * @static
- *
- * Limited implementation of Function.bind, with fallback
- *
- * @param {Function} inFunc - to setup bind on
- * @param {Object} thisObj - The this parameter to assume inside the binded function
- *
- * @returns {Function} The binded function
- *
- */
-
- }, {
- key: 'functionBinder',
- value: function functionBinder(inFunc, thisObj) {
- if (inFunc.bind) {
- return inFunc.bind(thisObj);
- }
-
- return function () {
- var args = arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments);
- return inFunc.apply(thisObj, args);
- };
- }
-
- /**
- * @memberOf Utils
- * @name isArray
- * @function
- * @static
- *
- * * Checks if is an array or Array-like object
- *
- * @param {Object} arg - The argument object to check if is array
- *
- * @returns {Boolean} true if is array or Array-like object
- *
- */
-
- }, {
- key: 'isArray',
- value: function isArray(array) {
- if (isNaN(array.length)) {
- return false;
- }
-
- return true;
- }
-
- /**
- * @memberOf Utils
- * @name getArgumentType
- * @function
- * @static
- *
- * Evaluate the argument type, to apply respective logic for it
- *
- * @param {Object} arg - The argument object to evaluate type
- *
- * @returns {String} Argument type Array/Number/Texture/Unknown
- *
- */
-
- }, {
- key: 'getArgumentType',
- value: function getArgumentType(arg) {
- if (Utils.isArray(arg)) {
- return 'Array';
- } else if (typeof arg === 'number') {
- return 'Number';
- } else if (arg instanceof Texture) {
- return 'Texture';
- } else if (arg instanceof Input) {
- return 'Input';
- } else {
- return 'Unknown';
- }
- }
- /**
- * @typedef {Object} gpuJSObject
- */
-
- /**
- * @memberOf Utils
- * @name isFloatReadPixelsSupported
- * @function
- * @static
- *
- * Checks if the browser supports readPixels with float type
- *
- * @param {gpuJSObject} gpu - the gpu object
- *
- * @returns {Boolean} true if browser supports
- *
- */
-
- }, {
- key: 'isFloatReadPixelsSupported',
- value: function isFloatReadPixelsSupported() {
- if (_isFloatReadPixelsSupported !== null) {
- return _isFloatReadPixelsSupported;
- }
-
- var GPU = require('../index');
- var x = new GPU({
- mode: 'webgl-validator'
- }).createKernel(function () {
- return 1;
- }, {
- output: [2],
- floatTextures: true,
- floatOutput: true,
- floatOutputForce: true
- })();
-
- _isFloatReadPixelsSupported = x[0] === 1;
-
- return _isFloatReadPixelsSupported;
- }
- }, {
- key: 'dimToTexSize',
- value: function dimToTexSize(opt, dimensions, output) {
- var numTexels = dimensions[0];
- for (var i = 1; i < dimensions.length; i++) {
- numTexels *= dimensions[i];
- }
-
- if (opt.floatTextures && (!output || opt.floatOutput)) {
- numTexels = Math.ceil(numTexels / 4);
- }
-
- var w = Math.ceil(Math.sqrt(numTexels));
- return [w, w];
- }
-
- /**
- * @memberOf Utils
- * @name getDimensions
- * @function
- * @static
- *
- * Return the dimension of an array.
- *
- * @param {Array} x - The array
- * @param {number} pad - To include padding in the dimension calculation [Optional]
- *
- *
- *
- */
-
- }, {
- key: 'getDimensions',
- value: function getDimensions(x, pad) {
- var ret = void 0;
- if (Utils.isArray(x)) {
- var dim = [];
- var temp = x;
- while (Utils.isArray(temp)) {
- dim.push(temp.length);
- temp = temp[0];
- }
- ret = dim.reverse();
- } else if (x instanceof Texture) {
- ret = x.output;
- } else if (x instanceof Input) {
- ret = x.size;
- } else {
- throw 'Unknown dimensions of ' + x;
- }
-
- if (pad) {
- ret = Utils.clone(ret);
- while (ret.length < 3) {
- ret.push(1);
- }
- }
-
- return ret;
- }
-
- /**
- * @memberOf Utils
- * @name pad
- * @function
- * @static
- *
- * Pad an array AND its elements with leading and ending zeros
- *
- * @param {Array} arr - the array to pad zeros to
- * @param {number} padding - amount of padding
- *
- * @returns {Array} Array with leading and ending zeros, and all the elements padded by zeros.
- *
- */
-
- }, {
- key: 'pad',
- value: function pad(arr, padding) {
- function zeros(n) {
- return Array.apply(null, new Array(n)).map(Number.prototype.valueOf, 0);
- }
-
- var len = arr.length + padding * 2;
-
- var ret = arr.map(function (x) {
- return [].concat(zeros(padding), x, zeros(padding));
- });
-
- for (var i = 0; i < padding; i++) {
- ret = [].concat([zeros(len)], ret, [zeros(len)]);
- }
-
- return ret;
- }
-
- /**
- * @memberOf Utils
- * @name flatten2dArrayTo
- * @function
- * @static
- *
- * Puts a nested 2d array into a one-dimensional target array
- * @param {Array|*} array
- * @param {Float32Array|Float64Array} target
- */
-
- }, {
- key: 'flatten2dArrayTo',
- value: function flatten2dArrayTo(array, target) {
- var offset = 0;
- for (var y = 0; y < array.length; y++) {
- target.set(array[y], offset);
- offset += array[y].length;
- }
- }
-
- /**
- * @memberOf Utils
- * @name flatten3dArrayTo
- * @function
- * @static
- *
- * Puts a nested 3d array into a one-dimensional target array
- * @param {Array|*} array
- * @param {Float32Array|Float64Array} target
- */
-
- }, {
- key: 'flatten3dArrayTo',
- value: function flatten3dArrayTo(array, target) {
- var offset = 0;
- for (var z = 0; z < array.length; z++) {
- for (var y = 0; y < array[z].length; y++) {
- target.set(array[z][y], offset);
- offset += array[z][y].length;
- }
- }
- }
-
- /**
- * @memberOf Utils
- * @name flatten3dArrayTo
- * @function
- * @static
- *
- * Puts a nested 1d, 2d, or 3d array into a one-dimensional target array
- * @param {Array|*} array
- * @param {Float32Array|Float64Array} target
- */
-
- }, {
- key: 'flattenTo',
- value: function flattenTo(array, target) {
- if (Utils.isArray(array[0])) {
- if (Utils.isArray(array[0][0])) {
- Utils.flatten3dArrayTo(array, target);
- } else {
- Utils.flatten2dArrayTo(array, target);
- }
- } else {
- target.set(array);
- }
- }
-
- /**
- * @memberOf Utils
- * @name splitArray
- * @function
- * @static
- *
- * Splits an array into smaller arrays.
- * Number of elements in one small chunk is given by `part`
- *
- * @param {Array} array - The array to split into chunks
- * @param {Array} part - elements in one chunk
- *
- * @returns {Array} An array of smaller chunks
- *
- */
-
- }, {
- key: 'splitArray',
- value: function splitArray(array, part) {
- var result = [];
- for (var i = 0; i < array.length; i += part) {
- result.push(Array.prototype.slice.call(array, i, i + part));
- }
- return result;
- }
- }, {
- key: 'getAstString',
- value: function getAstString(source, ast) {
- var lines = Array.isArray(source) ? source : source.split(/\r?\n/g);
- var start = ast.loc.start;
- var end = ast.loc.end;
- var result = [];
- result.push(lines[start.line - 1].slice(start.column));
- for (var i = start.line; i < end.line - 1; i++) {
- result.push(lines[i]);
- }
- result.push(lines[end.line - 1].slice(0, end.column));
- return result.join('\n');
- }
- }, {
- key: 'allPropertiesOf',
- value: function allPropertiesOf(obj) {
- var props = [];
-
- do {
- props.push.apply(props, Object.getOwnPropertyNames(obj));
- } while (obj = Object.getPrototypeOf(obj));
-
- return props;
- }
- }]);
-
- return Utils;
-}(UtilsCore);
-
-// This ensure static methods are "inherited"
-// See: https://stackoverflow.com/questions/5441508/how-to-inherit-static-methods-from-base-class-in-javascript
-
-
-Object.assign(Utils, UtilsCore);
-
-module.exports = Utils;
\ No newline at end of file
diff --git a/dist/gpu-browser-core.js b/dist/gpu-browser-core.js
new file mode 100644
index 00000000..2f489da1
--- /dev/null
+++ b/dist/gpu-browser-core.js
@@ -0,0 +1,15067 @@
+/**
+ * gpu.js
+ * http://gpu.rocks/
+ *
+ * GPU Accelerated JavaScript
+ *
+ * @version 2.16.0
+ * @date Thu Feb 13 2025 11:46:48 GMT-0800 (Pacific Standard Time)
+ *
+ * @license MIT
+ * The MIT License
+ *
+ * Copyright (c) 2025 gpu.js Team
+ */(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.GPU = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i 0) {
+ recording.pop();
+ }
+ }
+ function insertVariable(name, value) {
+ variables[name] = value;
+ }
+ function getEntity(value) {
+ const name = entityNames[value];
+ if (name) {
+ return contextName + '.' + name;
+ }
+ return value;
+ }
+ function setIndent(spaces) {
+ indent = ' '.repeat(spaces);
+ }
+ function addVariable(value, source) {
+ const variableName = `${contextName}Variable${contextVariables.length}`;
+ recording.push(`${indent}const ${variableName} = ${source};`);
+ contextVariables.push(value);
+ return variableName;
+ }
+ function writePPM(width, height) {
+ const sourceVariable = `${contextName}Variable${contextVariables.length}`;
+ const imageVariable = `imageDatum${imageCount}`;
+ recording.push(`${indent}let ${imageVariable} = ["P3\\n# ${readPixelsFile}.ppm\\n", ${width}, ' ', ${height}, "\\n255\\n"].join("");`);
+ recording.push(`${indent}for (let i = 0; i < ${imageVariable}.length; i += 4) {`);
+ recording.push(`${indent} ${imageVariable} += ${sourceVariable}[i] + ' ' + ${sourceVariable}[i + 1] + ' ' + ${sourceVariable}[i + 2] + ' ';`);
+ recording.push(`${indent}}`);
+ recording.push(`${indent}if (typeof require !== "undefined") {`);
+ recording.push(`${indent} require('fs').writeFileSync('./${readPixelsFile}.ppm', ${imageVariable});`);
+ recording.push(`${indent}}`);
+ imageCount++;
+ }
+ function addComment(value) {
+ recording.push(`${indent}// ${value}`);
+ }
+ function checkThrowError() {
+ recording.push(`${indent}(() => {
+${indent}const error = ${contextName}.getError();
+${indent}if (error !== ${contextName}.NONE) {
+${indent} const names = Object.getOwnPropertyNames(gl);
+${indent} for (let i = 0; i < names.length; i++) {
+${indent} const name = names[i];
+${indent} if (${contextName}[name] === error) {
+${indent} throw new Error('${contextName} threw ' + name);
+${indent} }
+${indent} }
+${indent}}
+${indent}})();`);
+ }
+ function methodCallToString(method, args) {
+ return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`;
+ }
+
+ function getVariableName(value) {
+ if (variables) {
+ for (const name in variables) {
+ if (variables[name] === value) {
+ return name;
+ }
+ }
+ }
+ return null;
+ }
+
+ function getContextVariableName(value) {
+ const i = contextVariables.indexOf(value);
+ if (i !== -1) {
+ return `${contextName}Variable${i}`;
+ }
+ return null;
+ }
+}
+
+function glExtensionWiretap(extension, options) {
+ const proxy = new Proxy(extension, { get: listen });
+ const extensionEntityNames = {};
+ const {
+ contextName,
+ contextVariables,
+ getEntity,
+ useTrackablePrimitives,
+ recording,
+ variables,
+ indent,
+ onUnrecognizedArgumentLookup,
+ } = options;
+ return proxy;
+ function listen(obj, property) {
+ if (typeof obj[property] === 'function') {
+ return function() {
+ switch (property) {
+ case 'drawBuffersWEBGL':
+ recording.push(`${indent}${contextName}.drawBuffersWEBGL([${argumentsToString(arguments[0], { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })}]);`);
+ return extension.drawBuffersWEBGL(arguments[0]);
+ }
+ let result = extension[property].apply(extension, arguments);
+ switch (typeof result) {
+ case 'undefined':
+ recording.push(`${indent}${methodCallToString(property, arguments)};`);
+ return;
+ case 'number':
+ case 'boolean':
+ if (useTrackablePrimitives && contextVariables.indexOf(trackablePrimitive(result)) === -1) {
+ recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);
+ contextVariables.push(result = trackablePrimitive(result));
+ } else {
+ recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);
+ contextVariables.push(result);
+ }
+ break;
+ default:
+ if (result === null) {
+ recording.push(`${methodCallToString(property, arguments)};`);
+ } else {
+ recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);
+ }
+ contextVariables.push(result);
+ }
+ return result;
+ };
+ }
+ extensionEntityNames[extension[property]] = property;
+ return extension[property];
+ }
+
+ function getExtensionEntity(value) {
+ if (extensionEntityNames.hasOwnProperty(value)) {
+ return `${contextName}.${extensionEntityNames[value]}`;
+ }
+ return getEntity(value);
+ }
+
+ function methodCallToString(method, args) {
+ return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`;
+ }
+
+ function addVariable(value, source) {
+ const variableName = `${contextName}Variable${contextVariables.length}`;
+ contextVariables.push(value);
+ recording.push(`${indent}const ${variableName} = ${source};`);
+ return variableName;
+ }
+}
+
+function argumentsToString(args, options) {
+ const { variables, onUnrecognizedArgumentLookup } = options;
+ return (Array.from(args).map((arg) => {
+ const variableName = getVariableName(arg);
+ if (variableName) {
+ return variableName;
+ }
+ return argumentToString(arg, options);
+ }).join(', '));
+
+ function getVariableName(value) {
+ if (variables) {
+ for (const name in variables) {
+ if (!variables.hasOwnProperty(name)) continue;
+ if (variables[name] === value) {
+ return name;
+ }
+ }
+ }
+ if (onUnrecognizedArgumentLookup) {
+ return onUnrecognizedArgumentLookup(value);
+ }
+ return null;
+ }
+}
+
+function argumentToString(arg, options) {
+ const { contextName, contextVariables, getEntity, addVariable, onUnrecognizedArgumentLookup } = options;
+ if (typeof arg === 'undefined') {
+ return 'undefined';
+ }
+ if (arg === null) {
+ return 'null';
+ }
+ const i = contextVariables.indexOf(arg);
+ if (i > -1) {
+ return `${contextName}Variable${i}`;
+ }
+ switch (arg.constructor.name) {
+ case 'String':
+ const hasLines = /\n/.test(arg);
+ const hasSingleQuotes = /'/.test(arg);
+ const hasDoubleQuotes = /"/.test(arg);
+ if (hasLines) {
+ return '`' + arg + '`';
+ } else if (hasSingleQuotes && !hasDoubleQuotes) {
+ return '"' + arg + '"';
+ } else if (!hasSingleQuotes && hasDoubleQuotes) {
+ return "'" + arg + "'";
+ } else {
+ return '\'' + arg + '\'';
+ }
+ case 'Number': return getEntity(arg);
+ case 'Boolean': return getEntity(arg);
+ case 'Array':
+ return addVariable(arg, `new ${arg.constructor.name}([${Array.from(arg).join(',')}])`);
+ case 'Float32Array':
+ case 'Uint8Array':
+ case 'Uint16Array':
+ case 'Int32Array':
+ return addVariable(arg, `new ${arg.constructor.name}(${JSON.stringify(Array.from(arg))})`);
+ default:
+ if (onUnrecognizedArgumentLookup) {
+ const instantiationString = onUnrecognizedArgumentLookup(arg);
+ if (instantiationString) {
+ return instantiationString;
+ }
+ }
+ throw new Error(`unrecognized argument type ${arg.constructor.name}`);
+ }
+}
+
+function trackablePrimitive(value) {
+ return new value.constructor(value);
+}
+
+if (typeof module !== 'undefined') {
+ module.exports = { glWiretap, glExtensionWiretap };
+}
+
+if (typeof window !== 'undefined') {
+ glWiretap.glExtensionWiretap = glExtensionWiretap;
+ window.glWiretap = glWiretap;
+}
+
+},{}],3:[function(require,module,exports){
+function setupArguments(args) {
+ const newArguments = new Array(args.length);
+ for (let i = 0; i < args.length; i++) {
+ const arg = args[i];
+ if (arg.toArray) {
+ newArguments[i] = arg.toArray();
+ } else {
+ newArguments[i] = arg;
+ }
+ }
+ return newArguments;
+}
+
+function mock1D() {
+ const args = setupArguments(arguments);
+ const row = new Float32Array(this.output.x);
+ for (let x = 0; x < this.output.x; x++) {
+ this.thread.x = x;
+ this.thread.y = 0;
+ this.thread.z = 0;
+ row[x] = this._fn.apply(this, args);
+ }
+ return row;
+}
+
+function mock2D() {
+ const args = setupArguments(arguments);
+ const matrix = new Array(this.output.y);
+ for (let y = 0; y < this.output.y; y++) {
+ const row = new Float32Array(this.output.x);
+ for (let x = 0; x < this.output.x; x++) {
+ this.thread.x = x;
+ this.thread.y = y;
+ this.thread.z = 0;
+ row[x] = this._fn.apply(this, args);
+ }
+ matrix[y] = row;
+ }
+ return matrix;
+}
+
+function mock2DGraphical() {
+ const args = setupArguments(arguments);
+ for (let y = 0; y < this.output.y; y++) {
+ for (let x = 0; x < this.output.x; x++) {
+ this.thread.x = x;
+ this.thread.y = y;
+ this.thread.z = 0;
+ this._fn.apply(this, args);
+ }
+ }
+}
+
+function mock3D() {
+ const args = setupArguments(arguments);
+ const cube = new Array(this.output.z);
+ for (let z = 0; z < this.output.z; z++) {
+ const matrix = new Array(this.output.y);
+ for (let y = 0; y < this.output.y; y++) {
+ const row = new Float32Array(this.output.x);
+ for (let x = 0; x < this.output.x; x++) {
+ this.thread.x = x;
+ this.thread.y = y;
+ this.thread.z = z;
+ row[x] = this._fn.apply(this, args);
+ }
+ matrix[y] = row;
+ }
+ cube[z] = matrix;
+ }
+ return cube;
+}
+
+function apiDecorate(kernel) {
+ kernel.setOutput = (output) => {
+ kernel.output = setupOutput(output);
+ if (kernel.graphical) {
+ setupGraphical(kernel);
+ }
+ };
+ kernel.toJSON = () => {
+ throw new Error('Not usable with gpuMock');
+ };
+ kernel.setConstants = (flag) => {
+ kernel.constants = flag;
+ return kernel;
+ };
+ kernel.setGraphical = (flag) => {
+ kernel.graphical = flag;
+ return kernel;
+ };
+ kernel.setCanvas = (flag) => {
+ kernel.canvas = flag;
+ return kernel;
+ };
+ kernel.setContext = (flag) => {
+ kernel.context = flag;
+ return kernel;
+ };
+ kernel.destroy = () => {};
+ kernel.validateSettings = () => {};
+ if (kernel.graphical && kernel.output) {
+ setupGraphical(kernel);
+ }
+ kernel.exec = function() {
+ return new Promise((resolve, reject) => {
+ try {
+ resolve(kernel.apply(kernel, arguments));
+ } catch(e) {
+ reject(e);
+ }
+ });
+ };
+ kernel.getPixels = (flip) => {
+ const {x, y} = kernel.output;
+ return flip ? flipPixels(kernel._imageData.data, x, y) : kernel._imageData.data.slice(0);
+ };
+ kernel.color = function(r, g, b, a) {
+ if (typeof a === 'undefined') {
+ a = 1;
+ }
+
+ r = Math.floor(r * 255);
+ g = Math.floor(g * 255);
+ b = Math.floor(b * 255);
+ a = Math.floor(a * 255);
+
+ const width = kernel.output.x;
+ const height = kernel.output.y;
+
+ const x = kernel.thread.x;
+ const y = height - kernel.thread.y - 1;
+
+ const index = x + y * width;
+
+ kernel._colorData[index * 4 + 0] = r;
+ kernel._colorData[index * 4 + 1] = g;
+ kernel._colorData[index * 4 + 2] = b;
+ kernel._colorData[index * 4 + 3] = a;
+ };
+
+ const mockMethod = () => kernel;
+ const methods = [
+ 'setWarnVarUsage',
+ 'setArgumentTypes',
+ 'setTactic',
+ 'setOptimizeFloatMemory',
+ 'setDebug',
+ 'setLoopMaxIterations',
+ 'setConstantTypes',
+ 'setFunctions',
+ 'setNativeFunctions',
+ 'setInjectedNative',
+ 'setPipeline',
+ 'setPrecision',
+ 'setOutputToTexture',
+ 'setImmutable',
+ 'setStrictIntegers',
+ 'setDynamicOutput',
+ 'setHardcodeConstants',
+ 'setDynamicArguments',
+ 'setUseLegacyEncoder',
+ 'setWarnVarUsage',
+ 'addSubKernel',
+ ];
+ for (let i = 0; i < methods.length; i++) {
+ kernel[methods[i]] = mockMethod;
+ }
+ return kernel;
+}
+
+function setupGraphical(kernel) {
+ const {x, y} = kernel.output;
+ if (kernel.context && kernel.context.createImageData) {
+ const data = new Uint8ClampedArray(x * y * 4);
+ kernel._imageData = kernel.context.createImageData(x, y);
+ kernel._colorData = data;
+ } else {
+ const data = new Uint8ClampedArray(x * y * 4);
+ kernel._imageData = { data };
+ kernel._colorData = data;
+ }
+}
+
+function setupOutput(output) {
+ let result = null;
+ if (output.length) {
+ if (output.length === 3) {
+ const [x,y,z] = output;
+ result = { x, y, z };
+ } else if (output.length === 2) {
+ const [x,y] = output;
+ result = { x, y };
+ } else {
+ const [x] = output;
+ result = { x };
+ }
+ } else {
+ result = output;
+ }
+ return result;
+}
+
+function gpuMock(fn, settings = {}) {
+ const output = settings.output ? setupOutput(settings.output) : null;
+ function kernel() {
+ if (kernel.output.z) {
+ return mock3D.apply(kernel, arguments);
+ } else if (kernel.output.y) {
+ if (kernel.graphical) {
+ return mock2DGraphical.apply(kernel, arguments);
+ }
+ return mock2D.apply(kernel, arguments);
+ } else {
+ return mock1D.apply(kernel, arguments);
+ }
+ }
+ kernel._fn = fn;
+ kernel.constants = settings.constants || null;
+ kernel.context = settings.context || null;
+ kernel.canvas = settings.canvas || null;
+ kernel.graphical = settings.graphical || false;
+ kernel._imageData = null;
+ kernel._colorData = null;
+ kernel.output = output;
+ kernel.thread = {
+ x: 0,
+ y: 0,
+ z: 0
+ };
+ return apiDecorate(kernel);
+}
+
+function flipPixels(pixels, width, height) {
+ const halfHeight = height / 2 | 0;
+ const bytesPerRow = width * 4;
+ const temp = new Uint8ClampedArray(width * 4);
+ const result = pixels.slice(0);
+ for (let y = 0; y < halfHeight; ++y) {
+ const topOffset = y * bytesPerRow;
+ const bottomOffset = (height - y - 1) * bytesPerRow;
+
+ temp.set(result.subarray(topOffset, topOffset + bytesPerRow));
+
+ result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow);
+
+ result.set(temp, bottomOffset);
+ }
+ return result;
+}
+
+module.exports = {
+ gpuMock
+};
+
+},{}],4:[function(require,module,exports){
+const { utils } = require('./utils');
+
+function alias(name, source) {
+ const fnString = source.toString();
+ return new Function(`return function ${ name } (${ utils.getArgumentNamesFromString(fnString).join(', ') }) {
+ ${ utils.getFunctionBodyFromString(fnString) }
+}`)();
+}
+
+module.exports = {
+ alias
+};
+},{"./utils":113}],5:[function(require,module,exports){
+const { FunctionNode } = require('../function-node');
+
+class CPUFunctionNode extends FunctionNode {
+ astFunction(ast, retArr) {
+
+ if (!this.isRootKernel) {
+ retArr.push('function');
+ retArr.push(' ');
+ retArr.push(this.name);
+ retArr.push('(');
+
+ for (let i = 0; i < this.argumentNames.length; ++i) {
+ const argumentName = this.argumentNames[i];
+
+ if (i > 0) {
+ retArr.push(', ');
+ }
+ retArr.push('user_');
+ retArr.push(argumentName);
+ }
+
+ retArr.push(') {\n');
+ }
+
+ for (let i = 0; i < ast.body.body.length; ++i) {
+ this.astGeneric(ast.body.body[i], retArr);
+ retArr.push('\n');
+ }
+
+ if (!this.isRootKernel) {
+ retArr.push('}\n');
+ }
+ return retArr;
+ }
+
+ astReturnStatement(ast, retArr) {
+ const type = this.returnType || this.getType(ast.argument);
+
+ if (!this.returnType) {
+ this.returnType = type;
+ }
+
+ if (this.isRootKernel) {
+ retArr.push(this.leadingReturnStatement);
+ this.astGeneric(ast.argument, retArr);
+ retArr.push(';\n');
+ retArr.push(this.followingReturnStatement);
+ retArr.push('continue;\n');
+ } else if (this.isSubKernel) {
+ retArr.push(`subKernelResult_${ this.name } = `);
+ this.astGeneric(ast.argument, retArr);
+ retArr.push(';');
+ retArr.push(`return subKernelResult_${ this.name };`);
+ } else {
+ retArr.push('return ');
+ this.astGeneric(ast.argument, retArr);
+ retArr.push(';');
+ }
+ return retArr;
+ }
+
+ astLiteral(ast, retArr) {
+
+ if (isNaN(ast.value)) {
+ throw this.astErrorOutput(
+ 'Non-numeric literal not supported : ' + ast.value,
+ ast
+ );
+ }
+
+ retArr.push(ast.value);
+
+ return retArr;
+ }
+
+ astBinaryExpression(ast, retArr) {
+ retArr.push('(');
+ this.astGeneric(ast.left, retArr);
+ retArr.push(ast.operator);
+ this.astGeneric(ast.right, retArr);
+ retArr.push(')');
+ return retArr;
+ }
+
+ astIdentifierExpression(idtNode, retArr) {
+ if (idtNode.type !== 'Identifier') {
+ throw this.astErrorOutput(
+ 'IdentifierExpression - not an Identifier',
+ idtNode
+ );
+ }
+
+ switch (idtNode.name) {
+ case 'Infinity':
+ retArr.push('Infinity');
+ break;
+ default:
+ if (this.constants && this.constants.hasOwnProperty(idtNode.name)) {
+ retArr.push('constants_' + idtNode.name);
+ } else {
+ retArr.push('user_' + idtNode.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) {
+ this.pushState('in-for-loop-init');
+ this.astGeneric(forNode.init, initArr);
+ for (let i = 0; i < initArr.length; i++) {
+ if (initArr[i].includes && initArr[i].includes(',')) {
+ isSafe = false;
+ }
+ }
+ this.popState('in-for-loop-init');
+ } else {
+ isSafe = false;
+ }
+
+ if (forNode.test) {
+ this.astGeneric(forNode.test, testArr);
+ } else {
+ isSafe = false;
+ }
+
+ if (forNode.update) {
+ 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) {
+ retArr.push(`for (${initArr.join('')};${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 (let ${iVariableName}=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
+ );
+ }
+
+ retArr.push('for (let i = 0; i < LOOP_MAX; i++) {');
+ retArr.push('if (');
+ this.astGeneric(whileNode.test, retArr);
+ retArr.push(') {\n');
+ this.astGeneric(whileNode.body, retArr);
+ retArr.push('} else {\n');
+ retArr.push('break;\n');
+ retArr.push('}\n');
+ retArr.push('}\n');
+
+ return retArr;
+ }
+
+ astDoWhileStatement(doWhileNode, retArr) {
+ if (doWhileNode.type !== 'DoWhileStatement') {
+ throw this.astErrorOutput(
+ 'Invalid while statement',
+ doWhileNode
+ );
+ }
+
+ retArr.push('for (let i = 0; i < LOOP_MAX; i++) {');
+ this.astGeneric(doWhileNode.body, retArr);
+ retArr.push('if (!');
+ this.astGeneric(doWhileNode.test, retArr);
+ retArr.push(') {\n');
+ retArr.push('break;\n');
+ retArr.push('}\n');
+ retArr.push('}\n');
+
+ return retArr;
+
+ }
+
+ astAssignmentExpression(assNode, retArr) {
+ const declaration = this.getDeclaration(assNode.left);
+ if (declaration && !declaration.assignable) {
+ throw this.astErrorOutput(`Variable ${assNode.left.name} is not assignable here`, assNode);
+ }
+ this.astGeneric(assNode.left, retArr);
+ retArr.push(assNode.operator);
+ this.astGeneric(assNode.right, retArr);
+ return retArr;
+ }
+
+ astBlockStatement(bNode, retArr) {
+ if (this.isState('loop-body')) {
+ this.pushState('block-body');
+ for (let i = 0; i < bNode.body.length; i++) {
+ this.astGeneric(bNode.body[i], retArr);
+ }
+ this.popState('block-body');
+ } else {
+ retArr.push('{\n');
+ for (let i = 0; i < bNode.body.length; i++) {
+ this.astGeneric(bNode.body[i], retArr);
+ }
+ retArr.push('}\n');
+ }
+ return retArr;
+ }
+
+ astVariableDeclaration(varDecNode, retArr) {
+ retArr.push(`${varDecNode.kind} `);
+ const { declarations } = varDecNode;
+ for (let i = 0; i < declarations.length; i++) {
+ if (i > 0) {
+ retArr.push(',');
+ }
+ const declaration = declarations[i];
+ const info = this.getDeclaration(declaration.id);
+ if (!info.valueType) {
+ info.valueType = this.getType(declaration.init);
+ }
+ this.astGeneric(declaration, retArr);
+ }
+ if (!this.isState('in-for-loop-init')) {
+ retArr.push(';');
+ }
+ return retArr;
+ }
+
+ astIfStatement(ifNode, retArr) {
+ retArr.push('if (');
+ this.astGeneric(ifNode.test, retArr);
+ retArr.push(')');
+ if (ifNode.consequent.type === 'BlockStatement') {
+ this.astGeneric(ifNode.consequent, retArr);
+ } else {
+ retArr.push(' {\n');
+ this.astGeneric(ifNode.consequent, retArr);
+ retArr.push('\n}\n');
+ }
+
+ if (ifNode.alternate) {
+ retArr.push('else ');
+ if (ifNode.alternate.type === 'BlockStatement' || ifNode.alternate.type === 'IfStatement') {
+ this.astGeneric(ifNode.alternate, retArr);
+ } else {
+ retArr.push(' {\n');
+ this.astGeneric(ifNode.alternate, retArr);
+ retArr.push('\n}\n');
+ }
+ }
+ return retArr;
+
+ }
+
+ astSwitchStatement(ast, retArr) {
+ const { discriminant, cases } = ast;
+ retArr.push('switch (');
+ this.astGeneric(discriminant, retArr);
+ retArr.push(') {\n');
+ for (let i = 0; i < cases.length; i++) {
+ if (cases[i].test === null) {
+ retArr.push('default:\n');
+ this.astGeneric(cases[i].consequent, retArr);
+ if (cases[i].consequent && cases[i].consequent.length > 0) {
+ retArr.push('break;\n');
+ }
+ continue;
+ }
+ retArr.push('case ');
+ this.astGeneric(cases[i].test, retArr);
+ retArr.push(':\n');
+ if (cases[i].consequent && cases[i].consequent.length > 0) {
+ this.astGeneric(cases[i].consequent, retArr);
+ retArr.push('break;\n');
+ }
+ }
+ retArr.push('\n}');
+ }
+
+ astThisExpression(tNode, retArr) {
+ retArr.push('_this');
+ return retArr;
+ }
+
+ astMemberExpression(mNode, retArr) {
+ const {
+ signature,
+ type,
+ property,
+ xProperty,
+ yProperty,
+ zProperty,
+ name,
+ origin
+ } = this.getMemberExpressionDetails(mNode);
+ switch (signature) {
+ case 'this.thread.value':
+ retArr.push(`_this.thread.${ name }`);
+ return retArr;
+ case 'this.output.value':
+ switch (name) {
+ case 'x':
+ retArr.push('outputX');
+ break;
+ case 'y':
+ retArr.push('outputY');
+ break;
+ case 'z':
+ retArr.push('outputZ');
+ break;
+ default:
+ throw this.astErrorOutput('Unexpected expression', mNode);
+ }
+ return retArr;
+ case 'value':
+ throw this.astErrorOutput('Unexpected expression', mNode);
+ case 'value[]':
+ case 'value[][]':
+ case 'value[][][]':
+ case 'value.value':
+ if (origin === 'Math') {
+ retArr.push(Math[name]);
+ return retArr;
+ }
+ switch (property) {
+ case 'r':
+ retArr.push(`user_${ name }[0]`);
+ return retArr;
+ case 'g':
+ retArr.push(`user_${ name }[1]`);
+ return retArr;
+ case 'b':
+ retArr.push(`user_${ name }[2]`);
+ return retArr;
+ case 'a':
+ retArr.push(`user_${ name }[3]`);
+ return retArr;
+ }
+ break;
+ case 'this.constants.value':
+ case 'this.constants.value[]':
+ case 'this.constants.value[][]':
+ case 'this.constants.value[][][]':
+ break;
+ case 'fn()[]':
+ this.astGeneric(mNode.object, retArr);
+ retArr.push('[');
+ this.astGeneric(mNode.property, retArr);
+ retArr.push(']');
+ return retArr;
+ case 'fn()[][]':
+ this.astGeneric(mNode.object.object, retArr);
+ retArr.push('[');
+ this.astGeneric(mNode.object.property, retArr);
+ retArr.push(']');
+ retArr.push('[');
+ this.astGeneric(mNode.property, retArr);
+ retArr.push(']');
+ return retArr;
+ default:
+ throw this.astErrorOutput('Unexpected expression', mNode);
+ }
+
+ if (!mNode.computed) {
+ switch (type) {
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ case 'Boolean':
+ retArr.push(`${origin}_${name}`);
+ return retArr;
+ }
+ }
+
+ const markupName = `${origin}_${name}`;
+
+ switch (type) {
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ case 'Matrix(2)':
+ case 'Matrix(3)':
+ case 'Matrix(4)':
+ case 'HTMLImageArray':
+ case 'ArrayTexture(1)':
+ case 'ArrayTexture(2)':
+ case 'ArrayTexture(3)':
+ case 'ArrayTexture(4)':
+ case 'HTMLImage':
+ default:
+ let size;
+ let isInput;
+ if (origin === 'constants') {
+ const constant = this.constants[name];
+ isInput = this.constantTypes[name] === 'Input';
+ size = isInput ? constant.size : null;
+ } else {
+ isInput = this.isInput(name);
+ size = isInput ? this.argumentSizes[this.argumentNames.indexOf(name)] : null;
+ }
+ retArr.push(`${ markupName }`);
+ if (zProperty && yProperty) {
+ if (isInput) {
+ retArr.push('[(');
+ this.astGeneric(zProperty, retArr);
+ retArr.push(`*${ this.dynamicArguments ? '(outputY * outputX)' : size[1] * size[0] })+(`);
+ this.astGeneric(yProperty, retArr);
+ retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`);
+ this.astGeneric(xProperty, retArr);
+ retArr.push(']');
+ } else {
+ retArr.push('[');
+ this.astGeneric(zProperty, retArr);
+ retArr.push(']');
+ retArr.push('[');
+ this.astGeneric(yProperty, retArr);
+ retArr.push(']');
+ retArr.push('[');
+ this.astGeneric(xProperty, retArr);
+ retArr.push(']');
+ }
+ } else if (yProperty) {
+ if (isInput) {
+ retArr.push('[(');
+ this.astGeneric(yProperty, retArr);
+ retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`);
+ this.astGeneric(xProperty, retArr);
+ retArr.push(']');
+ } else {
+ retArr.push('[');
+ this.astGeneric(yProperty, retArr);
+ retArr.push(']');
+ retArr.push('[');
+ this.astGeneric(xProperty, retArr);
+ retArr.push(']');
+ }
+ } else if (typeof xProperty !== 'undefined') {
+ retArr.push('[');
+ this.astGeneric(xProperty, retArr);
+ retArr.push(']');
+ }
+ }
+ return retArr;
+ }
+
+ astCallExpression(ast, retArr) {
+ if (ast.type !== 'CallExpression') {
+ throw this.astErrorOutput('Unknown CallExpression', ast);
+ }
+ let functionName = this.astMemberExpressionUnroll(ast.callee);
+
+ if (this.calledFunctions.indexOf(functionName) < 0) {
+ this.calledFunctions.push(functionName);
+ }
+
+ const isMathFunction = this.isAstMathFunction(ast);
+
+ if (this.onFunctionCall) {
+ this.onFunctionCall(this.name, functionName, ast.arguments);
+ }
+
+ retArr.push(functionName);
+
+ retArr.push('(');
+ const targetTypes = this.lookupFunctionArgumentTypes(functionName) || [];
+ for (let i = 0; i < ast.arguments.length; ++i) {
+ const argument = ast.arguments[i];
+
+ let argumentType = this.getType(argument);
+ if (!targetTypes[i]) {
+ this.triggerImplyArgumentType(functionName, i, argumentType, this);
+ }
+
+ if (i > 0) {
+ retArr.push(', ');
+ }
+ this.astGeneric(argument, retArr);
+ }
+ retArr.push(')');
+
+ return retArr;
+ }
+
+ astArrayExpression(arrNode, retArr) {
+ const returnType = this.getType(arrNode);
+ const arrLen = arrNode.elements.length;
+ const elements = [];
+ for (let i = 0; i < arrLen; ++i) {
+ const element = [];
+ this.astGeneric(arrNode.elements[i], element);
+ elements.push(element.join(''));
+ }
+ switch (returnType) {
+ case 'Matrix(2)':
+ case 'Matrix(3)':
+ case 'Matrix(4)':
+ retArr.push(`[${elements.join(', ')}]`);
+ break;
+ default:
+ retArr.push(`new Float32Array([${elements.join(', ')}])`);
+ }
+ return retArr;
+ }
+
+ astDebuggerStatement(arrNode, retArr) {
+ retArr.push('debugger;');
+ return retArr;
+ }
+}
+
+module.exports = {
+ CPUFunctionNode
+};
+},{"../function-node":9}],6:[function(require,module,exports){
+const { utils } = require('../../utils');
+
+function constantsToString(constants, types) {
+ const results = [];
+ for (const name in types) {
+ if (!types.hasOwnProperty(name)) continue;
+ const type = types[name];
+ const constant = constants[name];
+ switch (type) {
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ case 'Boolean':
+ results.push(`${name}:${constant}`);
+ break;
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ case 'Matrix(2)':
+ case 'Matrix(3)':
+ case 'Matrix(4)':
+ results.push(`${name}:new ${constant.constructor.name}(${JSON.stringify(Array.from(constant))})`);
+ break;
+ }
+ }
+ return `{ ${ results.join() } }`;
+}
+
+function cpuKernelString(cpuKernel, name) {
+ const header = [];
+ const thisProperties = [];
+ const beforeReturn = [];
+
+ const useFunctionKeyword = !/^function/.test(cpuKernel.color.toString());
+
+ header.push(
+ ' const { context, canvas, constants: incomingConstants } = settings;',
+ ` const output = new Int32Array(${JSON.stringify(Array.from(cpuKernel.output))});`,
+ ` const _constantTypes = ${JSON.stringify(cpuKernel.constantTypes)};`,
+ ` const _constants = ${constantsToString(cpuKernel.constants, cpuKernel.constantTypes)};`
+ );
+
+ thisProperties.push(
+ ' constants: _constants,',
+ ' context,',
+ ' output,',
+ ' thread: {x: 0, y: 0, z: 0},'
+ );
+
+ if (cpuKernel.graphical) {
+ header.push(` const _imageData = context.createImageData(${cpuKernel.output[0]}, ${cpuKernel.output[1]});`);
+ header.push(` const _colorData = new Uint8ClampedArray(${cpuKernel.output[0]} * ${cpuKernel.output[1]} * 4);`);
+
+ const colorFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.color.toString(), {
+ thisLookup: (propertyName) => {
+ switch (propertyName) {
+ case '_colorData':
+ return '_colorData';
+ case '_imageData':
+ return '_imageData';
+ case 'output':
+ return 'output';
+ case 'thread':
+ return 'this.thread';
+ }
+ return JSON.stringify(cpuKernel[propertyName]);
+ },
+ findDependency: (object, name) => {
+ return null;
+ }
+ });
+
+ const getPixelsFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.getPixels.toString(), {
+ thisLookup: (propertyName) => {
+ switch (propertyName) {
+ case '_colorData':
+ return '_colorData';
+ case '_imageData':
+ return '_imageData';
+ case 'output':
+ return 'output';
+ case 'thread':
+ return 'this.thread';
+ }
+ return JSON.stringify(cpuKernel[propertyName]);
+ },
+ findDependency: () => {
+ return null;
+ }
+ });
+
+ thisProperties.push(
+ ' _imageData,',
+ ' _colorData,',
+ ` color: ${colorFn},`
+ );
+
+ beforeReturn.push(
+ ` kernel.getPixels = ${getPixelsFn};`
+ );
+ }
+
+ const constantTypes = [];
+ const constantKeys = Object.keys(cpuKernel.constantTypes);
+ for (let i = 0; i < constantKeys.length; i++) {
+ constantTypes.push(cpuKernel.constantTypes[constantKeys]);
+ }
+ if (cpuKernel.argumentTypes.indexOf('HTMLImageArray') !== -1 || constantTypes.indexOf('HTMLImageArray') !== -1) {
+ const flattenedImageTo3DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._imageTo3DArray.toString(), {
+ doNotDefine: ['canvas'],
+ findDependency: (object, name) => {
+ if (object === 'this') {
+ return (useFunctionKeyword ? 'function ' : '') + cpuKernel[name].toString();
+ }
+ return null;
+ },
+ thisLookup: (propertyName) => {
+ switch (propertyName) {
+ case 'canvas':
+ return;
+ case 'context':
+ return 'context';
+ }
+ }
+ });
+ beforeReturn.push(flattenedImageTo3DArray);
+ thisProperties.push(` _mediaTo2DArray,`);
+ thisProperties.push(` _imageTo3DArray,`);
+ } else if (cpuKernel.argumentTypes.indexOf('HTMLImage') !== -1 || constantTypes.indexOf('HTMLImage') !== -1) {
+ const flattenedImageTo2DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._mediaTo2DArray.toString(), {
+ findDependency: (object, name) => {
+ return null;
+ },
+ thisLookup: (propertyName) => {
+ switch (propertyName) {
+ case 'canvas':
+ return 'settings.canvas';
+ case 'context':
+ return 'settings.context';
+ }
+ throw new Error('unhandled thisLookup');
+ }
+ });
+ beforeReturn.push(flattenedImageTo2DArray);
+ thisProperties.push(` _mediaTo2DArray,`);
+ }
+
+ return `function(settings) {
+${ header.join('\n') }
+ for (const p in _constantTypes) {
+ if (!_constantTypes.hasOwnProperty(p)) continue;
+ const type = _constantTypes[p];
+ switch (type) {
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ case 'Boolean':
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ case 'Matrix(2)':
+ case 'Matrix(3)':
+ case 'Matrix(4)':
+ if (incomingConstants.hasOwnProperty(p)) {
+ console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned');
+ }
+ continue;
+ }
+ if (!incomingConstants.hasOwnProperty(p)) {
+ throw new Error('constant ' + p + ' not found');
+ }
+ _constants[p] = incomingConstants[p];
+ }
+ const kernel = (function() {
+${cpuKernel._kernelString}
+ })
+ .apply({ ${thisProperties.join('\n')} });
+ ${ beforeReturn.join('\n') }
+ return kernel;
+}`;
+}
+
+module.exports = {
+ cpuKernelString
+};
+},{"../../utils":113}],7:[function(require,module,exports){
+const { Kernel } = require('../kernel');
+const { FunctionBuilder } = require('../function-builder');
+const { CPUFunctionNode } = require('./function-node');
+const { utils } = require('../../utils');
+const { cpuKernelString } = require('./kernel-string');
+
+class CPUKernel extends Kernel {
+ static getFeatures() {
+ return this.features;
+ }
+ static get features() {
+ return Object.freeze({
+ kernelMap: true,
+ isIntegerDivisionAccurate: true
+ });
+ }
+ static get isSupported() {
+ return true;
+ }
+ static isContextMatch(context) {
+ return false;
+ }
+ 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(combinedKernel) {
+ return combinedKernel;
+ }
+
+ static getSignature(kernel, argumentTypes) {
+ return 'cpu' + (argumentTypes.length > 0 ? ':' + argumentTypes.join(',') : '');
+ }
+
+ constructor(source, settings) {
+ super(source, settings);
+ this.mergeSettings(source.settings || settings);
+
+ this._imageData = null;
+ this._colorData = null;
+ this._kernelString = null;
+ this._prependedString = [];
+ this.thread = {
+ x: 0,
+ y: 0,
+ z: 0
+ };
+ this.translatedSources = null;
+ }
+
+ initCanvas() {
+ if (typeof document !== 'undefined') {
+ return document.createElement('canvas');
+ } else if (typeof OffscreenCanvas !== 'undefined') {
+ return new OffscreenCanvas(0, 0);
+ }
+ }
+
+ initContext() {
+ if (!this.canvas) return null;
+ return this.canvas.getContext('2d');
+ }
+
+ initPlugins(settings) {
+ return [];
+ }
+
+ validateSettings(args) {
+ 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 = utils.getDimensions(argType);
+ } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') {
+ this.output = args[0].output;
+ } else {
+ throw new Error('Auto output not supported for input type: ' + argType);
+ }
+ }
+
+ if (this.graphical) {
+ if (this.output.length !== 2) {
+ throw new Error('Output must have 2 dimensions on graphical mode');
+ }
+ }
+
+ this.checkOutput();
+ }
+
+ translateSource() {
+ this.leadingReturnStatement = this.output.length > 1 ? 'resultX[x] = ' : 'result[x] = ';
+ if (this.subKernels) {
+ const followingReturnStatement = [];
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const {
+ name
+ } = this.subKernels[i];
+ followingReturnStatement.push(this.output.length > 1 ? `resultX_${ name }[x] = subKernelResult_${ name };\n` : `result_${ name }[x] = subKernelResult_${ name };\n`);
+ }
+ this.followingReturnStatement = followingReturnStatement.join('');
+ }
+ const functionBuilder = FunctionBuilder.fromKernel(this, CPUFunctionNode);
+ this.translatedSources = functionBuilder.getPrototypes('kernel');
+ if (!this.graphical && !this.returnType) {
+ this.returnType = functionBuilder.getKernelResultType();
+ }
+ }
+
+ build() {
+ if (this.built) return;
+ this.setupConstants();
+ this.setupArguments(arguments);
+ this.validateSettings(arguments);
+ this.translateSource();
+
+ if (this.graphical) {
+ const {
+ canvas,
+ output
+ } = this;
+ if (!canvas) {
+ throw new Error('no canvas available for using graphical output');
+ }
+ const width = output[0];
+ const height = output[1] || 1;
+ canvas.width = width;
+ canvas.height = height;
+ this._imageData = this.context.createImageData(width, height);
+ this._colorData = new Uint8ClampedArray(width * height * 4);
+ }
+
+ const kernelString = this.getKernelString();
+ this.kernelString = kernelString;
+
+ if (this.debug) {
+ console.log('Function output:');
+ console.log(kernelString);
+ }
+
+ try {
+ this.run = new Function([], kernelString).bind(this)();
+ } catch (e) {
+ console.error('An error occurred compiling the javascript: ', e);
+ }
+ this.buildSignature(arguments);
+ this.built = true;
+ }
+
+ color(r, g, b, a) {
+ if (typeof a === 'undefined') {
+ a = 1;
+ }
+
+ r = Math.floor(r * 255);
+ g = Math.floor(g * 255);
+ b = Math.floor(b * 255);
+ a = Math.floor(a * 255);
+
+ const width = this.output[0];
+ const height = this.output[1];
+
+ const x = this.thread.x;
+ const y = height - this.thread.y - 1;
+
+ const index = x + y * width;
+
+ this._colorData[index * 4 + 0] = r;
+ this._colorData[index * 4 + 1] = g;
+ this._colorData[index * 4 + 2] = b;
+ this._colorData[index * 4 + 3] = a;
+ }
+
+ getKernelString() {
+ if (this._kernelString !== null) return this._kernelString;
+
+ let kernelThreadString = null;
+ let {
+ translatedSources
+ } = this;
+ if (translatedSources.length > 1) {
+ translatedSources = translatedSources.filter(fn => {
+ if (/^function/.test(fn)) return fn;
+ kernelThreadString = fn;
+ return false;
+ });
+ } else {
+ kernelThreadString = translatedSources.shift();
+ }
+ return this._kernelString = ` const LOOP_MAX = ${ this._getLoopMaxString() };
+ ${ this.injectedNative || '' }
+ const _this = this;
+ ${ this._resultKernelHeader() }
+ ${ this._processConstants() }
+ return (${ this.argumentNames.map(argumentName => 'user_' + argumentName).join(', ') }) => {
+ ${ this._prependedString.join('') }
+ ${ this._earlyThrows() }
+ ${ this._processArguments() }
+ ${ this.graphical ? this._graphicalKernelBody(kernelThreadString) : this._resultKernelBody(kernelThreadString) }
+ ${ translatedSources.length > 0 ? translatedSources.join('\n') : '' }
+ };`;
+ }
+
+ toString() {
+ return cpuKernelString(this);
+ }
+
+ _getLoopMaxString() {
+ return (
+ this.loopMaxIterations ?
+ ` ${ parseInt(this.loopMaxIterations) };` :
+ ' 1000;'
+ );
+ }
+
+ _processConstants() {
+ if (!this.constants) return '';
+
+ const result = [];
+ for (let p in this.constants) {
+ const type = this.constantTypes[p];
+ switch (type) {
+ case 'HTMLCanvas':
+ case 'OffscreenCanvas':
+ case 'HTMLImage':
+ case 'ImageBitmap':
+ case 'ImageData':
+ case 'HTMLVideo':
+ result.push(` const constants_${p} = this._mediaTo2DArray(this.constants.${p});\n`);
+ break;
+ case 'HTMLImageArray':
+ result.push(` const constants_${p} = this._imageTo3DArray(this.constants.${p});\n`);
+ break;
+ case 'Input':
+ result.push(` const constants_${p} = this.constants.${p}.value;\n`);
+ break;
+ default:
+ result.push(` const constants_${p} = this.constants.${p};\n`);
+ }
+ }
+ return result.join('');
+ }
+
+ _earlyThrows() {
+ if (this.graphical) return '';
+ if (this.immutable) return '';
+ if (!this.pipeline) return '';
+ const arrayArguments = [];
+ for (let i = 0; i < this.argumentTypes.length; i++) {
+ if (this.argumentTypes[i] === 'Array') {
+ arrayArguments.push(this.argumentNames[i]);
+ }
+ }
+ if (arrayArguments.length === 0) return '';
+ const checks = [];
+ for (let i = 0; i < arrayArguments.length; i++) {
+ const argumentName = arrayArguments[i];
+ const checkSubKernels = this._mapSubKernels(subKernel => `user_${argumentName} === result_${subKernel.name}`).join(' || ');
+ checks.push(`user_${argumentName} === result${checkSubKernels ? ` || ${checkSubKernels}` : ''}`);
+ }
+ return `if (${checks.join(' || ')}) throw new Error('Source and destination arrays are the same. Use immutable = true');`;
+ }
+
+ _processArguments() {
+ const result = [];
+ for (let i = 0; i < this.argumentTypes.length; i++) {
+ const variableName = `user_${this.argumentNames[i]}`;
+ switch (this.argumentTypes[i]) {
+ case 'HTMLCanvas':
+ case 'OffscreenCanvas':
+ case 'HTMLImage':
+ case 'ImageBitmap':
+ case 'ImageData':
+ case 'HTMLVideo':
+ result.push(` ${variableName} = this._mediaTo2DArray(${variableName});\n`);
+ break;
+ case 'HTMLImageArray':
+ result.push(` ${variableName} = this._imageTo3DArray(${variableName});\n`);
+ break;
+ case 'Input':
+ result.push(` ${variableName} = ${variableName}.value;\n`);
+ break;
+ case 'ArrayTexture(1)':
+ case 'ArrayTexture(2)':
+ case 'ArrayTexture(3)':
+ case 'ArrayTexture(4)':
+ case 'NumberTexture':
+ case 'MemoryOptimizedNumberTexture':
+ result.push(`
+ if (${variableName}.toArray) {
+ if (!_this.textureCache) {
+ _this.textureCache = [];
+ _this.arrayCache = [];
+ }
+ const textureIndex = _this.textureCache.indexOf(${variableName});
+ if (textureIndex !== -1) {
+ ${variableName} = _this.arrayCache[textureIndex];
+ } else {
+ _this.textureCache.push(${variableName});
+ ${variableName} = ${variableName}.toArray();
+ _this.arrayCache.push(${variableName});
+ }
+ }`);
+ break;
+ }
+ }
+ return result.join('');
+ }
+
+ _mediaTo2DArray(media) {
+ const canvas = this.canvas;
+ const width = media.width > 0 ? media.width : media.videoWidth;
+ const height = media.height > 0 ? media.height : media.videoHeight;
+ if (canvas.width < width) {
+ canvas.width = width;
+ }
+ if (canvas.height < height) {
+ canvas.height = height;
+ }
+ const ctx = this.context;
+ let pixelsData;
+ if (media.constructor === ImageData) {
+ pixelsData = media.data;
+ } else {
+ ctx.drawImage(media, 0, 0, width, height);
+ pixelsData = ctx.getImageData(0, 0, width, height).data;
+ }
+ const imageArray = new Array(height);
+ let index = 0;
+ for (let y = height - 1; y >= 0; y--) {
+ const row = imageArray[y] = new Array(width);
+ for (let x = 0; x < width; x++) {
+ const pixel = new Float32Array(4);
+ pixel[0] = pixelsData[index++] / 255;
+ pixel[1] = pixelsData[index++] / 255;
+ pixel[2] = pixelsData[index++] / 255;
+ pixel[3] = pixelsData[index++] / 255;
+ row[x] = pixel;
+ }
+ }
+ return imageArray;
+ }
+
+ getPixels(flip) {
+ const [width, height] = this.output;
+ return flip ? utils.flipPixels(this._imageData.data, width, height) : this._imageData.data.slice(0);
+ }
+
+ _imageTo3DArray(images) {
+ const imagesArray = new Array(images.length);
+ for (let i = 0; i < images.length; i++) {
+ imagesArray[i] = this._mediaTo2DArray(images[i]);
+ }
+ return imagesArray;
+ }
+
+ _resultKernelHeader() {
+ if (this.graphical) return '';
+ if (this.immutable) return '';
+ if (!this.pipeline) return '';
+ switch (this.output.length) {
+ case 1:
+ return this._mutableKernel1DResults();
+ case 2:
+ return this._mutableKernel2DResults();
+ case 3:
+ return this._mutableKernel3DResults();
+ }
+ }
+
+ _resultKernelBody(kernelString) {
+ switch (this.output.length) {
+ case 1:
+ return (!this.immutable && this.pipeline ? this._resultMutableKernel1DLoop(kernelString) : this._resultImmutableKernel1DLoop(kernelString)) + this._kernelOutput();
+ case 2:
+ return (!this.immutable && this.pipeline ? this._resultMutableKernel2DLoop(kernelString) : this._resultImmutableKernel2DLoop(kernelString)) + this._kernelOutput();
+ case 3:
+ return (!this.immutable && this.pipeline ? this._resultMutableKernel3DLoop(kernelString) : this._resultImmutableKernel3DLoop(kernelString)) + this._kernelOutput();
+ default:
+ throw new Error('unsupported size kernel');
+ }
+ }
+
+ _graphicalKernelBody(kernelThreadString) {
+ switch (this.output.length) {
+ case 2:
+ return this._graphicalKernel2DLoop(kernelThreadString) + this._graphicalOutput();
+ default:
+ throw new Error('unsupported size kernel');
+ }
+ }
+
+ _graphicalOutput() {
+ return `
+ this._imageData.data.set(this._colorData);
+ this.context.putImageData(this._imageData, 0, 0);
+ return;`
+ }
+
+ _getKernelResultTypeConstructorString() {
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ return 'Float32Array';
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ return 'Array';
+ default:
+ if (this.graphical) {
+ return 'Float32Array';
+ }
+ throw new Error(`unhandled returnType ${ this.returnType }`);
+ }
+ }
+
+ _resultImmutableKernel1DLoop(kernelString) {
+ const constructorString = this._getKernelResultTypeConstructorString();
+ return ` const outputX = _this.output[0];
+ const result = new ${constructorString}(outputX);
+ ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new ${constructorString}(outputX);\n`).join(' ') }
+ ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') }
+ for (let x = 0; x < outputX; x++) {
+ this.thread.x = x;
+ this.thread.y = 0;
+ this.thread.z = 0;
+ ${ kernelString }
+ }`;
+ }
+
+ _mutableKernel1DResults() {
+ const constructorString = this._getKernelResultTypeConstructorString();
+ return ` const outputX = _this.output[0];
+ const result = new ${constructorString}(outputX);
+ ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new ${constructorString}(outputX);\n`).join(' ') }
+ ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') }`;
+ }
+
+ _resultMutableKernel1DLoop(kernelString) {
+ return ` const outputX = _this.output[0];
+ for (let x = 0; x < outputX; x++) {
+ this.thread.x = x;
+ this.thread.y = 0;
+ this.thread.z = 0;
+ ${ kernelString }
+ }`;
+ }
+
+ _resultImmutableKernel2DLoop(kernelString) {
+ const constructorString = this._getKernelResultTypeConstructorString();
+ return ` const outputX = _this.output[0];
+ const outputY = _this.output[1];
+ const result = new Array(outputY);
+ ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\n`).join(' ') }
+ ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') }
+ for (let y = 0; y < outputY; y++) {
+ this.thread.z = 0;
+ this.thread.y = y;
+ const resultX = result[y] = new ${constructorString}(outputX);
+ ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join('') }
+ for (let x = 0; x < outputX; x++) {
+ this.thread.x = x;
+ ${ kernelString }
+ }
+ }`;
+ }
+
+ _mutableKernel2DResults() {
+ const constructorString = this._getKernelResultTypeConstructorString();
+ return ` const outputX = _this.output[0];
+ const outputY = _this.output[1];
+ const result = new Array(outputY);
+ ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\n`).join(' ') }
+ ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') }
+ for (let y = 0; y < outputY; y++) {
+ const resultX = result[y] = new ${constructorString}(outputX);
+ ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join('') }
+ }`;
+ }
+
+ _resultMutableKernel2DLoop(kernelString) {
+ const constructorString = this._getKernelResultTypeConstructorString();
+ return ` const outputX = _this.output[0];
+ const outputY = _this.output[1];
+ for (let y = 0; y < outputY; y++) {
+ this.thread.z = 0;
+ this.thread.y = y;
+ const resultX = result[y];
+ ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join('') }
+ for (let x = 0; x < outputX; x++) {
+ this.thread.x = x;
+ ${ kernelString }
+ }
+ }`;
+ }
+
+ _graphicalKernel2DLoop(kernelString) {
+ return ` const outputX = _this.output[0];
+ const outputY = _this.output[1];
+ for (let y = 0; y < outputY; y++) {
+ this.thread.z = 0;
+ this.thread.y = y;
+ for (let x = 0; x < outputX; x++) {
+ this.thread.x = x;
+ ${ kernelString }
+ }
+ }`;
+ }
+
+ _resultImmutableKernel3DLoop(kernelString) {
+ const constructorString = this._getKernelResultTypeConstructorString();
+ return ` const outputX = _this.output[0];
+ const outputY = _this.output[1];
+ const outputZ = _this.output[2];
+ const result = new Array(outputZ);
+ ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputZ);\n`).join(' ') }
+ ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') }
+ for (let z = 0; z < outputZ; z++) {
+ this.thread.z = z;
+ const resultY = result[z] = new Array(outputY);
+ ${ this._mapSubKernels(subKernel => `const resultY_${ subKernel.name } = result_${subKernel.name}[z] = new Array(outputY);\n`).join(' ') }
+ for (let y = 0; y < outputY; y++) {
+ this.thread.y = y;
+ const resultX = resultY[y] = new ${constructorString}(outputX);
+ ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = resultY_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join(' ') }
+ for (let x = 0; x < outputX; x++) {
+ this.thread.x = x;
+ ${ kernelString }
+ }
+ }
+ }`;
+ }
+
+ _mutableKernel3DResults() {
+ const constructorString = this._getKernelResultTypeConstructorString();
+ return ` const outputX = _this.output[0];
+ const outputY = _this.output[1];
+ const outputZ = _this.output[2];
+ const result = new Array(outputZ);
+ ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputZ);\n`).join(' ') }
+ ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') }
+ for (let z = 0; z < outputZ; z++) {
+ const resultY = result[z] = new Array(outputY);
+ ${ this._mapSubKernels(subKernel => `const resultY_${ subKernel.name } = result_${subKernel.name}[z] = new Array(outputY);\n`).join(' ') }
+ for (let y = 0; y < outputY; y++) {
+ const resultX = resultY[y] = new ${constructorString}(outputX);
+ ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = resultY_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join(' ') }
+ }
+ }`;
+ }
+
+ _resultMutableKernel3DLoop(kernelString) {
+ return ` const outputX = _this.output[0];
+ const outputY = _this.output[1];
+ const outputZ = _this.output[2];
+ for (let z = 0; z < outputZ; z++) {
+ this.thread.z = z;
+ const resultY = result[z];
+ for (let y = 0; y < outputY; y++) {
+ this.thread.y = y;
+ const resultX = resultY[y];
+ for (let x = 0; x < outputX; x++) {
+ this.thread.x = x;
+ ${ kernelString }
+ }
+ }
+ }`;
+ }
+
+ _kernelOutput() {
+ if (!this.subKernels) {
+ return '\n return result;';
+ }
+ return `\n return {
+ result: result,
+ ${ this.subKernels.map(subKernel => `${ subKernel.property }: result_${ subKernel.name }`).join(',\n ') }
+ };`;
+ }
+
+ _mapSubKernels(fn) {
+ return this.subKernels === null ? [''] :
+ this.subKernels.map(fn);
+ }
+
+ destroy(removeCanvasReference) {
+ if (removeCanvasReference) {
+ delete this.canvas;
+ }
+ }
+
+ static destroyContext(context) {}
+
+ toJSON() {
+ const json = super.toJSON();
+ json.functionNodes = FunctionBuilder.fromKernel(this, CPUFunctionNode).toJSON();
+ return json;
+ }
+
+ setOutput(output) {
+ super.setOutput(output);
+ const [width, height] = this.output;
+ if (this.graphical) {
+ this._imageData = this.context.createImageData(width, height);
+ this._colorData = new Uint8ClampedArray(width * height * 4);
+ }
+ }
+
+ prependString(value) {
+ if (this._kernelString) throw new Error('Kernel already built');
+ this._prependedString.push(value);
+ }
+
+ hasPrependString(value) {
+ return this._prependedString.indexOf(value) > -1;
+ }
+}
+
+module.exports = {
+ CPUKernel
+};
+},{"../../utils":113,"../function-builder":8,"../kernel":35,"./function-node":5,"./kernel-string":6}],8:[function(require,module,exports){
+class FunctionBuilder {
+ static fromKernel(kernel, FunctionNode, extraNodeOptions) {
+ const {
+ kernelArguments,
+ kernelConstants,
+ argumentNames,
+ argumentSizes,
+ argumentBitRatios,
+ constants,
+ constantBitRatios,
+ debug,
+ loopMaxIterations,
+ nativeFunctions,
+ output,
+ optimizeFloatMemory,
+ precision,
+ plugins,
+ source,
+ subKernels,
+ functions,
+ leadingReturnStatement,
+ followingReturnStatement,
+ dynamicArguments,
+ dynamicOutput,
+ } = kernel;
+
+ const argumentTypes = new Array(kernelArguments.length);
+ const constantTypes = {};
+
+ for (let i = 0; i < kernelArguments.length; i++) {
+ argumentTypes[i] = kernelArguments[i].type;
+ }
+
+ for (let i = 0; i < kernelConstants.length; i++) {
+ const kernelConstant = kernelConstants[i];
+ constantTypes[kernelConstant.name] = kernelConstant.type;
+ }
+
+ const needsArgumentType = (functionName, index) => {
+ return functionBuilder.needsArgumentType(functionName, index);
+ };
+
+ const assignArgumentType = (functionName, index, type) => {
+ functionBuilder.assignArgumentType(functionName, index, type);
+ };
+
+ const lookupReturnType = (functionName, ast, requestingNode) => {
+ return functionBuilder.lookupReturnType(functionName, ast, requestingNode);
+ };
+
+ const lookupFunctionArgumentTypes = (functionName) => {
+ return functionBuilder.lookupFunctionArgumentTypes(functionName);
+ };
+
+ const lookupFunctionArgumentName = (functionName, argumentIndex) => {
+ return functionBuilder.lookupFunctionArgumentName(functionName, argumentIndex);
+ };
+
+ const lookupFunctionArgumentBitRatio = (functionName, argumentName) => {
+ return functionBuilder.lookupFunctionArgumentBitRatio(functionName, argumentName);
+ };
+
+ const triggerImplyArgumentType = (functionName, i, argumentType, requestingNode) => {
+ functionBuilder.assignArgumentType(functionName, i, argumentType, requestingNode);
+ };
+
+ const triggerImplyArgumentBitRatio = (functionName, argumentName, calleeFunctionName, argumentIndex) => {
+ functionBuilder.assignArgumentBitRatio(functionName, argumentName, calleeFunctionName, argumentIndex);
+ };
+
+ const onFunctionCall = (functionName, calleeFunctionName, args) => {
+ functionBuilder.trackFunctionCall(functionName, calleeFunctionName, args);
+ };
+
+ const onNestedFunction = (ast, source) => {
+ const argumentNames = [];
+ for (let i = 0; i < ast.params.length; i++) {
+ argumentNames.push(ast.params[i].name);
+ }
+ const nestedFunction = new FunctionNode(source, Object.assign({}, nodeOptions, {
+ returnType: null,
+ ast,
+ name: ast.id.name,
+ argumentNames,
+ lookupReturnType,
+ lookupFunctionArgumentTypes,
+ lookupFunctionArgumentName,
+ lookupFunctionArgumentBitRatio,
+ needsArgumentType,
+ assignArgumentType,
+ triggerImplyArgumentType,
+ triggerImplyArgumentBitRatio,
+ onFunctionCall,
+ }));
+ nestedFunction.traceFunctionAST(ast);
+ functionBuilder.addFunctionNode(nestedFunction);
+ };
+
+ const nodeOptions = Object.assign({
+ isRootKernel: false,
+ onNestedFunction,
+ lookupReturnType,
+ lookupFunctionArgumentTypes,
+ lookupFunctionArgumentName,
+ lookupFunctionArgumentBitRatio,
+ needsArgumentType,
+ assignArgumentType,
+ triggerImplyArgumentType,
+ triggerImplyArgumentBitRatio,
+ onFunctionCall,
+ optimizeFloatMemory,
+ precision,
+ constants,
+ constantTypes,
+ constantBitRatios,
+ debug,
+ loopMaxIterations,
+ output,
+ plugins,
+ dynamicArguments,
+ dynamicOutput,
+ }, extraNodeOptions || {});
+
+ const rootNodeOptions = Object.assign({}, nodeOptions, {
+ isRootKernel: true,
+ name: 'kernel',
+ argumentNames,
+ argumentTypes,
+ argumentSizes,
+ argumentBitRatios,
+ leadingReturnStatement,
+ followingReturnStatement,
+ });
+
+ if (typeof source === 'object' && source.functionNodes) {
+ return new FunctionBuilder().fromJSON(source.functionNodes, FunctionNode);
+ }
+
+ const rootNode = new FunctionNode(source, rootNodeOptions);
+
+ let functionNodes = null;
+ if (functions) {
+ functionNodes = functions.map((fn) => new FunctionNode(fn.source, {
+ returnType: fn.returnType,
+ argumentTypes: fn.argumentTypes,
+ output,
+ plugins,
+ constants,
+ constantTypes,
+ constantBitRatios,
+ optimizeFloatMemory,
+ precision,
+ lookupReturnType,
+ lookupFunctionArgumentTypes,
+ lookupFunctionArgumentName,
+ lookupFunctionArgumentBitRatio,
+ needsArgumentType,
+ assignArgumentType,
+ triggerImplyArgumentType,
+ triggerImplyArgumentBitRatio,
+ onFunctionCall,
+ onNestedFunction,
+ }));
+ }
+
+ let subKernelNodes = null;
+ if (subKernels) {
+ subKernelNodes = subKernels.map((subKernel) => {
+ const { name, source } = subKernel;
+ return new FunctionNode(source, Object.assign({}, nodeOptions, {
+ name,
+ isSubKernel: true,
+ isRootKernel: false,
+ }));
+ });
+ }
+
+ const functionBuilder = new FunctionBuilder({
+ kernel,
+ rootNode,
+ functionNodes,
+ nativeFunctions,
+ subKernelNodes
+ });
+
+ return functionBuilder;
+ }
+
+ constructor(settings) {
+ settings = settings || {};
+ this.kernel = settings.kernel;
+ this.rootNode = settings.rootNode;
+ this.functionNodes = settings.functionNodes || [];
+ this.subKernelNodes = settings.subKernelNodes || [];
+ this.nativeFunctions = settings.nativeFunctions || [];
+ this.functionMap = {};
+ this.nativeFunctionNames = [];
+ this.lookupChain = [];
+ this.functionNodeDependencies = {};
+ this.functionCalls = {};
+
+ if (this.rootNode) {
+ this.functionMap['kernel'] = this.rootNode;
+ }
+
+ if (this.functionNodes) {
+ for (let i = 0; i < this.functionNodes.length; i++) {
+ this.functionMap[this.functionNodes[i].name] = this.functionNodes[i];
+ }
+ }
+
+ if (this.subKernelNodes) {
+ for (let i = 0; i < this.subKernelNodes.length; i++) {
+ this.functionMap[this.subKernelNodes[i].name] = this.subKernelNodes[i];
+ }
+ }
+
+ if (this.nativeFunctions) {
+ for (let i = 0; i < this.nativeFunctions.length; i++) {
+ const nativeFunction = this.nativeFunctions[i];
+ this.nativeFunctionNames.push(nativeFunction.name);
+ }
+ }
+ }
+
+ addFunctionNode(functionNode) {
+ if (!functionNode.name) throw new Error('functionNode.name needs set');
+ this.functionMap[functionNode.name] = functionNode;
+ if (functionNode.isRootKernel) {
+ this.rootNode = functionNode;
+ }
+ }
+
+ traceFunctionCalls(functionName, retList) {
+ functionName = functionName || 'kernel';
+ retList = retList || [];
+
+ if (this.nativeFunctionNames.indexOf(functionName) > -1) {
+ const nativeFunctionIndex = retList.indexOf(functionName);
+ if (nativeFunctionIndex === -1) {
+ retList.push(functionName);
+ } else {
+ const dependantNativeFunctionName = retList.splice(nativeFunctionIndex, 1)[0];
+ retList.push(dependantNativeFunctionName);
+ }
+ return retList;
+ }
+
+ const functionNode = this.functionMap[functionName];
+ if (functionNode) {
+ const functionIndex = retList.indexOf(functionName);
+ if (functionIndex === -1) {
+ retList.push(functionName);
+ functionNode.toString();
+ for (let i = 0; i < functionNode.calledFunctions.length; ++i) {
+ this.traceFunctionCalls(functionNode.calledFunctions[i], retList);
+ }
+ } else {
+ const dependantFunctionName = retList.splice(functionIndex, 1)[0];
+ retList.push(dependantFunctionName);
+ }
+ }
+
+ return retList;
+ }
+
+ getPrototypeString(functionName) {
+ return this.getPrototypes(functionName).join('\n');
+ }
+
+ getPrototypes(functionName) {
+ if (this.rootNode) {
+ this.rootNode.toString();
+ }
+ if (functionName) {
+ return this.getPrototypesFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse());
+ }
+ return this.getPrototypesFromFunctionNames(Object.keys(this.functionMap));
+ }
+
+ getStringFromFunctionNames(functionList) {
+ const ret = [];
+ for (let i = 0; i < functionList.length; ++i) {
+ const node = this.functionMap[functionList[i]];
+ if (node) {
+ ret.push(this.functionMap[functionList[i]].toString());
+ }
+ }
+ return ret.join('\n');
+ }
+
+ getPrototypesFromFunctionNames(functionList) {
+ const ret = [];
+ for (let i = 0; i < functionList.length; ++i) {
+ const functionName = functionList[i];
+ const functionIndex = this.nativeFunctionNames.indexOf(functionName);
+ if (functionIndex > -1) {
+ ret.push(this.nativeFunctions[functionIndex].source);
+ continue;
+ }
+ const node = this.functionMap[functionName];
+ if (node) {
+ ret.push(node.toString());
+ }
+ }
+ return ret;
+ }
+
+ toJSON() {
+ return this.traceFunctionCalls(this.rootNode.name).reverse().map(name => {
+ const nativeIndex = this.nativeFunctions.indexOf(name);
+ if (nativeIndex > -1) {
+ return {
+ name,
+ source: this.nativeFunctions[nativeIndex].source
+ };
+ } else if (this.functionMap[name]) {
+ return this.functionMap[name].toJSON();
+ } else {
+ throw new Error(`function ${ name } not found`);
+ }
+ });
+ }
+
+ fromJSON(jsonFunctionNodes, FunctionNode) {
+ this.functionMap = {};
+ for (let i = 0; i < jsonFunctionNodes.length; i++) {
+ const jsonFunctionNode = jsonFunctionNodes[i];
+ this.functionMap[jsonFunctionNode.settings.name] = new FunctionNode(jsonFunctionNode.ast, jsonFunctionNode.settings);
+ }
+ return this;
+ }
+
+ getString(functionName) {
+ if (functionName) {
+ return this.getStringFromFunctionNames(this.traceFunctionCalls(functionName).reverse());
+ }
+ return this.getStringFromFunctionNames(Object.keys(this.functionMap));
+ }
+
+ lookupReturnType(functionName, ast, requestingNode) {
+ if (ast.type !== 'CallExpression') {
+ throw new Error(`expected ast type of "CallExpression", but is ${ ast.type }`);
+ }
+ if (this._isNativeFunction(functionName)) {
+ return this._lookupNativeFunctionReturnType(functionName);
+ } else if (this._isFunction(functionName)) {
+ const node = this._getFunction(functionName);
+ if (node.returnType) {
+ return node.returnType;
+ } else {
+ for (let i = 0; i < this.lookupChain.length; i++) {
+ if (this.lookupChain[i].ast === ast) {
+ if (node.argumentTypes.length === 0 && ast.arguments.length > 0) {
+ const args = ast.arguments;
+ for (let j = 0; j < args.length; j++) {
+ this.lookupChain.push({
+ name: requestingNode.name,
+ ast: args[i],
+ requestingNode
+ });
+ node.argumentTypes[j] = requestingNode.getType(args[j]);
+ this.lookupChain.pop();
+ }
+ return node.returnType = node.getType(node.getJsAST());
+ }
+
+ throw new Error('circlical logic detected!');
+ }
+ }
+ this.lookupChain.push({
+ name: requestingNode.name,
+ ast,
+ requestingNode
+ });
+ const type = node.getType(node.getJsAST());
+ this.lookupChain.pop();
+ return node.returnType = type;
+ }
+ }
+
+ return null;
+ }
+
+ _getFunction(functionName) {
+ if (!this._isFunction(functionName)) {
+ new Error(`Function ${functionName} not found`);
+ }
+ return this.functionMap[functionName];
+ }
+
+ _isFunction(functionName) {
+ return Boolean(this.functionMap[functionName]);
+ }
+
+ _getNativeFunction(functionName) {
+ for (let i = 0; i < this.nativeFunctions.length; i++) {
+ if (this.nativeFunctions[i].name === functionName) return this.nativeFunctions[i];
+ }
+ return null;
+ }
+
+ _isNativeFunction(functionName) {
+ return Boolean(this._getNativeFunction(functionName));
+ }
+
+ _lookupNativeFunctionReturnType(functionName) {
+ let nativeFunction = this._getNativeFunction(functionName);
+ if (nativeFunction) {
+ return nativeFunction.returnType;
+ }
+ throw new Error(`Native function ${ functionName } not found`);
+ }
+
+ lookupFunctionArgumentTypes(functionName) {
+ if (this._isNativeFunction(functionName)) {
+ return this._getNativeFunction(functionName).argumentTypes;
+ } else if (this._isFunction(functionName)) {
+ return this._getFunction(functionName).argumentTypes;
+ }
+ return null;
+ }
+
+ lookupFunctionArgumentName(functionName, argumentIndex) {
+ return this._getFunction(functionName).argumentNames[argumentIndex];
+ }
+
+ lookupFunctionArgumentBitRatio(functionName, argumentName) {
+ if (!this._isFunction(functionName)) {
+ throw new Error('function not found');
+ }
+ if (this.rootNode.name === functionName) {
+ const i = this.rootNode.argumentNames.indexOf(argumentName);
+ if (i !== -1) {
+ return this.rootNode.argumentBitRatios[i];
+ }
+ }
+ const node = this._getFunction(functionName);
+ const i = node.argumentNames.indexOf(argumentName);
+ if (i === -1) {
+ throw new Error('argument not found');
+ }
+ const bitRatio = node.argumentBitRatios[i];
+ if (typeof bitRatio !== 'number') {
+ throw new Error('argument bit ratio not found');
+ }
+ return bitRatio;
+ }
+
+ needsArgumentType(functionName, i) {
+ if (!this._isFunction(functionName)) return false;
+ const fnNode = this._getFunction(functionName);
+ return !fnNode.argumentTypes[i];
+ }
+
+ assignArgumentType(functionName, i, argumentType, requestingNode) {
+ if (!this._isFunction(functionName)) return;
+ const fnNode = this._getFunction(functionName);
+ if (!fnNode.argumentTypes[i]) {
+ fnNode.argumentTypes[i] = argumentType;
+ }
+ }
+
+ assignArgumentBitRatio(functionName, argumentName, calleeFunctionName, argumentIndex) {
+ const node = this._getFunction(functionName);
+ if (this._isNativeFunction(calleeFunctionName)) return null;
+ const calleeNode = this._getFunction(calleeFunctionName);
+ const i = node.argumentNames.indexOf(argumentName);
+ if (i === -1) {
+ throw new Error(`Argument ${argumentName} not found in arguments from function ${functionName}`);
+ }
+ const bitRatio = node.argumentBitRatios[i];
+ if (typeof bitRatio !== 'number') {
+ throw new Error(`Bit ratio for argument ${argumentName} not found in function ${functionName}`);
+ }
+ if (!calleeNode.argumentBitRatios) {
+ calleeNode.argumentBitRatios = new Array(calleeNode.argumentNames.length);
+ }
+ const calleeBitRatio = calleeNode.argumentBitRatios[i];
+ if (typeof calleeBitRatio === 'number') {
+ if (calleeBitRatio !== bitRatio) {
+ throw new Error(`Incompatible bit ratio found at function ${functionName} at argument ${argumentName}`);
+ }
+ return calleeBitRatio;
+ }
+ calleeNode.argumentBitRatios[i] = bitRatio;
+ return bitRatio;
+ }
+
+ trackFunctionCall(functionName, calleeFunctionName, args) {
+ if (!this.functionNodeDependencies[functionName]) {
+ this.functionNodeDependencies[functionName] = new Set();
+ this.functionCalls[functionName] = [];
+ }
+ this.functionNodeDependencies[functionName].add(calleeFunctionName);
+ this.functionCalls[functionName].push(args);
+ }
+
+ getKernelResultType() {
+ return this.rootNode.returnType || this.rootNode.getType(this.rootNode.ast);
+ }
+
+ getSubKernelResultType(index) {
+ const subKernelNode = this.subKernelNodes[index];
+ let called = false;
+ for (let functionCallIndex = 0; functionCallIndex < this.rootNode.functionCalls.length; functionCallIndex++) {
+ const functionCall = this.rootNode.functionCalls[functionCallIndex];
+ if (functionCall.ast.callee.name === subKernelNode.name) {
+ called = true;
+ }
+ }
+ if (!called) {
+ throw new Error(`SubKernel ${ subKernelNode.name } never called by kernel`);
+ }
+ return subKernelNode.returnType || subKernelNode.getType(subKernelNode.getJsAST());
+ }
+
+ getReturnTypes() {
+ const result = {
+ [this.rootNode.name]: this.rootNode.getType(this.rootNode.ast),
+ };
+ const list = this.traceFunctionCalls(this.rootNode.name);
+ for (let i = 0; i < list.length; i++) {
+ const functionName = list[i];
+ const functionNode = this.functionMap[functionName];
+ result[functionName] = functionNode.getType(functionNode.ast);
+ }
+ return result;
+ }
+}
+
+module.exports = {
+ FunctionBuilder
+};
+},{}],9:[function(require,module,exports){
+const acorn = require('acorn');
+const { utils } = require('../utils');
+const { FunctionTracer } = require('./function-tracer');
+
+class FunctionNode {
+ constructor(source, settings) {
+ if (!source && !settings.ast) {
+ throw new Error('source parameter is missing');
+ }
+ settings = settings || {};
+ this.source = source;
+ this.ast = null;
+ this.name = typeof source === 'string' ? settings.isRootKernel ?
+ 'kernel' :
+ (settings.name || utils.getFunctionNameFromString(source)) : null;
+ this.calledFunctions = [];
+ this.constants = {};
+ this.constantTypes = {};
+ this.constantBitRatios = {};
+ this.isRootKernel = false;
+ this.isSubKernel = false;
+ 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 = (typeof this.source === 'string' ? utils.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 = false;
+ this.fixIntegerDivisionAccuracy = null;
+
+ if (settings) {
+ for (const p in settings) {
+ if (!settings.hasOwnProperty(p)) continue;
+ if (!this.hasOwnProperty(p)) continue;
+ this[p] = settings[p];
+ }
+ }
+
+ this.literalTypes = {};
+
+ this.validate();
+ this._string = null;
+ this._internalVariableNames = {};
+ }
+
+ validate() {
+ if (typeof this.source !== 'string' && !this.ast) {
+ throw new Error('this.source not a string');
+ }
+
+ if (!this.ast && !utils.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(name) {
+ if (!this.constants) return false;
+ return this.constants.hasOwnProperty(name);
+ }
+
+ isInput(argumentName) {
+ return this.argumentTypes[this.argumentNames.indexOf(argumentName)] === 'Input';
+ }
+
+ pushState(state) {
+ this.states.push(state);
+ }
+
+ popState(state) {
+ if (this.state !== state) {
+ throw new Error(`Cannot popState ${ state } when in ${ this.state }`);
+ }
+ this.states.pop();
+ }
+
+ isState(state) {
+ return this.state === state;
+ }
+
+ get state() {
+ return this.states[this.states.length - 1];
+ }
+
+ astMemberExpressionUnroll(ast) {
+ if (ast.type === 'Identifier') {
+ return ast.name;
+ } else if (ast.type === 'ThisExpression') {
+ return 'this';
+ }
+
+ if (ast.type === 'MemberExpression') {
+ if (ast.object && ast.property) {
+ if (ast.object.hasOwnProperty('name') && ast.object.name !== 'Math') {
+ return this.astMemberExpressionUnroll(ast.property);
+ }
+
+ return (
+ this.astMemberExpressionUnroll(ast.object) +
+ '.' +
+ this.astMemberExpressionUnroll(ast.property)
+ );
+ }
+ }
+
+ if (ast.hasOwnProperty('expressions')) {
+ const firstExpression = ast.expressions[0];
+ if (firstExpression.type === 'Literal' && firstExpression.value === 0 && ast.expressions.length === 2) {
+ return this.astMemberExpressionUnroll(ast.expressions[1]);
+ }
+ }
+
+ throw this.astErrorOutput('Unknown astMemberExpressionUnroll', ast);
+ }
+
+ getJsAST(inParser) {
+ if (this.ast) {
+ return this.ast;
+ }
+ if (typeof this.source === 'object') {
+ this.traceFunctionAST(this.source);
+ return this.ast = this.source;
+ }
+
+ inParser = inParser || acorn;
+ if (inParser === null) {
+ throw new Error('Missing JS to AST parser');
+ }
+
+ const ast = Object.freeze(inParser.parse(`const parser_${ this.name } = ${ this.source };`, {
+ locations: true
+ }));
+ const functionAST = ast.body[0].declarations[0].init;
+ this.traceFunctionAST(functionAST);
+
+ if (!ast) {
+ throw new Error('Failed to parse JS code');
+ }
+
+ return this.ast = functionAST;
+ }
+
+ traceFunctionAST(ast) {
+ const { contexts, declarations, functions, identifiers, functionCalls } = new FunctionTracer(ast);
+ this.contexts = contexts;
+ this.identifiers = identifiers;
+ this.functionCalls = functionCalls;
+ this.functions = functions;
+ for (let i = 0; i < declarations.length; i++) {
+ const declaration = declarations[i];
+ const { ast, inForLoopInit, inForLoopTest } = declaration;
+ const { init } = ast;
+ const dependencies = this.getDependencies(init);
+ let valueType = null;
+
+ if (inForLoopInit && inForLoopTest) {
+ valueType = 'Integer';
+ } else {
+ if (init) {
+ const realType = this.getType(init);
+ switch (realType) {
+ case 'Integer':
+ case 'Float':
+ case 'Number':
+ if (init.type === 'MemberExpression') {
+ valueType = realType;
+ } else {
+ valueType = 'Number';
+ }
+ break;
+ case 'LiteralInteger':
+ valueType = 'Number';
+ break;
+ default:
+ valueType = realType;
+ }
+ }
+ }
+ declaration.valueType = valueType;
+ declaration.dependencies = dependencies;
+ declaration.isSafe = this.isSafeDependencies(dependencies);
+ }
+
+ for (let i = 0; i < functions.length; i++) {
+ this.onNestedFunction(functions[i], this.source);
+ }
+ }
+
+ getDeclaration(ast) {
+ for (let i = 0; i < this.identifiers.length; i++) {
+ const identifier = this.identifiers[i];
+ if (ast === identifier.ast) {
+ return identifier.declaration;
+ }
+ }
+ return null;
+ }
+
+ getVariableType(ast) {
+ if (ast.type !== 'Identifier') {
+ throw new Error(`ast of ${ast.type} not "Identifier"`);
+ }
+ let type = null;
+ const argumentIndex = this.argumentNames.indexOf(ast.name);
+ if (argumentIndex === -1) {
+ const declaration = this.getDeclaration(ast);
+ if (declaration) {
+ return declaration.valueType;
+ }
+ } else {
+ const argumentType = this.argumentTypes[argumentIndex];
+ if (argumentType) {
+ type = argumentType;
+ }
+ }
+ if (!type && this.strictTypingChecking) {
+ throw new Error(`Declaration of ${name} not found`);
+ }
+ return type;
+ }
+
+ getLookupType(type) {
+ if (!typeLookupMap.hasOwnProperty(type)) {
+ throw new Error(`unknown typeLookupMap ${ type }`);
+ }
+ return typeLookupMap[type];
+ }
+
+ getConstantType(constantName) {
+ if (this.constantTypes[constantName]) {
+ const type = this.constantTypes[constantName];
+ if (type === 'Float') {
+ return 'Number';
+ } else {
+ return type;
+ }
+ }
+ throw new Error(`Type for constant "${ constantName }" not declared`);
+ }
+
+ toString() {
+ if (this._string) return this._string;
+ return this._string = this.astGeneric(this.getJsAST(), []).join('').trim();
+ }
+
+ toJSON() {
+ const settings = {
+ source: this.source,
+ name: this.name,
+ constants: this.constants,
+ constantTypes: this.constantTypes,
+ isRootKernel: this.isRootKernel,
+ isSubKernel: this.isSubKernel,
+ debug: this.debug,
+ output: this.output,
+ loopMaxIterations: this.loopMaxIterations,
+ argumentNames: this.argumentNames,
+ argumentTypes: this.argumentTypes,
+ argumentSizes: this.argumentSizes,
+ returnType: this.returnType,
+ leadingReturnStatement: this.leadingReturnStatement,
+ followingReturnStatement: this.followingReturnStatement,
+ };
+
+ return {
+ ast: this.ast,
+ settings
+ };
+ }
+
+ getType(ast) {
+ if (Array.isArray(ast)) {
+ return this.getType(ast[ast.length - 1]);
+ }
+ switch (ast.type) {
+ case 'BlockStatement':
+ return this.getType(ast.body);
+ case 'ArrayExpression':
+ const childType = this.getType(ast.elements[0]);
+ switch (childType) {
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ return `Matrix(${ast.elements.length})`;
+ }
+ return `Array(${ ast.elements.length })`;
+ case 'Literal':
+ const literalKey = this.astKey(ast);
+ if (this.literalTypes[literalKey]) {
+ return this.literalTypes[literalKey];
+ }
+ if (Number.isInteger(ast.value)) {
+ return 'LiteralInteger';
+ } else if (ast.value === true || ast.value === false) {
+ return 'Boolean';
+ } else {
+ return 'Number';
+ }
+ case 'AssignmentExpression':
+ return this.getType(ast.left);
+ case 'CallExpression':
+ if (this.isAstMathFunction(ast)) {
+ return 'Number';
+ }
+ if (!ast.callee || !ast.callee.name) {
+ if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[ast.callee.expressions.length - 1].property.name) {
+ const functionName = ast.callee.expressions[ast.callee.expressions.length - 1].property.name;
+ this.inferArgumentTypesIfNeeded(functionName, ast.arguments);
+ return this.lookupReturnType(functionName, ast, this);
+ }
+ if (this.getVariableSignature(ast.callee, true) === 'this.color') {
+ return null;
+ }
+ if (ast.callee.type === 'MemberExpression' && ast.callee.object && ast.callee.property && ast.callee.property.name && ast.arguments) {
+ const functionName = ast.callee.property.name;
+ this.inferArgumentTypesIfNeeded(functionName, ast.arguments);
+ return this.lookupReturnType(functionName, ast, this);
+ }
+ throw this.astErrorOutput('Unknown call expression', ast);
+ }
+ if (ast.callee && ast.callee.name) {
+ const functionName = ast.callee.name;
+ this.inferArgumentTypesIfNeeded(functionName, ast.arguments);
+ return this.lookupReturnType(functionName, ast, this);
+ }
+ throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast);
+ case 'LogicalExpression':
+ return 'Boolean';
+ case 'BinaryExpression':
+ switch (ast.operator) {
+ case '%':
+ case '/':
+ if (this.fixIntegerDivisionAccuracy) {
+ return 'Number';
+ } else {
+ break;
+ }
+ case '>':
+ case '<':
+ return 'Boolean';
+ case '&':
+ case '|':
+ case '^':
+ case '<<':
+ case '>>':
+ case '>>>':
+ return 'Integer';
+ }
+ const type = this.getType(ast.left);
+ if (this.isState('skip-literal-correction')) return type;
+ if (type === 'LiteralInteger') {
+ const rightType = this.getType(ast.right);
+ if (rightType === 'LiteralInteger') {
+ if (ast.left.value % 1 === 0) {
+ return 'Integer';
+ } else {
+ return 'Float';
+ }
+ }
+ return rightType;
+ }
+ return typeLookupMap[type] || type;
+ case 'UpdateExpression':
+ return this.getType(ast.argument);
+ case 'UnaryExpression':
+ if (ast.operator === '~') {
+ return 'Integer';
+ }
+ return this.getType(ast.argument);
+ case 'VariableDeclaration': {
+ const declarations = ast.declarations;
+ let lastType;
+ for (let i = 0; i < declarations.length; i++) {
+ const declaration = declarations[i];
+ lastType = this.getType(declaration);
+ }
+ if (!lastType) {
+ throw this.astErrorOutput(`Unable to find type for declaration`, ast);
+ }
+ return lastType;
+ }
+ case 'VariableDeclarator':
+ const declaration = this.getDeclaration(ast.id);
+ if (!declaration) {
+ throw this.astErrorOutput(`Unable to find declarator`, ast);
+ }
+
+ if (!declaration.valueType) {
+ throw this.astErrorOutput(`Unable to find declarator valueType`, ast);
+ }
+
+ return declaration.valueType;
+ case 'Identifier':
+ if (ast.name === 'Infinity') {
+ return 'Number';
+ }
+ if (this.isAstVariable(ast)) {
+ const signature = this.getVariableSignature(ast);
+ if (signature === 'value') {
+ return this.getCheckVariableType(ast);
+ }
+ }
+ const origin = this.findIdentifierOrigin(ast);
+ if (origin && origin.init) {
+ return this.getType(origin.init);
+ }
+ return null;
+ case 'ReturnStatement':
+ return this.getType(ast.argument);
+ case 'MemberExpression':
+ if (this.isAstMathFunction(ast)) {
+ switch (ast.property.name) {
+ case 'ceil':
+ return 'Integer';
+ case 'floor':
+ return 'Integer';
+ case 'round':
+ return 'Integer';
+ }
+ return 'Number';
+ }
+ if (this.isAstVariable(ast)) {
+ const variableSignature = this.getVariableSignature(ast);
+ switch (variableSignature) {
+ case 'value[]':
+ return this.getLookupType(this.getCheckVariableType(ast.object));
+ case 'value[][]':
+ return this.getLookupType(this.getCheckVariableType(ast.object.object));
+ case 'value[][][]':
+ return this.getLookupType(this.getCheckVariableType(ast.object.object.object));
+ case 'value[][][][]':
+ return this.getLookupType(this.getCheckVariableType(ast.object.object.object.object));
+ case 'value.thread.value':
+ case 'this.thread.value':
+ return 'Integer';
+ case 'this.output.value':
+ return this.dynamicOutput ? 'Integer' : 'LiteralInteger';
+ case 'this.constants.value':
+ return this.getConstantType(ast.property.name);
+ case 'this.constants.value[]':
+ return this.getLookupType(this.getConstantType(ast.object.property.name));
+ case 'this.constants.value[][]':
+ return this.getLookupType(this.getConstantType(ast.object.object.property.name));
+ case 'this.constants.value[][][]':
+ return this.getLookupType(this.getConstantType(ast.object.object.object.property.name));
+ case 'this.constants.value[][][][]':
+ return this.getLookupType(this.getConstantType(ast.object.object.object.object.property.name));
+ case 'fn()[]':
+ case 'fn()[][]':
+ case 'fn()[][][]':
+ return this.getLookupType(this.getType(ast.object));
+ case 'value.value':
+ if (this.isAstMathVariable(ast)) {
+ return 'Number';
+ }
+ switch (ast.property.name) {
+ case 'r':
+ case 'g':
+ case 'b':
+ case 'a':
+ return this.getLookupType(this.getCheckVariableType(ast.object));
+ }
+ case '[][]':
+ return 'Number';
+ }
+ throw this.astErrorOutput('Unhandled getType MemberExpression', ast);
+ }
+ throw this.astErrorOutput('Unhandled getType MemberExpression', ast);
+ case 'ConditionalExpression':
+ return this.getType(ast.consequent);
+ case 'FunctionDeclaration':
+ case 'FunctionExpression':
+ const lastReturn = this.findLastReturn(ast.body);
+ if (lastReturn) {
+ return this.getType(lastReturn);
+ }
+ return null;
+ case 'IfStatement':
+ return this.getType(ast.consequent);
+ case 'SequenceExpression':
+ return this.getType(ast.expressions[ast.expressions.length - 1]);
+ default:
+ throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast);
+ }
+ }
+
+ getCheckVariableType(ast) {
+ const type = this.getVariableType(ast);
+ if (!type) {
+ throw this.astErrorOutput(`${ast.type} is not defined`, ast);
+ }
+ return type;
+ }
+
+ inferArgumentTypesIfNeeded(functionName, args) {
+ for (let i = 0; i < args.length; i++) {
+ if (!this.needsArgumentType(functionName, i)) continue;
+ const type = this.getType(args[i]);
+ if (!type) {
+ throw this.astErrorOutput(`Unable to infer argument ${i}`, args[i]);
+ }
+ this.assignArgumentType(functionName, i, type);
+ }
+ }
+
+ isAstMathVariable(ast) {
+ const mathProperties = [
+ 'E',
+ 'PI',
+ 'SQRT2',
+ 'SQRT1_2',
+ 'LN2',
+ 'LN10',
+ 'LOG2E',
+ 'LOG10E',
+ ];
+ return ast.type === 'MemberExpression' &&
+ ast.object && ast.object.type === 'Identifier' &&
+ ast.object.name === 'Math' &&
+ ast.property &&
+ ast.property.type === 'Identifier' &&
+ mathProperties.indexOf(ast.property.name) > -1;
+ }
+
+ isAstMathFunction(ast) {
+ const mathFunctions = [
+ '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',
+ ];
+ return ast.type === 'CallExpression' &&
+ ast.callee &&
+ ast.callee.type === 'MemberExpression' &&
+ ast.callee.object &&
+ ast.callee.object.type === 'Identifier' &&
+ ast.callee.object.name === 'Math' &&
+ ast.callee.property &&
+ ast.callee.property.type === 'Identifier' &&
+ mathFunctions.indexOf(ast.callee.property.name) > -1;
+ }
+
+ isAstVariable(ast) {
+ return ast.type === 'Identifier' || ast.type === 'MemberExpression';
+ }
+
+ isSafe(ast) {
+ return this.isSafeDependencies(this.getDependencies(ast));
+ }
+
+ isSafeDependencies(dependencies) {
+ return dependencies && dependencies.every ? dependencies.every(dependency => dependency.isSafe) : true;
+ }
+
+ getDependencies(ast, dependencies, isNotSafe) {
+ if (!dependencies) {
+ dependencies = [];
+ }
+ if (!ast) return null;
+ if (Array.isArray(ast)) {
+ for (let i = 0; i < ast.length; i++) {
+ this.getDependencies(ast[i], dependencies, isNotSafe);
+ }
+ return dependencies;
+ }
+ switch (ast.type) {
+ case 'AssignmentExpression':
+ this.getDependencies(ast.left, dependencies, isNotSafe);
+ this.getDependencies(ast.right, dependencies, isNotSafe);
+ return dependencies;
+ case 'ConditionalExpression':
+ this.getDependencies(ast.test, dependencies, isNotSafe);
+ this.getDependencies(ast.alternate, dependencies, isNotSafe);
+ this.getDependencies(ast.consequent, dependencies, isNotSafe);
+ return dependencies;
+ case 'Literal':
+ dependencies.push({
+ origin: 'literal',
+ value: ast.value,
+ isSafe: isNotSafe === true ? false : ast.value > -Infinity && ast.value < Infinity && !isNaN(ast.value)
+ });
+ break;
+ case 'VariableDeclarator':
+ return this.getDependencies(ast.init, dependencies, isNotSafe);
+ case 'Identifier':
+ const declaration = this.getDeclaration(ast);
+ if (declaration) {
+ dependencies.push({
+ name: ast.name,
+ origin: 'declaration',
+ isSafe: isNotSafe ? false : this.isSafeDependencies(declaration.dependencies),
+ });
+ } else if (this.argumentNames.indexOf(ast.name) > -1) {
+ dependencies.push({
+ name: ast.name,
+ origin: 'argument',
+ isSafe: false,
+ });
+ } else if (this.strictTypingChecking) {
+ throw new Error(`Cannot find identifier origin "${ast.name}"`);
+ }
+ break;
+ case 'FunctionDeclaration':
+ return this.getDependencies(ast.body.body[ast.body.body.length - 1], dependencies, isNotSafe);
+ case 'ReturnStatement':
+ return this.getDependencies(ast.argument, dependencies);
+ case 'BinaryExpression':
+ case 'LogicalExpression':
+ isNotSafe = (ast.operator === '/' || ast.operator === '*');
+ this.getDependencies(ast.left, dependencies, isNotSafe);
+ this.getDependencies(ast.right, dependencies, isNotSafe);
+ return dependencies;
+ case 'UnaryExpression':
+ case 'UpdateExpression':
+ return this.getDependencies(ast.argument, dependencies, isNotSafe);
+ case 'VariableDeclaration':
+ return this.getDependencies(ast.declarations, dependencies, isNotSafe);
+ case 'ArrayExpression':
+ dependencies.push({
+ origin: 'declaration',
+ isSafe: true,
+ });
+ return dependencies;
+ case 'CallExpression':
+ dependencies.push({
+ origin: 'function',
+ isSafe: true,
+ });
+ return dependencies;
+ case 'MemberExpression':
+ const details = this.getMemberExpressionDetails(ast);
+ switch (details.signature) {
+ case 'value[]':
+ this.getDependencies(ast.object, dependencies, isNotSafe);
+ break;
+ case 'value[][]':
+ this.getDependencies(ast.object.object, dependencies, isNotSafe);
+ break;
+ case 'value[][][]':
+ this.getDependencies(ast.object.object.object, dependencies, isNotSafe);
+ break;
+ case 'this.output.value':
+ if (this.dynamicOutput) {
+ dependencies.push({
+ name: details.name,
+ origin: 'output',
+ isSafe: false,
+ });
+ }
+ break;
+ }
+ if (details) {
+ if (details.property) {
+ this.getDependencies(details.property, dependencies, isNotSafe);
+ }
+ if (details.xProperty) {
+ this.getDependencies(details.xProperty, dependencies, isNotSafe);
+ }
+ if (details.yProperty) {
+ this.getDependencies(details.yProperty, dependencies, isNotSafe);
+ }
+ if (details.zProperty) {
+ this.getDependencies(details.zProperty, dependencies, isNotSafe);
+ }
+ return dependencies;
+ }
+ case 'SequenceExpression':
+ return this.getDependencies(ast.expressions, dependencies, isNotSafe);
+ default:
+ throw this.astErrorOutput(`Unhandled type ${ ast.type } in getDependencies`, ast);
+ }
+ return dependencies;
+ }
+
+ getVariableSignature(ast, returnRawValue) {
+ if (!this.isAstVariable(ast)) {
+ throw new Error(`ast of type "${ ast.type }" is not a variable signature`);
+ }
+ if (ast.type === 'Identifier') {
+ return 'value';
+ }
+ const signature = [];
+ while (true) {
+ if (!ast) break;
+ if (ast.computed) {
+ signature.push('[]');
+ } else if (ast.type === 'ThisExpression') {
+ signature.unshift('this');
+ } else if (ast.property && ast.property.name) {
+ if (
+ ast.property.name === 'x' ||
+ ast.property.name === 'y' ||
+ ast.property.name === 'z'
+ ) {
+ signature.unshift(returnRawValue ? '.' + ast.property.name : '.value');
+ } else if (
+ ast.property.name === 'constants' ||
+ ast.property.name === 'thread' ||
+ ast.property.name === 'output'
+ ) {
+ signature.unshift('.' + ast.property.name);
+ } else {
+ signature.unshift(returnRawValue ? '.' + ast.property.name : '.value');
+ }
+ } else if (ast.name) {
+ signature.unshift(returnRawValue ? ast.name : 'value');
+ } else if (ast.callee && ast.callee.name) {
+ signature.unshift(returnRawValue ? ast.callee.name + '()' : 'fn()');
+ } else if (ast.elements) {
+ signature.unshift('[]');
+ } else {
+ signature.unshift('unknown');
+ }
+ ast = ast.object;
+ }
+
+ const signatureString = signature.join('');
+ if (returnRawValue) {
+ return signatureString;
+ }
+
+ const allowedExpressions = [
+ '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()[][][]',
+ '[][]',
+ ];
+ if (allowedExpressions.indexOf(signatureString) > -1) {
+ return signatureString;
+ }
+ return null;
+ }
+
+ build() {
+ return this.toString().length > 0;
+ }
+
+ astGeneric(ast, retArr) {
+ if (ast === null) {
+ throw this.astErrorOutput('NULL ast', ast);
+ } else {
+ if (Array.isArray(ast)) {
+ for (let i = 0; i < ast.length; i++) {
+ this.astGeneric(ast[i], retArr);
+ }
+ return retArr;
+ }
+
+ switch (ast.type) {
+ case 'FunctionDeclaration':
+ return this.astFunctionDeclaration(ast, retArr);
+ case 'FunctionExpression':
+ return this.astFunctionExpression(ast, retArr);
+ case 'ReturnStatement':
+ return this.astReturnStatement(ast, retArr);
+ case 'Literal':
+ return this.astLiteral(ast, retArr);
+ case 'BinaryExpression':
+ return this.astBinaryExpression(ast, retArr);
+ case 'Identifier':
+ return this.astIdentifierExpression(ast, retArr);
+ case 'AssignmentExpression':
+ return this.astAssignmentExpression(ast, retArr);
+ case 'ExpressionStatement':
+ return this.astExpressionStatement(ast, retArr);
+ case 'EmptyStatement':
+ return this.astEmptyStatement(ast, retArr);
+ case 'BlockStatement':
+ return this.astBlockStatement(ast, retArr);
+ case 'IfStatement':
+ return this.astIfStatement(ast, retArr);
+ case 'SwitchStatement':
+ return this.astSwitchStatement(ast, retArr);
+ case 'BreakStatement':
+ return this.astBreakStatement(ast, retArr);
+ case 'ContinueStatement':
+ return this.astContinueStatement(ast, retArr);
+ case 'ForStatement':
+ return this.astForStatement(ast, retArr);
+ case 'WhileStatement':
+ return this.astWhileStatement(ast, retArr);
+ case 'DoWhileStatement':
+ return this.astDoWhileStatement(ast, retArr);
+ case 'VariableDeclaration':
+ return this.astVariableDeclaration(ast, retArr);
+ case 'VariableDeclarator':
+ return this.astVariableDeclarator(ast, retArr);
+ case 'ThisExpression':
+ return this.astThisExpression(ast, retArr);
+ case 'SequenceExpression':
+ return this.astSequenceExpression(ast, retArr);
+ case 'UnaryExpression':
+ return this.astUnaryExpression(ast, retArr);
+ case 'UpdateExpression':
+ return this.astUpdateExpression(ast, retArr);
+ case 'LogicalExpression':
+ return this.astLogicalExpression(ast, retArr);
+ case 'MemberExpression':
+ return this.astMemberExpression(ast, retArr);
+ case 'CallExpression':
+ return this.astCallExpression(ast, retArr);
+ case 'ArrayExpression':
+ return this.astArrayExpression(ast, retArr);
+ case 'DebuggerStatement':
+ return this.astDebuggerStatement(ast, retArr);
+ case 'ConditionalExpression':
+ return this.astConditionalExpression(ast, retArr);
+ }
+
+ throw this.astErrorOutput('Unknown ast type : ' + ast.type, ast);
+ }
+ }
+ astErrorOutput(error, ast) {
+ if (typeof this.source !== 'string') {
+ return new Error(error);
+ }
+
+ const debugString = utils.getAstString(this.source, ast);
+ const leadingSource = this.source.substr(ast.start);
+ const splitLines = leadingSource.split(/\n/);
+ const lineBefore = splitLines.length > 0 ? splitLines[splitLines.length - 1] : 0;
+ return new Error(`${error} on line ${ splitLines.length }, position ${ lineBefore.length }:\n ${ debugString }`);
+ }
+
+ astDebuggerStatement(arrNode, retArr) {
+ return retArr;
+ }
+
+ astConditionalExpression(ast, retArr) {
+ if (ast.type !== 'ConditionalExpression') {
+ throw this.astErrorOutput('Not a conditional expression', ast);
+ }
+ retArr.push('(');
+ this.astGeneric(ast.test, retArr);
+ retArr.push('?');
+ this.astGeneric(ast.consequent, retArr);
+ retArr.push(':');
+ this.astGeneric(ast.alternate, retArr);
+ retArr.push(')');
+ return retArr;
+ }
+
+ astFunction(ast, retArr) {
+ throw new Error(`"astFunction" not defined on ${ this.constructor.name }`);
+ }
+
+ astFunctionDeclaration(ast, retArr) {
+ if (this.isChildFunction(ast)) {
+ return retArr;
+ }
+ return this.astFunction(ast, retArr);
+ }
+ astFunctionExpression(ast, retArr) {
+ if (this.isChildFunction(ast)) {
+ return retArr;
+ }
+ return this.astFunction(ast, retArr);
+ }
+ isChildFunction(ast) {
+ for (let i = 0; i < this.functions.length; i++) {
+ if (this.functions[i] === ast) {
+ return true;
+ }
+ }
+ return false;
+ }
+ astReturnStatement(ast, retArr) {
+ return retArr;
+ }
+ astLiteral(ast, retArr) {
+ this.literalTypes[this.astKey(ast)] = 'Number';
+ return retArr;
+ }
+ astBinaryExpression(ast, retArr) {
+ return retArr;
+ }
+ astIdentifierExpression(ast, retArr) {
+ return retArr;
+ }
+ astAssignmentExpression(ast, retArr) {
+ return retArr;
+ }
+ astExpressionStatement(esNode, retArr) {
+ this.astGeneric(esNode.expression, retArr);
+ retArr.push(';');
+ return retArr;
+ }
+ astEmptyStatement(eNode, retArr) {
+ return retArr;
+ }
+ astBlockStatement(ast, retArr) {
+ return retArr;
+ }
+ astIfStatement(ast, retArr) {
+ return retArr;
+ }
+ astSwitchStatement(ast, retArr) {
+ return retArr;
+ }
+ astBreakStatement(brNode, retArr) {
+ retArr.push('break;');
+ return retArr;
+ }
+ astContinueStatement(crNode, retArr) {
+ retArr.push('continue;\n');
+ return retArr;
+ }
+ astForStatement(ast, retArr) {
+ return retArr;
+ }
+ astWhileStatement(ast, retArr) {
+ return retArr;
+ }
+ astDoWhileStatement(ast, retArr) {
+ return retArr;
+ }
+ astVariableDeclarator(iVarDecNode, retArr) {
+ this.astGeneric(iVarDecNode.id, retArr);
+ if (iVarDecNode.init !== null) {
+ retArr.push('=');
+ this.astGeneric(iVarDecNode.init, retArr);
+ }
+ return retArr;
+ }
+ astThisExpression(ast, retArr) {
+ return retArr;
+ }
+ astSequenceExpression(sNode, retArr) {
+ const { expressions } = sNode;
+ const sequenceResult = [];
+ for (let i = 0; i < expressions.length; i++) {
+ const expression = expressions[i];
+ const expressionResult = [];
+ this.astGeneric(expression, expressionResult);
+ sequenceResult.push(expressionResult.join(''));
+ }
+ if (sequenceResult.length > 1) {
+ retArr.push('(', sequenceResult.join(','), ')');
+ } else {
+ retArr.push(sequenceResult[0]);
+ }
+ return retArr;
+ }
+ astUnaryExpression(uNode, retArr) {
+ const unaryResult = this.checkAndUpconvertBitwiseUnary(uNode, retArr);
+ if (unaryResult) {
+ 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;
+ }
+
+ checkAndUpconvertBitwiseUnary(uNode, retArr) {}
+
+ astUpdateExpression(uNode, 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;
+ }
+ astLogicalExpression(logNode, retArr) {
+ retArr.push('(');
+ this.astGeneric(logNode.left, retArr);
+ retArr.push(logNode.operator);
+ this.astGeneric(logNode.right, retArr);
+ retArr.push(')');
+ return retArr;
+ }
+ astMemberExpression(ast, retArr) {
+ return retArr;
+ }
+ astCallExpression(ast, retArr) {
+ return retArr;
+ }
+ astArrayExpression(ast, retArr) {
+ return retArr;
+ }
+
+ getMemberExpressionDetails(ast) {
+ if (ast.type !== 'MemberExpression') {
+ throw this.astErrorOutput(`Expression ${ ast.type } not a MemberExpression`, ast);
+ }
+ let name = null;
+ let type = null;
+ const variableSignature = this.getVariableSignature(ast);
+ switch (variableSignature) {
+ case 'value':
+ return null;
+ case 'value.thread.value':
+ case 'this.thread.value':
+ case 'this.output.value':
+ return {
+ signature: variableSignature,
+ type: 'Integer',
+ name: ast.property.name
+ };
+ case 'value[]':
+ if (typeof ast.object.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.object.name;
+ return {
+ name,
+ origin: 'user',
+ signature: variableSignature,
+ type: this.getVariableType(ast.object),
+ xProperty: ast.property
+ };
+ case 'value[][]':
+ if (typeof ast.object.object.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.object.object.name;
+ return {
+ name,
+ origin: 'user',
+ signature: variableSignature,
+ type: this.getVariableType(ast.object.object),
+ yProperty: ast.object.property,
+ xProperty: ast.property,
+ };
+ case 'value[][][]':
+ if (typeof ast.object.object.object.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.object.object.object.name;
+ return {
+ name,
+ origin: 'user',
+ signature: variableSignature,
+ type: this.getVariableType(ast.object.object.object),
+ zProperty: ast.object.object.property,
+ yProperty: ast.object.property,
+ xProperty: ast.property,
+ };
+ case 'value[][][][]':
+ if (typeof ast.object.object.object.object.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.object.object.object.object.name;
+ return {
+ name,
+ origin: 'user',
+ signature: variableSignature,
+ type: this.getVariableType(ast.object.object.object.object),
+ zProperty: ast.object.object.property,
+ yProperty: ast.object.property,
+ xProperty: ast.property,
+ };
+ case 'value.value':
+ if (typeof ast.property.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ if (this.isAstMathVariable(ast)) {
+ name = ast.property.name;
+ return {
+ name,
+ origin: 'Math',
+ type: 'Number',
+ signature: variableSignature,
+ };
+ }
+ switch (ast.property.name) {
+ case 'r':
+ case 'g':
+ case 'b':
+ case 'a':
+ name = ast.object.name;
+ return {
+ name,
+ property: ast.property.name,
+ origin: 'user',
+ signature: variableSignature,
+ type: 'Number'
+ };
+ default:
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ case 'this.constants.value':
+ if (typeof ast.property.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.property.name;
+ type = this.getConstantType(name);
+ if (!type) {
+ throw this.astErrorOutput('Constant has no type', ast);
+ }
+ return {
+ name,
+ type,
+ origin: 'constants',
+ signature: variableSignature,
+ };
+ case 'this.constants.value[]':
+ if (typeof ast.object.property.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.object.property.name;
+ type = this.getConstantType(name);
+ if (!type) {
+ throw this.astErrorOutput('Constant has no type', ast);
+ }
+ return {
+ name,
+ type,
+ origin: 'constants',
+ signature: variableSignature,
+ xProperty: ast.property,
+ };
+ case 'this.constants.value[][]': {
+ if (typeof ast.object.object.property.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.object.object.property.name;
+ type = this.getConstantType(name);
+ if (!type) {
+ throw this.astErrorOutput('Constant has no type', ast);
+ }
+ return {
+ name,
+ type,
+ origin: 'constants',
+ signature: variableSignature,
+ yProperty: ast.object.property,
+ xProperty: ast.property,
+ };
+ }
+ case 'this.constants.value[][][]': {
+ if (typeof ast.object.object.object.property.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.object.object.object.property.name;
+ type = this.getConstantType(name);
+ if (!type) {
+ throw this.astErrorOutput('Constant has no type', ast);
+ }
+ return {
+ name,
+ type,
+ origin: 'constants',
+ signature: variableSignature,
+ zProperty: ast.object.object.property,
+ yProperty: ast.object.property,
+ xProperty: ast.property,
+ };
+ }
+ case 'fn()[]':
+ case 'fn()[][]':
+ case '[][]':
+ return {
+ signature: variableSignature,
+ property: ast.property,
+ };
+ default:
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ }
+
+ findIdentifierOrigin(astToFind) {
+ const stack = [this.ast];
+
+ while (stack.length > 0) {
+ const atNode = stack[0];
+ if (atNode.type === 'VariableDeclarator' && atNode.id && atNode.id.name && atNode.id.name === astToFind.name) {
+ return atNode;
+ }
+ stack.shift();
+ if (atNode.argument) {
+ stack.push(atNode.argument);
+ } else if (atNode.body) {
+ stack.push(atNode.body);
+ } else if (atNode.declarations) {
+ stack.push(atNode.declarations);
+ } else if (Array.isArray(atNode)) {
+ for (let i = 0; i < atNode.length; i++) {
+ stack.push(atNode[i]);
+ }
+ }
+ }
+ return null;
+ }
+
+ findLastReturn(ast) {
+ const stack = [ast || this.ast];
+
+ while (stack.length > 0) {
+ const atNode = stack.pop();
+ if (atNode.type === 'ReturnStatement') {
+ return atNode;
+ }
+ if (atNode.type === 'FunctionDeclaration') {
+ continue;
+ }
+ if (atNode.argument) {
+ stack.push(atNode.argument);
+ } else if (atNode.body) {
+ stack.push(atNode.body);
+ } else if (atNode.declarations) {
+ stack.push(atNode.declarations);
+ } else if (Array.isArray(atNode)) {
+ for (let i = 0; i < atNode.length; i++) {
+ stack.push(atNode[i]);
+ }
+ } else if (atNode.consequent) {
+ stack.push(atNode.consequent);
+ } else if (atNode.cases) {
+ stack.push(atNode.cases);
+ }
+ }
+ return null;
+ }
+
+ getInternalVariableName(name) {
+ if (!this._internalVariableNames.hasOwnProperty(name)) {
+ this._internalVariableNames[name] = 0;
+ }
+ this._internalVariableNames[name]++;
+ if (this._internalVariableNames[name] === 1) {
+ return name;
+ }
+ return name + this._internalVariableNames[name];
+ }
+
+ astKey(ast, separator = ',') {
+ if (!ast.start || !ast.end) throw new Error('AST start and end needed');
+ return `${ast.start}${separator}${ast.end}`;
+ }
+}
+
+const typeLookupMap = {
+ '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)',
+};
+
+module.exports = {
+ FunctionNode
+};
+},{"../utils":113,"./function-tracer":10,"acorn":1}],10:[function(require,module,exports){
+const { utils } = require('../utils');
+
+function last(array) {
+ return array.length > 0 ? array[array.length - 1] : null;
+}
+
+const states = {
+ trackIdentifiers: 'trackIdentifiers',
+ memberExpression: 'memberExpression',
+ inForLoopInit: 'inForLoopInit'
+};
+
+class FunctionTracer {
+ constructor(ast) {
+ 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(ast);
+ }
+
+ isState(state) {
+ return this.states[this.states.length - 1] === state;
+ }
+
+ hasState(state) {
+ return this.states.indexOf(state) > -1;
+ }
+
+ pushState(state) {
+ this.states.push(state);
+ }
+
+ popState(state) {
+ if (this.isState(state)) {
+ this.states.pop();
+ } else {
+ throw new Error(`Cannot pop the non-active state "${state}"`);
+ }
+ }
+
+ get currentFunctionContext() {
+ return last(this.functionContexts);
+ }
+
+ get currentContext() {
+ return last(this.runningContexts);
+ }
+
+ newFunctionContext() {
+ const newContext = { '@contextType': 'function' };
+ this.contexts.push(newContext);
+ this.functionContexts.push(newContext);
+ }
+
+ newContext(run) {
+ const newContext = Object.assign({ '@contextType': 'const/let' }, this.currentContext);
+ this.contexts.push(newContext);
+ this.runningContexts.push(newContext);
+ run();
+ const { currentFunctionContext } = this;
+ for (const p in currentFunctionContext) {
+ if (!currentFunctionContext.hasOwnProperty(p) || newContext.hasOwnProperty(p)) continue;
+ newContext[p] = currentFunctionContext[p];
+ }
+ this.runningContexts.pop();
+ return newContext;
+ }
+
+ useFunctionContext(run) {
+ const functionContext = last(this.functionContexts);
+ this.runningContexts.push(functionContext);
+ run();
+ this.runningContexts.pop();
+ }
+
+ getIdentifiers(run) {
+ const trackedIdentifiers = this.trackedIdentifiers = [];
+ this.pushState(states.trackIdentifiers);
+ run();
+ this.trackedIdentifiers = null;
+ this.popState(states.trackIdentifiers);
+ return trackedIdentifiers;
+ }
+
+ getDeclaration(name) {
+ const { currentContext, currentFunctionContext, runningContexts } = this;
+ const declaration = currentContext[name] || currentFunctionContext[name] || null;
+
+ if (
+ !declaration &&
+ currentContext === currentFunctionContext &&
+ runningContexts.length > 0
+ ) {
+ const previousRunningContext = runningContexts[runningContexts.length - 2];
+ if (previousRunningContext[name]) {
+ return previousRunningContext[name];
+ }
+ }
+
+ return declaration;
+ }
+
+ scan(ast) {
+ if (!ast) return;
+ if (Array.isArray(ast)) {
+ for (let i = 0; i < ast.length; i++) {
+ this.scan(ast[i]);
+ }
+ return;
+ }
+ switch (ast.type) {
+ case 'Program':
+ this.useFunctionContext(() => {
+ this.scan(ast.body);
+ });
+ break;
+ case 'BlockStatement':
+ this.newContext(() => {
+ this.scan(ast.body);
+ });
+ break;
+ case 'AssignmentExpression':
+ case 'LogicalExpression':
+ this.scan(ast.left);
+ this.scan(ast.right);
+ break;
+ case 'BinaryExpression':
+ this.scan(ast.left);
+ this.scan(ast.right);
+ break;
+ case 'UpdateExpression':
+ if (ast.operator === '++') {
+ const declaration = this.getDeclaration(ast.argument.name);
+ if (declaration) {
+ declaration.suggestedType = 'Integer';
+ }
+ }
+ this.scan(ast.argument);
+ break;
+ case 'UnaryExpression':
+ this.scan(ast.argument);
+ break;
+ case 'VariableDeclaration':
+ if (ast.kind === 'var') {
+ this.useFunctionContext(() => {
+ ast.declarations = utils.normalizeDeclarations(ast);
+ this.scan(ast.declarations);
+ });
+ } else {
+ ast.declarations = utils.normalizeDeclarations(ast);
+ this.scan(ast.declarations);
+ }
+ break;
+ case 'VariableDeclarator': {
+ const { currentContext } = this;
+ const inForLoopInit = this.hasState(states.inForLoopInit);
+ const declaration = {
+ ast: ast,
+ context: currentContext,
+ name: ast.id.name,
+ origin: 'declaration',
+ inForLoopInit,
+ inForLoopTest: null,
+ assignable: currentContext === this.currentFunctionContext || (!inForLoopInit && !currentContext.hasOwnProperty(ast.id.name)),
+ suggestedType: null,
+ valueType: null,
+ dependencies: null,
+ isSafe: null,
+ };
+ if (!currentContext[ast.id.name]) {
+ currentContext[ast.id.name] = declaration;
+ }
+ this.declarations.push(declaration);
+ this.scan(ast.id);
+ this.scan(ast.init);
+ break;
+ }
+ case 'FunctionExpression':
+ case 'FunctionDeclaration':
+ if (this.runningContexts.length === 0) {
+ this.scan(ast.body);
+ } else {
+ this.functions.push(ast);
+ }
+ break;
+ case 'IfStatement':
+ this.scan(ast.test);
+ this.scan(ast.consequent);
+ if (ast.alternate) this.scan(ast.alternate);
+ break;
+ case 'ForStatement': {
+ let testIdentifiers;
+ const context = this.newContext(() => {
+ this.pushState(states.inForLoopInit);
+ this.scan(ast.init);
+ this.popState(states.inForLoopInit);
+
+ testIdentifiers = this.getIdentifiers(() => {
+ this.scan(ast.test);
+ });
+
+ this.scan(ast.update);
+ this.newContext(() => {
+ this.scan(ast.body);
+ });
+ });
+
+ if (testIdentifiers) {
+ for (const p in context) {
+ if (p === '@contextType') continue;
+ if (testIdentifiers.indexOf(p) > -1) {
+ context[p].inForLoopTest = true;
+ }
+ }
+ }
+ break;
+ }
+ case 'DoWhileStatement':
+ case 'WhileStatement':
+ this.newContext(() => {
+ this.scan(ast.body);
+ this.scan(ast.test);
+ });
+ break;
+ case 'Identifier': {
+ if (this.isState(states.trackIdentifiers)) {
+ this.trackedIdentifiers.push(ast.name);
+ }
+ this.identifiers.push({
+ context: this.currentContext,
+ declaration: this.getDeclaration(ast.name),
+ ast,
+ });
+ break;
+ }
+ case 'ReturnStatement':
+ this.returnStatements.push(ast);
+ this.scan(ast.argument);
+ break;
+ case 'MemberExpression':
+ this.pushState(states.memberExpression);
+ this.scan(ast.object);
+ this.scan(ast.property);
+ this.popState(states.memberExpression);
+ break;
+ case 'ExpressionStatement':
+ this.scan(ast.expression);
+ break;
+ case 'SequenceExpression':
+ this.scan(ast.expressions);
+ break;
+ case 'CallExpression':
+ this.functionCalls.push({
+ context: this.currentContext,
+ ast,
+ });
+ this.scan(ast.arguments);
+ break;
+ case 'ArrayExpression':
+ this.scan(ast.elements);
+ break;
+ case 'ConditionalExpression':
+ this.scan(ast.test);
+ this.scan(ast.alternate);
+ this.scan(ast.consequent);
+ break;
+ case 'SwitchStatement':
+ this.scan(ast.discriminant);
+ this.scan(ast.cases);
+ break;
+ case 'SwitchCase':
+ this.scan(ast.test);
+ this.scan(ast.consequent);
+ break;
+
+ case 'ThisExpression':
+ case 'Literal':
+ case 'DebuggerStatement':
+ case 'EmptyStatement':
+ case 'BreakStatement':
+ case 'ContinueStatement':
+ break;
+ default:
+ throw new Error(`unhandled type "${ast.type}"`);
+ }
+ }
+}
+
+module.exports = {
+ FunctionTracer,
+};
+},{"../utils":113}],11:[function(require,module,exports){
+const { glWiretap } = require('gl-wiretap');
+const { utils } = require('../../utils');
+
+function toStringWithoutUtils(fn) {
+ return fn.toString()
+ .replace('=>', '')
+ .replace(/^function /, '')
+ .replace(/utils[.]/g, '/*utils.*/');
+}
+
+function glKernelString(Kernel, args, originKernel, setupContextString, destroyContextString) {
+ if (!originKernel.built) {
+ originKernel.build.apply(originKernel, args);
+ }
+ args = args ? Array.from(args).map(arg => {
+ switch (typeof arg) {
+ case 'boolean':
+ return new Boolean(arg);
+ case 'number':
+ return new Number(arg);
+ default:
+ return arg;
+ }
+ }) : null;
+ const uploadedValues = [];
+ const postResult = [];
+ const context = glWiretap(originKernel.context, {
+ useTrackablePrimitives: true,
+ onReadPixels: (targetName) => {
+ if (kernel.subKernels) {
+ if (!subKernelsResultVariableSetup) {
+ postResult.push(` const result = { result: ${getRenderString(targetName, kernel)} };`);
+ subKernelsResultVariableSetup = true;
+ } else {
+ const property = kernel.subKernels[subKernelsResultIndex++].property;
+ postResult.push(` result${isNaN(property) ? '.' + property : `[${property}]`} = ${getRenderString(targetName, kernel)};`);
+ }
+ if (subKernelsResultIndex === kernel.subKernels.length) {
+ postResult.push(' return result;');
+ }
+ return;
+ }
+ if (targetName) {
+ postResult.push(` return ${getRenderString(targetName, kernel)};`);
+ } else {
+ postResult.push(` return null;`);
+ }
+ },
+ onUnrecognizedArgumentLookup: (argument) => {
+ const argumentName = findKernelValue(argument, kernel.kernelArguments, [], context, uploadedValues);
+ if (argumentName) {
+ return argumentName;
+ }
+ const constantName = findKernelValue(argument, kernel.kernelConstants, constants ? Object.keys(constants).map(key => constants[key]) : [], context, uploadedValues);
+ if (constantName) {
+ return constantName;
+ }
+ return null;
+ }
+ });
+ let subKernelsResultVariableSetup = false;
+ let subKernelsResultIndex = 0;
+ const {
+ source,
+ canvas,
+ output,
+ pipeline,
+ graphical,
+ loopMaxIterations,
+ constants,
+ optimizeFloatMemory,
+ precision,
+ fixIntegerDivisionAccuracy,
+ functions,
+ nativeFunctions,
+ subKernels,
+ immutable,
+ argumentTypes,
+ constantTypes,
+ kernelArguments,
+ kernelConstants,
+ tactic,
+ } = originKernel;
+ const kernel = new Kernel(source, {
+ canvas,
+ context,
+ checkContext: false,
+ output,
+ pipeline,
+ graphical,
+ loopMaxIterations,
+ constants,
+ optimizeFloatMemory,
+ precision,
+ fixIntegerDivisionAccuracy,
+ functions,
+ nativeFunctions,
+ subKernels,
+ immutable,
+ argumentTypes,
+ constantTypes,
+ tactic,
+ });
+ let result = [];
+ context.setIndent(2);
+ kernel.build.apply(kernel, args);
+ result.push(context.toString());
+ context.reset();
+
+ kernel.kernelArguments.forEach((kernelArgument, i) => {
+ switch (kernelArgument.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':
+ context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue);
+ break;
+ case 'HTMLImageArray':
+ for (let imageIndex = 0; imageIndex < args[i].length; imageIndex++) {
+ const arg = args[i];
+ context.insertVariable(`uploadValue_${kernelArgument.name}[${imageIndex}]`, arg[imageIndex]);
+ }
+ break;
+ case 'Input':
+ context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue);
+ break;
+ case 'MemoryOptimizedNumberTexture':
+ case 'NumberTexture':
+ case 'Array1D(2)':
+ case 'Array1D(3)':
+ case 'Array1D(4)':
+ case 'Array2D(2)':
+ case 'Array2D(3)':
+ case 'Array2D(4)':
+ case 'Array3D(2)':
+ case 'Array3D(3)':
+ case 'Array3D(4)':
+ case 'ArrayTexture(1)':
+ case 'ArrayTexture(2)':
+ case 'ArrayTexture(3)':
+ case 'ArrayTexture(4)':
+ context.insertVariable(`uploadValue_${kernelArgument.name}`, args[i].texture);
+ break;
+ default:
+ throw new Error(`unhandled kernelArgumentType insertion for glWiretap of type ${kernelArgument.type}`);
+ }
+ });
+ result.push('/** start of injected functions **/');
+ result.push(`function ${toStringWithoutUtils(utils.flattenTo)}`);
+ result.push(`function ${toStringWithoutUtils(utils.flatten2dArrayTo)}`);
+ result.push(`function ${toStringWithoutUtils(utils.flatten3dArrayTo)}`);
+ result.push(`function ${toStringWithoutUtils(utils.flatten4dArrayTo)}`);
+ result.push(`function ${toStringWithoutUtils(utils.isArray)}`);
+ if (kernel.renderOutput !== kernel.renderTexture && kernel.formatValues) {
+ result.push(
+ ` const renderOutput = function ${toStringWithoutUtils(kernel.formatValues)};`
+ );
+ }
+ result.push('/** end of injected functions **/');
+ result.push(` const innerKernel = function (${kernel.kernelArguments.map(kernelArgument => kernelArgument.varName).join(', ')}) {`);
+ context.setIndent(4);
+ kernel.run.apply(kernel, args);
+ if (kernel.renderKernels) {
+ kernel.renderKernels();
+ } else if (kernel.renderOutput) {
+ kernel.renderOutput();
+ }
+ result.push(' /** start setup uploads for kernel values **/');
+ kernel.kernelArguments.forEach(kernelArgument => {
+ result.push(' ' + kernelArgument.getStringValueHandler().split('\n').join('\n '));
+ });
+ result.push(' /** end setup uploads for kernel values **/');
+ result.push(context.toString());
+ if (kernel.renderOutput === kernel.renderTexture) {
+ context.reset();
+ const framebufferName = context.getContextVariableName(kernel.framebuffer);
+ if (kernel.renderKernels) {
+ const results = kernel.renderKernels();
+ const textureName = context.getContextVariableName(kernel.texture.texture);
+ result.push(` return {
+ result: {
+ texture: ${ textureName },
+ type: '${ results.result.type }',
+ toArray: ${ getToArrayString(results.result, textureName, framebufferName) }
+ },`);
+ const { subKernels, mappedTextures } = kernel;
+ for (let i = 0; i < subKernels.length; i++) {
+ const texture = mappedTextures[i];
+ const subKernel = subKernels[i];
+ const subKernelResult = results[subKernel.property];
+ const subKernelTextureName = context.getContextVariableName(texture.texture);
+ result.push(`
+ ${subKernel.property}: {
+ texture: ${ subKernelTextureName },
+ type: '${ subKernelResult.type }',
+ toArray: ${ getToArrayString(subKernelResult, subKernelTextureName, framebufferName) }
+ },`);
+ }
+ result.push(` };`);
+ } else {
+ const rendered = kernel.renderOutput();
+ const textureName = context.getContextVariableName(kernel.texture.texture);
+ result.push(` return {
+ texture: ${ textureName },
+ type: '${ rendered.type }',
+ toArray: ${ getToArrayString(rendered, textureName, framebufferName) }
+ };`);
+ }
+ }
+ result.push(` ${destroyContextString ? '\n' + destroyContextString + ' ': ''}`);
+ result.push(postResult.join('\n'));
+ result.push(' };');
+ if (kernel.graphical) {
+ result.push(getGetPixelsString(kernel));
+ result.push(` innerKernel.getPixels = getPixels;`);
+ }
+ result.push(' return innerKernel;');
+
+ let constantsUpload = [];
+ kernelConstants.forEach((kernelConstant) => {
+ constantsUpload.push(`${kernelConstant.getStringValueHandler()}`);
+ });
+ return `function kernel(settings) {
+ const { context, constants } = settings;
+ ${constantsUpload.join('')}
+ ${setupContextString ? setupContextString : ''}
+${result.join('\n')}
+}`;
+}
+
+function getRenderString(targetName, kernel) {
+ const readBackValue = kernel.precision === 'single' ? targetName : `new Float32Array(${targetName}.buffer)`;
+ if (kernel.output[2]) {
+ return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]}, ${kernel.output[2]})`;
+ }
+ if (kernel.output[1]) {
+ return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]})`;
+ }
+
+ return `renderOutput(${readBackValue}, ${kernel.output[0]})`;
+}
+
+function getGetPixelsString(kernel) {
+ const getPixels = kernel.getPixels.toString();
+ const useFunctionKeyword = !/^function/.test(getPixels);
+ return utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ getPixels }`, {
+ findDependency: (object, name) => {
+ if (object === 'utils') {
+ return `const ${name} = ${utils[name].toString()};`;
+ }
+ return null;
+ },
+ thisLookup: (property) => {
+ if (property === 'context') {
+ return null;
+ }
+ if (kernel.hasOwnProperty(property)) {
+ return JSON.stringify(kernel[property]);
+ }
+ throw new Error(`unhandled thisLookup ${ property }`);
+ }
+ });
+}
+
+function getToArrayString(kernelResult, textureName, framebufferName) {
+ const toArray = kernelResult.toArray.toString();
+ const useFunctionKeyword = !/^function/.test(toArray);
+ const flattenedFunctions = utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ toArray }`, {
+ findDependency: (object, name) => {
+ if (object === 'utils') {
+ return `const ${name} = ${utils[name].toString()};`;
+ } else if (object === 'this') {
+ if (name === 'framebuffer') {
+ return '';
+ }
+ return `${useFunctionKeyword ? 'function ' : ''}${kernelResult[name].toString()}`;
+ } else {
+ throw new Error('unhandled fromObject');
+ }
+ },
+ thisLookup: (property, isDeclaration) => {
+ if (property === 'texture') {
+ return textureName;
+ }
+ if (property === 'context') {
+ if (isDeclaration) return null;
+ return 'gl';
+ }
+ if (kernelResult.hasOwnProperty(property)) {
+ return JSON.stringify(kernelResult[property]);
+ }
+ throw new Error(`unhandled thisLookup ${ property }`);
+ }
+ });
+ return `() => {
+ function framebuffer() { return ${framebufferName}; };
+ ${flattenedFunctions}
+ return toArray();
+ }`;
+}
+
+function findKernelValue(argument, kernelValues, values, context, uploadedValues) {
+ if (argument === null) return null;
+ if (kernelValues === null) return null;
+ switch (typeof argument) {
+ case 'boolean':
+ case 'number':
+ return null;
+ }
+ if (
+ typeof HTMLImageElement !== 'undefined' &&
+ argument instanceof HTMLImageElement
+ ) {
+ for (let i = 0; i < kernelValues.length; i++) {
+ const kernelValue = kernelValues[i];
+ if (kernelValue.type !== 'HTMLImageArray' && kernelValue) continue;
+ if (kernelValue.uploadValue !== argument) continue;
+ const variableIndex = values[i].indexOf(argument);
+ if (variableIndex === -1) continue;
+ const variableName = `uploadValue_${kernelValue.name}[${variableIndex}]`;
+ context.insertVariable(variableName, argument);
+ return variableName;
+ }
+ }
+
+ for (let i = 0; i < kernelValues.length; i++) {
+ const kernelValue = kernelValues[i];
+ if (argument !== kernelValue.uploadValue) continue;
+ const variable = `uploadValue_${kernelValue.name}`;
+ context.insertVariable(variable, kernelValue);
+ return variable;
+ }
+ return null;
+}
+
+module.exports = {
+ glKernelString
+};
+},{"../../utils":113,"gl-wiretap":2}],12:[function(require,module,exports){
+const { Kernel } = require('../kernel');
+const { utils } = require('../../utils');
+const { GLTextureArray2Float } = require('./texture/array-2-float');
+const { GLTextureArray2Float2D } = require('./texture/array-2-float-2d');
+const { GLTextureArray2Float3D } = require('./texture/array-2-float-3d');
+const { GLTextureArray3Float } = require('./texture/array-3-float');
+const { GLTextureArray3Float2D } = require('./texture/array-3-float-2d');
+const { GLTextureArray3Float3D } = require('./texture/array-3-float-3d');
+const { GLTextureArray4Float } = require('./texture/array-4-float');
+const { GLTextureArray4Float2D } = require('./texture/array-4-float-2d');
+const { GLTextureArray4Float3D } = require('./texture/array-4-float-3d');
+const { GLTextureFloat } = require('./texture/float');
+const { GLTextureFloat2D } = require('./texture/float-2d');
+const { GLTextureFloat3D } = require('./texture/float-3d');
+const { GLTextureMemoryOptimized } = require('./texture/memory-optimized');
+const { GLTextureMemoryOptimized2D } = require('./texture/memory-optimized-2d');
+const { GLTextureMemoryOptimized3D } = require('./texture/memory-optimized-3d');
+const { GLTextureUnsigned } = require('./texture/unsigned');
+const { GLTextureUnsigned2D } = require('./texture/unsigned-2d');
+const { GLTextureUnsigned3D } = require('./texture/unsigned-3d');
+const { GLTextureGraphical } = require('./texture/graphical');
+
+class GLKernel extends Kernel {
+ static get mode() {
+ return 'gpu';
+ }
+
+ static getIsFloatRead() {
+ const kernelString = `function kernelFunction() {
+ return 1;
+ }`;
+ const kernel = new this(kernelString, {
+ context: this.testContext,
+ canvas: this.testCanvas,
+ validate: false,
+ output: [1],
+ precision: 'single',
+ returnType: 'Number',
+ tactic: 'speed',
+ });
+ kernel.build();
+ kernel.run();
+ const result = kernel.renderOutput();
+ kernel.destroy(true);
+ return result[0] === 1;
+ }
+
+ static getIsIntegerDivisionAccurate() {
+ function kernelFunction(v1, v2) {
+ return v1[this.thread.x] / v2[this.thread.x];
+ }
+ const kernel = new this(kernelFunction.toString(), {
+ context: this.testContext,
+ canvas: this.testCanvas,
+ validate: false,
+ output: [2],
+ returnType: 'Number',
+ precision: 'unsigned',
+ tactic: 'speed',
+ });
+ const args = [
+ [6, 6030401],
+ [3, 3991]
+ ];
+ kernel.build.apply(kernel, args);
+ kernel.run.apply(kernel, args);
+ const result = kernel.renderOutput();
+ kernel.destroy(true);
+ return result[0] === 2 && result[1] === 1511;
+ }
+
+ static getIsSpeedTacticSupported() {
+ function kernelFunction(value) {
+ return value[this.thread.x];
+ }
+ const kernel = new this(kernelFunction.toString(), {
+ context: this.testContext,
+ canvas: this.testCanvas,
+ validate: false,
+ output: [4],
+ returnType: 'Number',
+ precision: 'unsigned',
+ tactic: 'speed',
+ });
+ const args = [
+ [0, 1, 2, 3]
+ ];
+ kernel.build.apply(kernel, args);
+ kernel.run.apply(kernel, args);
+ const result = kernel.renderOutput();
+ kernel.destroy(true);
+ return Math.round(result[0]) === 0 && Math.round(result[1]) === 1 && Math.round(result[2]) === 2 && Math.round(result[3]) === 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 gl = this.testContext;
+ const isDrawBuffers = this.getIsDrawBuffers();
+ return Object.freeze({
+ isFloatRead: this.getIsFloatRead(),
+ isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(),
+ isSpeedTacticSupported: this.getIsSpeedTacticSupported(),
+ isTextureFloat: this.getIsTextureFloat(),
+ isDrawBuffers,
+ kernelMap: isDrawBuffers,
+ channelCount: this.getChannelCount(),
+ maxTextureSize: this.getMaxTextureSize(),
+ lowIntPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_INT),
+ lowFloatPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_FLOAT),
+ mediumIntPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_INT),
+ mediumFloatPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT),
+ highIntPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_INT),
+ highFloatPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT),
+ });
+ }
+
+ static setupFeatureChecks() {
+ throw new Error(`"setupFeatureChecks" not defined on ${ this.name }`);
+ }
+
+ static getSignature(kernel, argumentTypes) {
+ return kernel.getVariablePrecisionString() + (argumentTypes.length > 0 ? ':' + argumentTypes.join(',') : '');
+ }
+
+ setFixIntegerDivisionAccuracy(fix) {
+ this.fixIntegerDivisionAccuracy = fix;
+ return this;
+ }
+
+ setPrecision(flag) {
+ this.precision = flag;
+ return this;
+ }
+
+ setFloatTextures(flag) {
+ utils.warnDeprecated('method', 'setFloatTextures', 'setOptimizeFloatMemory');
+ this.floatTextures = flag;
+ return this;
+ }
+
+ static nativeFunctionArguments(source) {
+ const argumentTypes = [];
+ const argumentNames = [];
+ const states = [];
+ const isStartingVariableName = /^[a-zA-Z_]/;
+ const isVariableChar = /[a-zA-Z_0-9]/;
+ let i = 0;
+ let argumentName = null;
+ let argumentType = null;
+ while (i < source.length) {
+ const char = source[i];
+ const nextChar = source[i + 1];
+ const state = states.length > 0 ? states[states.length - 1] : null;
+
+ if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '*') {
+ states.push('MULTI_LINE_COMMENT');
+ i += 2;
+ continue;
+ } else if (state === 'MULTI_LINE_COMMENT' && char === '*' && nextChar === '/') {
+ states.pop();
+ i += 2;
+ continue;
+ }
+
+ else if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '/') {
+ states.push('COMMENT');
+ i += 2;
+ continue;
+ } else if (state === 'COMMENT' && char === '\n') {
+ states.pop();
+ i++;
+ continue;
+ }
+
+ else if (state === null && char === '(') {
+ states.push('FUNCTION_ARGUMENTS');
+ i++;
+ continue;
+ } else if (state === 'FUNCTION_ARGUMENTS') {
+ if (char === ')') {
+ states.pop();
+ break;
+ }
+ if (char === 'f' && nextChar === 'l' && source[i + 2] === 'o' && source[i + 3] === 'a' && source[i + 4] === 't' && source[i + 5] === ' ') {
+ states.push('DECLARE_VARIABLE');
+ argumentType = 'float';
+ argumentName = '';
+ i += 6;
+ continue;
+ } else if (char === 'i' && nextChar === 'n' && source[i + 2] === 't' && source[i + 3] === ' ') {
+ states.push('DECLARE_VARIABLE');
+ argumentType = 'int';
+ argumentName = '';
+ i += 4;
+ continue;
+ } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '2' && source[i + 4] === ' ') {
+ states.push('DECLARE_VARIABLE');
+ argumentType = 'vec2';
+ argumentName = '';
+ i += 5;
+ continue;
+ } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '3' && source[i + 4] === ' ') {
+ states.push('DECLARE_VARIABLE');
+ argumentType = 'vec3';
+ argumentName = '';
+ i += 5;
+ continue;
+ } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '4' && source[i + 4] === ' ') {
+ states.push('DECLARE_VARIABLE');
+ argumentType = 'vec4';
+ argumentName = '';
+ i += 5;
+ continue;
+ }
+ }
+
+ else if (state === 'DECLARE_VARIABLE') {
+ if (argumentName === '') {
+ if (char === ' ') {
+ i++;
+ continue;
+ }
+ if (!isStartingVariableName.test(char)) {
+ throw new Error('variable name is not expected string');
+ }
+ }
+ argumentName += char;
+ if (!isVariableChar.test(nextChar)) {
+ states.pop();
+ argumentNames.push(argumentName);
+ argumentTypes.push(typeMap[argumentType]);
+ }
+ }
+
+ i++;
+ }
+ if (states.length > 0) {
+ throw new Error('GLSL function was not parsable');
+ }
+ return {
+ argumentNames,
+ argumentTypes,
+ };
+ }
+
+ static nativeFunctionReturnType(source) {
+ return typeMap[source.match(/int|float|vec[2-4]/)[0]];
+ }
+
+ static combineKernels(combinedKernel, lastKernel) {
+ combinedKernel.apply(null, arguments);
+ const {
+ texSize,
+ context,
+ threadDim
+ } = lastKernel.texSize;
+ let result;
+ if (lastKernel.precision === 'single') {
+ const w = texSize[0];
+ const h = Math.ceil(texSize[1] / 4);
+ result = new Float32Array(w * h * 4 * 4);
+ context.readPixels(0, 0, w, h * 4, context.RGBA, context.FLOAT, result);
+ } else {
+ const bytes = new Uint8Array(texSize[0] * texSize[1] * 4);
+ context.readPixels(0, 0, texSize[0], texSize[1], context.RGBA, context.UNSIGNED_BYTE, bytes);
+ result = new Float32Array(bytes.buffer);
+ }
+
+ result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]);
+
+ if (lastKernel.output.length === 1) {
+ return result;
+ } else if (lastKernel.output.length === 2) {
+ return utils.splitArray(result, lastKernel.output[0]);
+ } else if (lastKernel.output.length === 3) {
+ const cube = utils.splitArray(result, lastKernel.output[0] * lastKernel.output[1]);
+ return cube.map(function(x) {
+ return utils.splitArray(x, lastKernel.output[0]);
+ });
+ }
+ }
+
+ constructor(source, settings) {
+ super(source, settings);
+ 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 } = this.constructor;
+ if (this.texSize[0] > features.maxTextureSize || this.texSize[1] > features.maxTextureSize) {
+ throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${features.maxTextureSize},${features.maxTextureSize}]`);
+ }
+ }
+
+ translateSource() {
+ throw new Error(`"translateSource" not defined on ${this.constructor.name}`);
+ }
+
+ pickRenderStrategy(args) {
+ if (this.graphical) {
+ this.renderRawOutput = this.readPackedPixelsToUint8Array;
+ this.transferValues = (pixels) => pixels;
+ this.TextureConstructor = GLTextureGraphical;
+ return null;
+ }
+ if (this.precision === 'unsigned') {
+ this.renderRawOutput = this.readPackedPixelsToUint8Array;
+ this.transferValues = this.readPackedPixelsToFloat32Array;
+ if (this.pipeline) {
+ this.renderOutput = this.renderTexture;
+ if (this.subKernels !== null) {
+ this.renderKernels = this.renderKernelsToTextures;
+ }
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Float':
+ case 'Number':
+ case 'Integer':
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureUnsigned3D;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureUnsigned2D;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureUnsigned;
+ return null;
+ }
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ return this.requestFallback(args);
+ }
+ } else {
+ if (this.subKernels !== null) {
+ this.renderKernels = this.renderKernelsToArrays;
+ }
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Float':
+ case 'Number':
+ case 'Integer':
+ this.renderOutput = this.renderValues;
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureUnsigned3D;
+ this.formatValues = utils.erect3DPackedFloat;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureUnsigned2D;
+ this.formatValues = utils.erect2DPackedFloat;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureUnsigned;
+ this.formatValues = utils.erectPackedFloat;
+ return null;
+ }
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ return this.requestFallback(args);
+ }
+ }
+ } else if (this.precision === 'single') {
+ this.renderRawOutput = this.readFloatPixelsToFloat32Array;
+ this.transferValues = this.readFloatPixelsToFloat32Array;
+ if (this.pipeline) {
+ this.renderOutput = this.renderTexture;
+ if (this.subKernels !== null) {
+ this.renderKernels = this.renderKernelsToTextures;
+ }
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Float':
+ case 'Number':
+ case 'Integer': {
+ if (this.optimizeFloatMemory) {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureMemoryOptimized3D;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureMemoryOptimized2D;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureMemoryOptimized;
+ return null;
+ }
+ } else {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureFloat3D;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureFloat2D;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureFloat;
+ return null;
+ }
+ }
+ }
+ case 'Array(2)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray2Float3D;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray2Float2D;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray2Float;
+ return null;
+ }
+ }
+ case 'Array(3)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray3Float3D;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray3Float2D;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray3Float;
+ return null;
+ }
+ }
+ case 'Array(4)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray4Float3D;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray4Float2D;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray4Float;
+ return null;
+ }
+ }
+ }
+ }
+ this.renderOutput = this.renderValues;
+ if (this.subKernels !== null) {
+ this.renderKernels = this.renderKernelsToArrays;
+ }
+ if (this.optimizeFloatMemory) {
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Float':
+ case 'Number':
+ case 'Integer': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureMemoryOptimized3D;
+ this.formatValues = utils.erectMemoryOptimized3DFloat;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureMemoryOptimized2D;
+ this.formatValues = utils.erectMemoryOptimized2DFloat;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureMemoryOptimized;
+ this.formatValues = utils.erectMemoryOptimizedFloat;
+ return null;
+ }
+ }
+ case 'Array(2)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray2Float3D;
+ this.formatValues = utils.erect3DArray2;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray2Float2D;
+ this.formatValues = utils.erect2DArray2;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray2Float;
+ this.formatValues = utils.erectArray2;
+ return null;
+ }
+ }
+ case 'Array(3)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray3Float3D;
+ this.formatValues = utils.erect3DArray3;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray3Float2D;
+ this.formatValues = utils.erect2DArray3;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray3Float;
+ this.formatValues = utils.erectArray3;
+ return null;
+ }
+ }
+ case 'Array(4)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray4Float3D;
+ this.formatValues = utils.erect3DArray4;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray4Float2D;
+ this.formatValues = utils.erect2DArray4;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray4Float;
+ this.formatValues = utils.erectArray4;
+ return null;
+ }
+ }
+ }
+ } else {
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Float':
+ case 'Number':
+ case 'Integer': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureFloat3D;
+ this.formatValues = utils.erect3DFloat;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureFloat2D;
+ this.formatValues = utils.erect2DFloat;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureFloat;
+ this.formatValues = utils.erectFloat;
+ return null;
+ }
+ }
+ case 'Array(2)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray2Float3D;
+ this.formatValues = utils.erect3DArray2;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray2Float2D;
+ this.formatValues = utils.erect2DArray2;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray2Float;
+ this.formatValues = utils.erectArray2;
+ return null;
+ }
+ }
+ case 'Array(3)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray3Float3D;
+ this.formatValues = utils.erect3DArray3;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray3Float2D;
+ this.formatValues = utils.erect2DArray3;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray3Float;
+ this.formatValues = utils.erectArray3;
+ return null;
+ }
+ }
+ case 'Array(4)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray4Float3D;
+ this.formatValues = utils.erect3DArray4;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray4Float2D;
+ this.formatValues = utils.erect2DArray4;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray4Float;
+ this.formatValues = utils.erectArray4;
+ return null;
+ }
+ }
+ }
+ }
+ } else {
+ throw new Error(`unhandled precision of "${this.precision}"`);
+ }
+
+ 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() {
+ if (this.graphical) {
+ return this.getMainResultGraphical();
+ } else if (this.precision === 'single') {
+ if (this.optimizeFloatMemory) {
+ return this.getMainResultMemoryOptimizedFloats();
+ }
+ return this.getMainResultTexture();
+ } else {
+ return this.getMainResultPackedPixels();
+ }
+ }
+
+ getMainResultNumberTexture() {
+ return utils.linesToString(this.getMainResultKernelNumberTexture()) +
+ utils.linesToString(this.getMainResultSubKernelNumberTexture());
+ }
+
+ getMainResultArray2Texture() {
+ return utils.linesToString(this.getMainResultKernelArray2Texture()) +
+ utils.linesToString(this.getMainResultSubKernelArray2Texture());
+ }
+
+ getMainResultArray3Texture() {
+ return utils.linesToString(this.getMainResultKernelArray3Texture()) +
+ utils.linesToString(this.getMainResultSubKernelArray3Texture());
+ }
+
+ getMainResultArray4Texture() {
+ return utils.linesToString(this.getMainResultKernelArray4Texture()) +
+ utils.linesToString(this.getMainResultSubKernelArray4Texture());
+ }
+
+ getFloatTacticDeclaration() {
+ const variablePrecision = this.getVariablePrecisionString(this.texSize, this.tactic);
+ return `precision ${variablePrecision} float;\n`;
+ }
+
+ getIntTacticDeclaration() {
+ return `precision ${this.getVariablePrecisionString(this.texSize, this.tactic, true)} 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 (this.precision !== 'unsigned') throw new Error('Requires this.precision to be "unsigned"');
+ const {
+ texSize,
+ context: gl
+ } = this;
+ const result = new Uint8Array(texSize[0] * texSize[1] * 4);
+ gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, result);
+ return result;
+ }
+
+ readPackedPixelsToFloat32Array() {
+ return new Float32Array(this.readPackedPixelsToUint8Array().buffer);
+ }
+
+ readFloatPixelsToFloat32Array() {
+ if (this.precision !== 'single') throw new Error('Requires this.precision to be "single"');
+ const {
+ texSize,
+ context: gl
+ } = this;
+ const w = texSize[0];
+ const h = texSize[1];
+ const result = new Float32Array(w * h * 4);
+ gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result);
+ return result;
+ }
+
+ getPixels(flip) {
+ const {
+ context: gl,
+ output
+ } = this;
+ const [width, height] = output;
+ const pixels = new Uint8Array(width * height * 4);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+ return new Uint8ClampedArray((flip ? pixels : utils.flipPixels(pixels, width, height)).buffer);
+ }
+
+ renderKernelsToArrays() {
+ const result = {
+ result: this.renderOutput(),
+ };
+ for (let i = 0; i < this.subKernels.length; i++) {
+ result[this.subKernels[i].property] = this.mappedTextures[i].toArray();
+ }
+ return result;
+ }
+
+ renderKernelsToTextures() {
+ const result = {
+ result: this.renderOutput(),
+ };
+ 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) {
+ if (!this.dynamicOutput) {
+ throw new Error('Resizing a kernel with dynamicOutput: false is not possible');
+ }
+ const newThreadDim = [newOutput[0], newOutput[1] || 1, newOutput[2] || 1];
+ const newTexSize = utils.getKernelTextureSize({
+ optimizeFloatMemory: this.optimizeFloatMemory,
+ precision: this.precision,
+ }, newThreadDim);
+ const oldTexSize = this.texSize;
+ if (oldTexSize) {
+ const oldPrecision = this.getVariablePrecisionString(oldTexSize, this.tactic);
+ const newPrecision = this.getVariablePrecisionString(newTexSize, this.tactic);
+ if (oldPrecision !== newPrecision) {
+ if (this.debug) {
+ console.warn('Precision requirement changed, asking GPU instance to recompile');
+ }
+ this.switchKernels({
+ type: 'outputPrecisionMismatch',
+ precision: newPrecision,
+ needed: output
+ });
+ return;
+ }
+ }
+ this.output = newOutput;
+ this.threadDim = newThreadDim;
+ this.texSize = newTexSize;
+ const { context: gl } = this;
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
+ this.updateMaxTexSize();
+ this.framebuffer.width = this.texSize[0];
+ this.framebuffer.height = this.texSize[1];
+ gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);
+ this.canvas.width = this.maxTexSize[0];
+ this.canvas.height = this.maxTexSize[1];
+ if (this.texture) {
+ this.texture.delete();
+ }
+ this.texture = null;
+ this._setupOutputTexture();
+ if (this.mappedTextures && this.mappedTextures.length > 0) {
+ for (let i = 0; i < this.mappedTextures.length; i++) {
+ this.mappedTextures[i].delete();
+ }
+ this.mappedTextures = null;
+ this._setupSubOutputTextures();
+ }
+ } else {
+ this.output = newOutput;
+ }
+ return this;
+ }
+ 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';
+ const low = this.constructor.features[isInt ? 'lowIntPrecision' : 'lowFloatPrecision'];
+ const medium = this.constructor.features[isInt ? 'mediumIntPrecision' : 'mediumFloatPrecision'];
+ const high = this.constructor.features[isInt ? 'highIntPrecision' : 'highFloatPrecision'];
+ const requiredSize = Math.log2(textureSize[0] * textureSize[1]);
+ if (requiredSize <= low.rangeMax) {
+ return 'lowp';
+ } else if (requiredSize <= medium.rangeMax) {
+ return 'mediump';
+ } else if (requiredSize <= high.rangeMax) {
+ return 'highp';
+ } else {
+ throw new Error(`The required size exceeds that of the ability of your system`);
+ }
+ }
+ switch (tactic) {
+ case 'speed':
+ return 'lowp';
+ case 'balanced':
+ return 'mediump';
+ case 'precision':
+ return 'highp';
+ default:
+ throw new Error(`Unknown tactic "${tactic}" use "speed", "balanced", "precision", or empty for auto`);
+ }
+ }
+
+ updateTextureArgumentRefs(kernelValue, arg) {
+ if (!this.immutable) return;
+ if (this.texture.texture === arg.texture) {
+ const { prevArg } = kernelValue;
+ if (prevArg) {
+ if (prevArg.texture._refs === 1) {
+ this.texture.delete();
+ this.texture = prevArg.clone();
+ this._textureSwitched = true;
+ }
+ prevArg.delete();
+ }
+ kernelValue.prevArg = arg.clone();
+ } else if (this.mappedTextures && this.mappedTextures.length > 0) {
+ const { mappedTextures } = this;
+ for (let i = 0; i < mappedTextures.length; i++) {
+ const mappedTexture = mappedTextures[i];
+ if (mappedTexture.texture === arg.texture) {
+ const { prevArg } = kernelValue;
+ if (prevArg) {
+ if (prevArg.texture._refs === 1) {
+ mappedTexture.delete();
+ mappedTextures[i] = prevArg.clone();
+ this._mappedTextureSwitched[i] = true;
+ }
+ prevArg.delete();
+ }
+ kernelValue.prevArg = arg.clone();
+ return;
+ }
+ }
+ }
+ }
+
+ onActivate(previousKernel) {
+ this._textureSwitched = true;
+ this.texture = previousKernel.texture;
+ if (this.mappedTextures) {
+ for (let i = 0; i < this.mappedTextures.length; i++) {
+ this._mappedTextureSwitched[i] = true;
+ }
+ this.mappedTextures = previousKernel.mappedTextures;
+ }
+ }
+
+ initCanvas() {}
+}
+
+const typeMap = {
+ int: 'Integer',
+ float: 'Number',
+ vec2: 'Array(2)',
+ vec3: 'Array(3)',
+ vec4: 'Array(4)',
+};
+
+module.exports = {
+ GLKernel
+};
+},{"../../utils":113,"../kernel":35,"./texture/array-2-float":15,"./texture/array-2-float-2d":13,"./texture/array-2-float-3d":14,"./texture/array-3-float":18,"./texture/array-3-float-2d":16,"./texture/array-3-float-3d":17,"./texture/array-4-float":21,"./texture/array-4-float-2d":19,"./texture/array-4-float-3d":20,"./texture/float":24,"./texture/float-2d":22,"./texture/float-3d":23,"./texture/graphical":25,"./texture/memory-optimized":29,"./texture/memory-optimized-2d":27,"./texture/memory-optimized-3d":28,"./texture/unsigned":32,"./texture/unsigned-2d":30,"./texture/unsigned-3d":31}],13:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray2Float2D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(2)';
+ }
+ toArray() {
+ return utils.erect2DArray2(this.renderValues(), this.output[0], this.output[1]);
+ }
+}
+
+module.exports = {
+ GLTextureArray2Float2D
+};
+},{"../../../utils":113,"./float":24}],14:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray2Float3D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(2)';
+ }
+ toArray() {
+ return utils.erect3DArray2(this.renderValues(), this.output[0], this.output[1], this.output[2]);
+ }
+}
+
+module.exports = {
+ GLTextureArray2Float3D
+};
+},{"../../../utils":113,"./float":24}],15:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray2Float extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(2)';
+ }
+ toArray() {
+ return utils.erectArray2(this.renderValues(), this.output[0], this.output[1]);
+ }
+}
+
+module.exports = {
+ GLTextureArray2Float
+};
+},{"../../../utils":113,"./float":24}],16:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray3Float2D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(3)';
+ }
+ toArray() {
+ return utils.erect2DArray3(this.renderValues(), this.output[0], this.output[1]);
+ }
+}
+
+module.exports = {
+ GLTextureArray3Float2D
+};
+},{"../../../utils":113,"./float":24}],17:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray3Float3D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(3)';
+ }
+ toArray() {
+ return utils.erect3DArray3(this.renderValues(), this.output[0], this.output[1], this.output[2]);
+ }
+}
+
+module.exports = {
+ GLTextureArray3Float3D
+};
+},{"../../../utils":113,"./float":24}],18:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray3Float extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(3)';
+ }
+ toArray() {
+ return utils.erectArray3(this.renderValues(), this.output[0]);
+ }
+}
+
+module.exports = {
+ GLTextureArray3Float
+};
+},{"../../../utils":113,"./float":24}],19:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray4Float2D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(4)';
+ }
+ toArray() {
+ return utils.erect2DArray4(this.renderValues(), this.output[0], this.output[1]);
+ }
+}
+
+module.exports = {
+ GLTextureArray4Float2D
+};
+},{"../../../utils":113,"./float":24}],20:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray4Float3D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(4)';
+ }
+ toArray() {
+ return utils.erect3DArray4(this.renderValues(), this.output[0], this.output[1], this.output[2]);
+ }
+}
+
+module.exports = {
+ GLTextureArray4Float3D
+};
+},{"../../../utils":113,"./float":24}],21:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray4Float extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(4)';
+ }
+ toArray() {
+ return utils.erectArray4(this.renderValues(), this.output[0]);
+ }
+}
+
+module.exports = {
+ GLTextureArray4Float
+};
+},{"../../../utils":113,"./float":24}],22:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureFloat2D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(1)';
+ }
+ toArray() {
+ return utils.erect2DFloat(this.renderValues(), this.output[0], this.output[1]);
+ }
+}
+
+module.exports = {
+ GLTextureFloat2D
+};
+},{"../../../utils":113,"./float":24}],23:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureFloat3D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(1)';
+ }
+ toArray() {
+ return utils.erect3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]);
+ }
+}
+
+module.exports = {
+ GLTextureFloat3D
+};
+},{"../../../utils":113,"./float":24}],24:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTexture } = require('./index');
+
+class GLTextureFloat extends GLTexture {
+ get textureType() {
+ return this.context.FLOAT;
+ }
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(1)';
+ }
+ renderRawOutput() {
+ const gl = this.context;
+ const size = this.size;
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer());
+ gl.framebufferTexture2D(
+ gl.FRAMEBUFFER,
+ gl.COLOR_ATTACHMENT0,
+ gl.TEXTURE_2D,
+ this.texture,
+ 0
+ );
+ const result = new Float32Array(size[0] * size[1] * 4);
+ gl.readPixels(0, 0, size[0], size[1], gl.RGBA, gl.FLOAT, result);
+ return result;
+ }
+ renderValues() {
+ if (this._deleted) return null;
+ return this.renderRawOutput();
+ }
+ toArray() {
+ return utils.erectFloat(this.renderValues(), this.output[0]);
+ }
+}
+
+module.exports = {
+ GLTextureFloat
+};
+},{"../../../utils":113,"./index":26}],25:[function(require,module,exports){
+const { GLTextureUnsigned } = require('./unsigned');
+
+class GLTextureGraphical extends GLTextureUnsigned {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(4)';
+ }
+ toArray() {
+ return this.renderValues();
+ }
+}
+
+module.exports = {
+ GLTextureGraphical
+};
+},{"./unsigned":32}],26:[function(require,module,exports){
+const { Texture } = require('../../../texture');
+
+class GLTexture extends Texture {
+ get textureType() {
+ throw new Error(`"textureType" not implemented on ${ this.name }`);
+ }
+
+ clone() {
+ return new this.constructor(this);
+ }
+
+ beforeMutate() {
+ if (this.texture._refs > 1) {
+ this.newTexture();
+ return true;
+ }
+ return false;
+ }
+
+ cloneTexture() {
+ this.texture._refs--;
+ const { context: gl, size, texture, kernel } = this;
+ if (kernel.debug) {
+ console.warn('cloning internal texture');
+ }
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer());
+ selectTexture(gl, texture);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ const target = gl.createTexture();
+ selectTexture(gl, target);
+ gl.texImage2D(gl.TEXTURE_2D, 0, this.internalFormat, size[0], size[1], 0, this.textureFormat, this.textureType, null);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, size[0], size[1]);
+ target._refs = 1;
+ this.texture = target;
+ }
+
+ newTexture() {
+ this.texture._refs--;
+ const gl = this.context;
+ const size = this.size;
+ const kernel = this.kernel;
+ if (kernel.debug) {
+ console.warn('new internal texture');
+ }
+ const target = gl.createTexture();
+ selectTexture(gl, target);
+ gl.texImage2D(gl.TEXTURE_2D, 0, this.internalFormat, size[0], size[1], 0, this.textureFormat, this.textureType, null);
+ target._refs = 1;
+ this.texture = target;
+ }
+
+ clear() {
+ if (this.texture._refs) {
+ this.texture._refs--;
+ const gl = this.context;
+ const target = this.texture = gl.createTexture();
+ selectTexture(gl, target);
+ const size = this.size;
+ target._refs = 1;
+ gl.texImage2D(gl.TEXTURE_2D, 0, this.internalFormat, size[0], size[1], 0, this.textureFormat, this.textureType, null);
+ }
+ const { context: gl, texture } = this;
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer());
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ selectTexture(gl, texture);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ gl.clearColor(0, 0, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ }
+
+ delete() {
+ if (this._deleted) return;
+ this._deleted = true;
+ if (this.texture._refs) {
+ this.texture._refs--;
+ if (this.texture._refs) return;
+ }
+ this.context.deleteTexture(this.texture);
+ }
+
+ framebuffer() {
+ if (!this._framebuffer) {
+ this._framebuffer = this.kernel.getRawValueFramebuffer(this.size[0], this.size[1]);
+ }
+ return this._framebuffer;
+ }
+}
+
+function selectTexture(gl, texture) {
+ gl.activeTexture(gl.TEXTURE15);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+}
+
+module.exports = { GLTexture };
+},{"../../../texture":112}],27:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureMemoryOptimized2D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'MemoryOptimizedNumberTexture';
+ }
+ toArray() {
+ return utils.erectMemoryOptimized2DFloat(this.renderValues(), this.output[0], this.output[1]);
+ }
+}
+
+module.exports = {
+ GLTextureMemoryOptimized2D
+};
+},{"../../../utils":113,"./float":24}],28:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureMemoryOptimized3D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'MemoryOptimizedNumberTexture';
+ }
+ toArray() {
+ return utils.erectMemoryOptimized3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]);
+ }
+}
+
+module.exports = {
+ GLTextureMemoryOptimized3D
+};
+},{"../../../utils":113,"./float":24}],29:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureMemoryOptimized extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'MemoryOptimizedNumberTexture';
+ }
+ toArray() {
+ return utils.erectMemoryOptimizedFloat(this.renderValues(), this.output[0]);
+ }
+}
+
+module.exports = {
+ GLTextureMemoryOptimized
+};
+},{"../../../utils":113,"./float":24}],30:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureUnsigned } = require('./unsigned');
+
+class GLTextureUnsigned2D extends GLTextureUnsigned {
+ constructor(settings) {
+ super(settings);
+ this.type = 'NumberTexture';
+ }
+ toArray() {
+ return utils.erect2DPackedFloat(this.renderValues(), this.output[0], this.output[1]);
+ }
+}
+
+module.exports = {
+ GLTextureUnsigned2D
+};
+},{"../../../utils":113,"./unsigned":32}],31:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureUnsigned } = require('./unsigned');
+
+class GLTextureUnsigned3D extends GLTextureUnsigned {
+ constructor(settings) {
+ super(settings);
+ this.type = 'NumberTexture';
+ }
+ toArray() {
+ return utils.erect3DPackedFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]);
+ }
+}
+
+module.exports = {
+ GLTextureUnsigned3D
+};
+},{"../../../utils":113,"./unsigned":32}],32:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTexture } = require('./index');
+
+class GLTextureUnsigned extends GLTexture {
+ get textureType() {
+ return this.context.UNSIGNED_BYTE;
+ }
+ constructor(settings) {
+ super(settings);
+ this.type = 'NumberTexture';
+ }
+ renderRawOutput() {
+ const { context: gl } = this;
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer());
+ gl.framebufferTexture2D(
+ gl.FRAMEBUFFER,
+ gl.COLOR_ATTACHMENT0,
+ gl.TEXTURE_2D,
+ this.texture,
+ 0
+ );
+ const result = new Uint8Array(this.size[0] * this.size[1] * 4);
+ gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.UNSIGNED_BYTE, result);
+ return result;
+ }
+ renderValues() {
+ if (this._deleted) return null;
+ return new Float32Array(this.renderRawOutput().buffer);
+ }
+ toArray() {
+ return utils.erectPackedFloat(this.renderValues(), this.output[0]);
+ }
+}
+
+module.exports = {
+ GLTextureUnsigned
+};
+},{"../../../utils":113,"./index":26}],33:[function(require,module,exports){
+const getContext = require('gl');
+const { WebGLKernel } = require('../web-gl/kernel');
+const { glKernelString } = require('../gl/kernel-string');
+
+let isSupported = null;
+let testCanvas = null;
+let testContext = null;
+let testExtensions = null;
+let features = null;
+
+class HeadlessGLKernel extends WebGLKernel {
+ static get isSupported() {
+ if (isSupported !== null) return isSupported;
+ this.setupFeatureChecks();
+ isSupported = testContext !== null;
+ return isSupported;
+ }
+
+ static setupFeatureChecks() {
+ testCanvas = null;
+ testExtensions = null;
+ if (typeof getContext !== 'function') return;
+ try {
+ testContext = getContext(2, 2, {
+ preserveDrawingBuffer: true
+ });
+ if (!testContext || !testContext.getExtension) return;
+ testExtensions = {
+ STACKGL_resize_drawingbuffer: testContext.getExtension('STACKGL_resize_drawingbuffer'),
+ STACKGL_destroy_context: testContext.getExtension('STACKGL_destroy_context'),
+ OES_texture_float: testContext.getExtension('OES_texture_float'),
+ OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'),
+ OES_element_index_uint: testContext.getExtension('OES_element_index_uint'),
+ WEBGL_draw_buffers: testContext.getExtension('WEBGL_draw_buffers'),
+ WEBGL_color_buffer_float: testContext.getExtension('WEBGL_color_buffer_float'),
+ };
+ features = this.getFeatures();
+ } catch (e) {
+ console.warn(e);
+ }
+ }
+
+ static isContextMatch(context) {
+ try {
+ return context.getParameter(context.RENDERER) === 'ANGLE';
+ } catch (e) {
+ return false;
+ }
+ }
+
+ static getIsTextureFloat() {
+ return Boolean(testExtensions.OES_texture_float);
+ }
+
+ static getIsDrawBuffers() {
+ return Boolean(testExtensions.WEBGL_draw_buffers);
+ }
+
+ static getChannelCount() {
+ return testExtensions.WEBGL_draw_buffers ?
+ testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) :
+ 1;
+ }
+
+ static getMaxTextureSize() {
+ return testContext.getParameter(testContext.MAX_TEXTURE_SIZE);
+ }
+
+ static get testCanvas() {
+ return testCanvas;
+ }
+
+ static get testContext() {
+ return testContext;
+ }
+
+ static get features() {
+ return features;
+ }
+
+ initCanvas() {
+ return {};
+ }
+
+ initContext() {
+ return getContext(2, 2, {
+ preserveDrawingBuffer: true
+ });
+ }
+
+ 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);
+ if (!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(context) {
+ const extension = context.getExtension('STACKGL_destroy_context');
+ if (extension && extension.destroy) {
+ extension.destroy();
+ }
+ }
+
+ toString() {
+ const setupContextString = `const gl = context || require('gl')(1, 1);\n`;
+ const destroyContextString = ` if (!context) { gl.getExtension('STACKGL_destroy_context').destroy(); }\n`;
+ return glKernelString(this.constructor, arguments, this, setupContextString, destroyContextString);
+ }
+
+ setOutput(output) {
+ super.setOutput(output);
+ if (this.graphical && this.extensions.STACKGL_resize_drawingbuffer) {
+ this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0], this.maxTexSize[1]);
+ }
+ return this;
+ }
+}
+
+module.exports = {
+ HeadlessGLKernel
+};
+},{"../gl/kernel-string":11,"../web-gl/kernel":69,"gl":1}],34:[function(require,module,exports){
+class KernelValue {
+ constructor(value, settings) {
+ const {
+ name,
+ kernel,
+ context,
+ checkContext,
+ onRequestContextHandle,
+ onUpdateValueMismatch,
+ origin,
+ strictIntegers,
+ type,
+ tactic,
+ } = settings;
+ if (!name) {
+ throw new Error('name not set');
+ }
+ if (!type) {
+ throw new Error('type not set');
+ }
+ if (!origin) {
+ throw new Error('origin not set');
+ }
+ if (origin !== 'user' && origin !== 'constants') {
+ throw new Error(`origin must be "user" or "constants" value is "${ origin }"`);
+ }
+ if (!onRequestContextHandle) {
+ throw new Error('onRequestContextHandle is not set');
+ }
+ this.name = name;
+ this.origin = origin;
+ this.tactic = tactic;
+ this.varName = origin === 'constants' ? `constants.${name}` : name;
+ this.kernel = kernel;
+ this.strictIntegers = strictIntegers;
+ this.type = value.type || type;
+ this.size = value.size || null;
+ this.index = null;
+ this.context = context;
+ this.checkContext = checkContext !== null && checkContext !== undefined ? checkContext : true;
+ this.contextHandle = null;
+ this.onRequestContextHandle = onRequestContextHandle;
+ this.onUpdateValueMismatch = onUpdateValueMismatch;
+ this.forceUploadEachRun = null;
+ }
+
+ get id() {
+ return `${this.origin}_${name}`;
+ }
+
+ getSource() {
+ throw new Error(`"getSource" not defined on ${ this.constructor.name }`);
+ }
+
+ updateValue(value) {
+ throw new Error(`"updateValue" not defined on ${ this.constructor.name }`);
+ }
+}
+
+module.exports = {
+ KernelValue
+};
+},{}],35:[function(require,module,exports){
+const { utils } = require('../utils');
+const { Input } = require('../input');
+
+class Kernel {
+ static get isSupported() {
+ throw new Error(`"isSupported" not implemented on ${ this.name }`);
+ }
+
+ static isContextMatch(context) {
+ throw new Error(`"isContextMatch" not implemented on ${ this.name }`);
+ }
+
+ static getFeatures() {
+ throw new Error(`"getFeatures" not implemented on ${ this.name }`);
+ }
+
+ static destroyContext(context) {
+ 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(source, settings) {
+ if (typeof source !== 'object') {
+ if (typeof source !== 'string') {
+ throw new Error('source not a string');
+ }
+ if (!utils.isFunctionString(source)) {
+ throw new Error('source not a function string');
+ }
+ }
+ this.useLegacyEncoder = false;
+ this.fallbackRequested = false;
+ this.onRequestFallback = null;
+
+ this.argumentNames = typeof source === 'string' ? utils.getArgumentNamesFromString(source) : null;
+ this.argumentTypes = null;
+ this.argumentSizes = null;
+ this.argumentBitRatios = null;
+ this.kernelArguments = null;
+ this.kernelConstants = null;
+ this.forceUploadKernelConstants = null;
+
+
+ this.source = source;
+
+ this.output = null;
+
+ this.debug = false;
+
+ this.graphical = false;
+
+ this.loopMaxIterations = 0;
+
+ this.constants = null;
+
+ this.constantTypes = null;
+
+ this.constantBitRatios = null;
+
+ this.dynamicArguments = false;
+
+ this.dynamicOutput = false;
+
+ 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 = true;
+
+ this.immutable = false;
+
+ this.pipeline = false;
+
+ this.precision = null;
+
+ this.tactic = null;
+
+ this.plugins = null;
+
+ this.returnType = null;
+ this.leadingReturnStatement = null;
+ this.followingReturnStatement = null;
+ this.optimizeFloatMemory = null;
+ this.strictIntegers = false;
+ this.fixIntegerDivisionAccuracy = null;
+ this.built = false;
+ this.signature = null;
+ }
+
+ mergeSettings(settings) {
+ for (let p in settings) {
+ if (!settings.hasOwnProperty(p) || !this.hasOwnProperty(p)) continue;
+ switch (p) {
+ case 'output':
+ if (!Array.isArray(settings.output)) {
+ this.setOutput(settings.output);
+ continue;
+ }
+ break;
+ case 'functions':
+ this.functions = [];
+ for (let i = 0; i < settings.functions.length; i++) {
+ this.addFunction(settings.functions[i]);
+ }
+ continue;
+ case 'graphical':
+ if (settings[p] && !settings.hasOwnProperty('precision')) {
+ this.precision = 'unsigned';
+ }
+ this[p] = settings[p];
+ continue;
+ case 'nativeFunctions':
+ if (!settings.nativeFunctions) continue;
+ this.nativeFunctions = [];
+ for (let i = 0; i < settings.nativeFunctions.length; i++) {
+ const s = settings.nativeFunctions[i];
+ const { name, source } = s;
+ this.addNativeFunction(name, source, s);
+ }
+ continue;
+ }
+ this[p] = settings[p];
+ }
+
+ if (!this.canvas) this.canvas = this.initCanvas();
+ if (!this.context) this.context = this.initContext();
+ if (!this.plugins) this.plugins = this.initPlugins(settings);
+ }
+ build() {
+ throw new Error(`"build" not defined on ${ this.constructor.name }`);
+ }
+
+ run() {
+ throw new Error(`"run" not defined on ${ this.constructor.name }`)
+ }
+
+ initCanvas() {
+ throw new Error(`"initCanvas" not defined on ${ this.constructor.name }`);
+ }
+
+ initContext() {
+ throw new Error(`"initContext" not defined on ${ this.constructor.name }`);
+ }
+
+ initPlugins(settings) {
+ throw new Error(`"initPlugins" not defined on ${ this.constructor.name }`);
+ }
+
+ addFunction(source, settings = {}) {
+ if (source.name && source.source && source.argumentTypes && 'returnType' in source) {
+ this.functions.push(source);
+ } else if ('settings' in source && 'source' in source) {
+ this.functions.push(this.functionToIGPUFunction(source.source, source.settings));
+ } else if (typeof source === 'string' || typeof source === 'function') {
+ this.functions.push(this.functionToIGPUFunction(source, settings));
+ } else {
+ throw new Error(`function not properly defined`);
+ }
+ return this;
+ }
+
+ addNativeFunction(name, source, settings = {}) {
+ const { argumentTypes, argumentNames } = settings.argumentTypes ?
+ splitArgumentTypes(settings.argumentTypes) :
+ this.constructor.nativeFunctionArguments(source) || {};
+ this.nativeFunctions.push({
+ name,
+ source,
+ settings,
+ argumentTypes,
+ argumentNames,
+ returnType: settings.returnType || this.constructor.nativeFunctionReturnType(source)
+ });
+ return this;
+ }
+
+ setupArguments(args) {
+ this.kernelArguments = [];
+ if (!this.argumentTypes) {
+ if (!this.argumentTypes) {
+ this.argumentTypes = [];
+ for (let i = 0; i < args.length; i++) {
+ const argType = utils.getVariableType(args[i], this.strictIntegers);
+ const type = argType === 'Integer' ? 'Number' : argType;
+ this.argumentTypes.push(type);
+ this.kernelArguments.push({
+ type
+ });
+ }
+ }
+ } else {
+ for (let i = 0; i < this.argumentTypes.length; i++) {
+ this.kernelArguments.push({
+ type: this.argumentTypes[i]
+ });
+ }
+ }
+
+ this.argumentSizes = new Array(args.length);
+ this.argumentBitRatios = new Int32Array(args.length);
+
+ for (let i = 0; i < args.length; i++) {
+ const arg = args[i];
+ this.argumentSizes[i] = arg.constructor === Input ? arg.size : null;
+ this.argumentBitRatios[i] = this.getBitRatio(arg);
+ }
+
+ if (this.argumentNames.length !== args.length) {
+ throw new Error(`arguments are miss-aligned`);
+ }
+ }
+
+ setupConstants() {
+ this.kernelConstants = [];
+ let needsConstantTypes = this.constantTypes === null;
+ if (needsConstantTypes) {
+ this.constantTypes = {};
+ }
+ this.constantBitRatios = {};
+ if (this.constants) {
+ for (let name in this.constants) {
+ if (needsConstantTypes) {
+ const type = utils.getVariableType(this.constants[name], this.strictIntegers);
+ this.constantTypes[name] = type;
+ this.kernelConstants.push({
+ name,
+ type
+ });
+ } else {
+ this.kernelConstants.push({
+ name,
+ type: this.constantTypes[name]
+ });
+ }
+ this.constantBitRatios[name] = this.getBitRatio(this.constants[name]);
+ }
+ }
+ }
+
+ setOptimizeFloatMemory(flag) {
+ this.optimizeFloatMemory = flag;
+ return this;
+ }
+
+ toKernelOutput(output) {
+ if (output.hasOwnProperty('x')) {
+ if (output.hasOwnProperty('y')) {
+ if (output.hasOwnProperty('z')) {
+ return [output.x, output.y, output.z];
+ } else {
+ return [output.x, output.y];
+ }
+ } else {
+ return [output.x];
+ }
+ } else {
+ return output;
+ }
+ }
+
+ setOutput(output) {
+ this.output = this.toKernelOutput(output);
+ return this;
+ }
+
+ setDebug(flag) {
+ this.debug = flag;
+ return this;
+ }
+
+ setGraphical(flag) {
+ this.graphical = flag;
+ this.precision = 'unsigned';
+ return this;
+ }
+
+ setLoopMaxIterations(max) {
+ this.loopMaxIterations = max;
+ return this;
+ }
+
+ setConstants(constants) {
+ this.constants = constants;
+ return this;
+ }
+
+ setConstantTypes(constantTypes) {
+ this.constantTypes = constantTypes;
+ return this;
+ }
+
+ setFunctions(functions) {
+ for (let i = 0; i < functions.length; i++) {
+ this.addFunction(functions[i]);
+ }
+ return this;
+ }
+
+ setNativeFunctions(nativeFunctions) {
+ for (let i = 0; i < nativeFunctions.length; i++) {
+ const settings = nativeFunctions[i];
+ const { name, source } = settings;
+ this.addNativeFunction(name, source, settings);
+ }
+ return this;
+ }
+
+ setInjectedNative(injectedNative) {
+ this.injectedNative = injectedNative;
+ return this;
+ }
+
+ setPipeline(flag) {
+ this.pipeline = flag;
+ return this;
+ }
+
+ setPrecision(flag) {
+ this.precision = flag;
+ return this;
+ }
+
+ setDimensions(flag) {
+ utils.warnDeprecated('method', 'setDimensions', 'setOutput');
+ this.output = flag;
+ return this;
+ }
+
+ setOutputToTexture(flag) {
+ utils.warnDeprecated('method', 'setOutputToTexture', 'setPipeline');
+ this.pipeline = flag;
+ return this;
+ }
+
+ setImmutable(flag) {
+ this.immutable = flag;
+ return this;
+ }
+
+ setCanvas(canvas) {
+ this.canvas = canvas;
+ return this;
+ }
+
+ setStrictIntegers(flag) {
+ this.strictIntegers = flag;
+ return this;
+ }
+
+ setDynamicOutput(flag) {
+ this.dynamicOutput = flag;
+ return this;
+ }
+
+ setHardcodeConstants(flag) {
+ utils.warnDeprecated('method', 'setHardcodeConstants');
+ this.setDynamicOutput(flag);
+ this.setDynamicArguments(flag);
+ return this;
+ }
+
+ setDynamicArguments(flag) {
+ this.dynamicArguments = flag;
+ return this;
+ }
+
+ setUseLegacyEncoder(flag) {
+ this.useLegacyEncoder = flag;
+ return this;
+ }
+
+ setWarnVarUsage(flag) {
+ utils.warnDeprecated('method', 'setWarnVarUsage');
+ return this;
+ }
+
+ getCanvas() {
+ utils.warnDeprecated('method', 'getCanvas');
+ return this.canvas;
+ }
+
+ getWebGl() {
+ utils.warnDeprecated('method', 'getWebGl');
+ return this.context;
+ }
+
+ setContext(context) {
+ this.context = context;
+ return this;
+ }
+
+ setArgumentTypes(argumentTypes) {
+ if (Array.isArray(argumentTypes)) {
+ this.argumentTypes = argumentTypes;
+ } else {
+ this.argumentTypes = [];
+ for (const p in argumentTypes) {
+ if (!argumentTypes.hasOwnProperty(p)) continue;
+ const argumentIndex = this.argumentNames.indexOf(p);
+ if (argumentIndex === -1) throw new Error(`unable to find argument ${ p }`);
+ this.argumentTypes[argumentIndex] = argumentTypes[p];
+ }
+ }
+ return this;
+ }
+
+ setTactic(tactic) {
+ this.tactic = tactic;
+ return this;
+ }
+
+ requestFallback(args) {
+ if (!this.onRequestFallback) {
+ throw new Error(`"onRequestFallback" not defined on ${ this.constructor.name }`);
+ }
+ this.fallbackRequested = true;
+ return this.onRequestFallback(args);
+ }
+
+ validateSettings() {
+ throw new Error(`"validateSettings" not defined on ${ this.constructor.name }`);
+ }
+
+ addSubKernel(subKernel) {
+ if (this.subKernels === null) {
+ this.subKernels = [];
+ }
+ if (!subKernel.source) throw new Error('subKernel missing "source" property');
+ if (!subKernel.property && isNaN(subKernel.property)) throw new Error('subKernel missing "property" property');
+ if (!subKernel.name) throw new Error('subKernel missing "name" property');
+ this.subKernels.push(subKernel);
+ return this;
+ }
+
+ destroy(removeCanvasReferences) {
+ throw new Error(`"destroy" called on ${ this.constructor.name }`);
+ }
+
+ getBitRatio(value) {
+ if (this.precision === 'single') {
+ return 4;
+ } else if (Array.isArray(value[0])) {
+ return this.getBitRatio(value[0]);
+ } else if (value.constructor === Input) {
+ return this.getBitRatio(value.value);
+ }
+ switch (value.constructor) {
+ case Uint8ClampedArray:
+ case Uint8Array:
+ case Int8Array:
+ return 1;
+ case Uint16Array:
+ case Int16Array:
+ return 2;
+ case Float32Array:
+ case Int32Array:
+ default:
+ return 4;
+ }
+ }
+
+ getPixels(flip) {
+ throw new Error(`"getPixels" called on ${ this.constructor.name }`);
+ }
+
+ checkOutput() {
+ if (!this.output || !utils.isArray(this.output)) throw new Error('kernel.output not an array');
+ if (this.output.length < 1) throw new Error('kernel.output is empty, needs at least 1 value');
+ for (let i = 0; i < this.output.length; i++) {
+ if (isNaN(this.output[i]) || this.output[i] < 1) {
+ throw new Error(`${ this.constructor.name }.output[${ i }] incorrectly defined as \`${ this.output[i] }\`, needs to be numeric, and greater than 0`);
+ }
+ }
+ }
+
+ prependString(value) {
+ throw new Error(`"prependString" called on ${ this.constructor.name }`);
+ }
+
+ hasPrependString(value) {
+ throw new Error(`"hasPrependString" called on ${ this.constructor.name }`);
+ }
+
+ toJSON() {
+ return {
+ settings: {
+ output: this.output,
+ pipeline: this.pipeline,
+ argumentNames: this.argumentNames,
+ argumentsTypes: this.argumentTypes,
+ constants: this.constants,
+ pluginNames: this.plugins ? this.plugins.map(plugin => plugin.name) : null,
+ returnType: this.returnType,
+ }
+ };
+ }
+
+ buildSignature(args) {
+ const Constructor = this.constructor;
+ this.signature = Constructor.getSignature(this, Constructor.getArgumentTypes(this, args));
+ }
+
+ static getArgumentTypes(kernel, args) {
+ const argumentTypes = new Array(args.length);
+ for (let i = 0; i < args.length; i++) {
+ const arg = args[i];
+ const type = kernel.argumentTypes[i];
+ if (arg.type) {
+ argumentTypes[i] = arg.type;
+ } else {
+ switch (type) {
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ case 'ArrayTexture(1)':
+ argumentTypes[i] = utils.getVariableType(arg);
+ break;
+ default:
+ argumentTypes[i] = type;
+ }
+ }
+ }
+ return argumentTypes;
+ }
+
+ static getSignature(kernel, argumentTypes) {
+ throw new Error(`"getSignature" not implemented on ${ this.name }`);
+ }
+
+ functionToIGPUFunction(source, settings = {}) {
+ if (typeof source !== 'string' && typeof source !== 'function') throw new Error('source not a string or function');
+ const sourceString = typeof source === 'string' ? source : source.toString();
+ let argumentTypes = [];
+
+ if (Array.isArray(settings.argumentTypes)) {
+ argumentTypes = settings.argumentTypes;
+ } else if (typeof settings.argumentTypes === 'object') {
+ argumentTypes = utils.getArgumentNamesFromString(sourceString)
+ .map(name => settings.argumentTypes[name]) || [];
+ } else {
+ argumentTypes = settings.argumentTypes || [];
+ }
+
+ return {
+ name: utils.getFunctionNameFromString(sourceString) || null,
+ source: sourceString,
+ argumentTypes,
+ returnType: settings.returnType || null,
+ };
+ }
+
+ onActivate(previousKernel) {}
+}
+
+function splitArgumentTypes(argumentTypesObject) {
+ const argumentNames = Object.keys(argumentTypesObject);
+ const argumentTypes = [];
+ for (let i = 0; i < argumentNames.length; i++) {
+ const argumentName = argumentNames[i];
+ argumentTypes.push(argumentTypesObject[argumentName]);
+ }
+ return { argumentTypes, argumentNames };
+}
+
+module.exports = {
+ Kernel
+};
+},{"../input":109,"../utils":113}],36:[function(require,module,exports){
+const fragmentShader = `__HEADER__;
+__FLOAT_TACTIC_DECLARATION__;
+__INT_TACTIC_DECLARATION__;
+__SAMPLER_2D_TACTIC_DECLARATION__;
+
+const int LOOP_MAX = __LOOP_MAX__;
+
+__PLUGINS__;
+__CONSTANTS__;
+
+varying vec2 vTexCoord;
+
+float acosh(float x) {
+ return log(x + sqrt(x * x - 1.0));
+}
+
+float sinh(float x) {
+ return (pow(${Math.E}, x) - pow(${Math.E}, -x)) / 2.0;
+}
+
+float asinh(float x) {
+ return log(x + sqrt(x * x + 1.0));
+}
+
+float atan2(float v1, float v2) {
+ if (v1 == 0.0 || v2 == 0.0) return 0.0;
+ return atan(v1 / v2);
+}
+
+float atanh(float x) {
+ x = (x + 1.0) / (x - 1.0);
+ if (x < 0.0) {
+ return 0.5 * log(-x);
+ }
+ return 0.5 * log(x);
+}
+
+float cbrt(float x) {
+ if (x >= 0.0) {
+ return pow(x, 1.0 / 3.0);
+ } else {
+ return -pow(x, 1.0 / 3.0);
+ }
+}
+
+float cosh(float x) {
+ return (pow(${Math.E}, x) + pow(${Math.E}, -x)) / 2.0;
+}
+
+float expm1(float x) {
+ return pow(${Math.E}, x) - 1.0;
+}
+
+float fround(highp float x) {
+ return x;
+}
+
+float imul(float v1, float v2) {
+ return float(int(v1) * int(v2));
+}
+
+float log10(float x) {
+ return log2(x) * (1.0 / log2(10.0));
+}
+
+float log1p(float x) {
+ return log(1.0 + x);
+}
+
+float _pow(float v1, float v2) {
+ if (v2 == 0.0) return 1.0;
+ return pow(v1, v2);
+}
+
+float tanh(float x) {
+ float e = exp(2.0 * x);
+ return (e - 1.0) / (e + 1.0);
+}
+
+float trunc(float x) {
+ if (x >= 0.0) {
+ return floor(x);
+ } else {
+ return ceil(x);
+ }
+}
+
+vec4 _round(vec4 x) {
+ return floor(x + 0.5);
+}
+
+float _round(float x) {
+ return floor(x + 0.5);
+}
+
+const int BIT_COUNT = 32;
+int modi(int x, int y) {
+ return x - y * (x / y);
+}
+
+int bitwiseOr(int a, int b) {
+ int result = 0;
+ int n = 1;
+
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {
+ result += n;
+ }
+ a = a / 2;
+ b = b / 2;
+ n = n * 2;
+ if(!(a > 0 || b > 0)) {
+ break;
+ }
+ }
+ return result;
+}
+int bitwiseXOR(int a, int b) {
+ int result = 0;
+ int n = 1;
+
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {
+ result += n;
+ }
+ a = a / 2;
+ b = b / 2;
+ n = n * 2;
+ if(!(a > 0 || b > 0)) {
+ break;
+ }
+ }
+ return result;
+}
+int bitwiseAnd(int a, int b) {
+ int result = 0;
+ int n = 1;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {
+ result += n;
+ }
+ a = a / 2;
+ b = b / 2;
+ n = n * 2;
+ if(!(a > 0 && b > 0)) {
+ break;
+ }
+ }
+ return result;
+}
+int bitwiseNot(int a) {
+ int result = 0;
+ int n = 1;
+
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (modi(a, 2) == 0) {
+ result += n;
+ }
+ a = a / 2;
+ n = n * 2;
+ }
+ return result;
+}
+int bitwiseZeroFillLeftShift(int n, int shift) {
+ int maxBytes = BIT_COUNT;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (maxBytes >= n) {
+ break;
+ }
+ maxBytes *= 2;
+ }
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= shift) {
+ break;
+ }
+ n *= 2;
+ }
+
+ int result = 0;
+ int byteVal = 1;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= maxBytes) break;
+ if (modi(n, 2) > 0) { result += byteVal; }
+ n = int(n / 2);
+ byteVal *= 2;
+ }
+ return result;
+}
+
+int bitwiseSignedRightShift(int num, int shifts) {
+ return int(floor(float(num) / pow(2.0, float(shifts))));
+}
+
+int bitwiseZeroFillRightShift(int n, int shift) {
+ int maxBytes = BIT_COUNT;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (maxBytes >= n) {
+ break;
+ }
+ maxBytes *= 2;
+ }
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= shift) {
+ break;
+ }
+ n /= 2;
+ }
+ int result = 0;
+ int byteVal = 1;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= maxBytes) break;
+ if (modi(n, 2) > 0) { result += byteVal; }
+ n = int(n / 2);
+ byteVal *= 2;
+ }
+ return result;
+}
+
+vec2 integerMod(vec2 x, float y) {
+ vec2 res = floor(mod(x, y));
+ return res * step(1.0 - floor(y), -res);
+}
+
+vec3 integerMod(vec3 x, float y) {
+ vec3 res = floor(mod(x, y));
+ return res * step(1.0 - floor(y), -res);
+}
+
+vec4 integerMod(vec4 x, vec4 y) {
+ vec4 res = floor(mod(x, y));
+ return res * step(1.0 - floor(y), -res);
+}
+
+float integerMod(float x, float y) {
+ float res = floor(mod(x, y));
+ return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);
+}
+
+int integerMod(int x, int y) {
+ return x - (y * int(x / y));
+}
+
+__DIVIDE_WITH_INTEGER_CHECK__;
+
+// Here be dragons!
+// DO NOT OPTIMIZE THIS CODE
+// YOU WILL BREAK SOMETHING ON SOMEBODY\'S MACHINE
+// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME
+const vec2 MAGIC_VEC = vec2(1.0, -256.0);
+const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);
+const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536
+float decode32(vec4 texel) {
+ __DECODE32_ENDIANNESS__;
+ texel *= 255.0;
+ vec2 gte128;
+ gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;
+ gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;
+ float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);
+ float res = exp2(_round(exponent));
+ texel.b = texel.b - 128.0 * gte128.x;
+ res = dot(texel, SCALE_FACTOR) * exp2(_round(exponent-23.0)) + res;
+ res *= gte128.y * -2.0 + 1.0;
+ return res;
+}
+
+float decode16(vec4 texel, int index) {
+ int channel = integerMod(index, 2);
+ if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0;
+ if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0;
+ return 0.0;
+}
+
+float decode8(vec4 texel, int index) {
+ int channel = integerMod(index, 4);
+ if (channel == 0) return texel.r * 255.0;
+ if (channel == 1) return texel.g * 255.0;
+ if (channel == 2) return texel.b * 255.0;
+ if (channel == 3) return texel.a * 255.0;
+ return 0.0;
+}
+
+vec4 legacyEncode32(float f) {
+ float F = abs(f);
+ float sign = f < 0.0 ? 1.0 : 0.0;
+ float exponent = floor(log2(F));
+ float mantissa = (exp2(-exponent) * F);
+ // exponent += floor(log2(mantissa));
+ vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;
+ texel.rg = integerMod(texel.rg, 256.0);
+ texel.b = integerMod(texel.b, 128.0);
+ texel.a = exponent*0.5 + 63.5;
+ texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;
+ texel = floor(texel);
+ texel *= 0.003921569; // 1/255
+ __ENCODE32_ENDIANNESS__;
+ return texel;
+}
+
+// https://github.com/gpujs/gpu.js/wiki/Encoder-details
+vec4 encode32(float value) {
+ if (value == 0.0) return vec4(0, 0, 0, 0);
+
+ float exponent;
+ float mantissa;
+ vec4 result;
+ float sgn;
+
+ sgn = step(0.0, -value);
+ value = abs(value);
+
+ exponent = floor(log2(value));
+
+ mantissa = value*pow(2.0, -exponent)-1.0;
+ exponent = exponent+127.0;
+ result = vec4(0,0,0,0);
+
+ result.a = floor(exponent/2.0);
+ exponent = exponent - result.a*2.0;
+ result.a = result.a + 128.0*sgn;
+
+ result.b = floor(mantissa * 128.0);
+ mantissa = mantissa - result.b / 128.0;
+ result.b = result.b + exponent*128.0;
+
+ result.g = floor(mantissa*32768.0);
+ mantissa = mantissa - result.g/32768.0;
+
+ result.r = floor(mantissa*8388608.0);
+ return result/255.0;
+}
+// Dragons end here
+
+int index;
+ivec3 threadId;
+
+ivec3 indexTo3D(int idx, ivec3 texDim) {
+ int z = int(idx / (texDim.x * texDim.y));
+ idx -= z * int(texDim.x * texDim.y);
+ int y = int(idx / texDim.x);
+ int x = int(integerMod(idx, texDim.x));
+ return ivec3(x, y, z);
+}
+
+float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture2D(tex, st / vec2(texSize));
+ return decode32(texel);
+}
+
+float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int w = texSize.x * 2;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y));
+ return decode16(texel, index);
+}
+
+float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int w = texSize.x * 4;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y));
+ return decode8(texel, index);
+}
+
+float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int channel = integerMod(index, 4);
+ index = index / 4;
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture2D(tex, st / vec2(texSize));
+ if (channel == 0) return texel.r;
+ if (channel == 1) return texel.g;
+ if (channel == 2) return texel.b;
+ if (channel == 3) return texel.a;
+ return 0.0;
+}
+
+vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ return texture2D(tex, st / vec2(texSize));
+}
+
+float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
+ return result[0];
+}
+
+vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
+ return vec2(result[0], result[1]);
+}
+
+vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + (texDim.x * (y + (texDim.y * z)));
+ int channel = integerMod(index, 2);
+ index = index / 2;
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture2D(tex, st / vec2(texSize));
+ if (channel == 0) return vec2(texel.r, texel.g);
+ if (channel == 1) return vec2(texel.b, texel.a);
+ return vec2(0.0, 0.0);
+}
+
+vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
+ return vec3(result[0], result[1], result[2]);
+}
+
+vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));
+ int vectorIndex = fieldIndex / 4;
+ int vectorOffset = fieldIndex - vectorIndex * 4;
+ int readY = vectorIndex / texSize.x;
+ int readX = vectorIndex - readY * texSize.x;
+ vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));
+
+ if (vectorOffset == 0) {
+ return tex1.xyz;
+ } else if (vectorOffset == 1) {
+ return tex1.yzw;
+ } else {
+ readX++;
+ if (readX >= texSize.x) {
+ readX = 0;
+ readY++;
+ }
+ vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize));
+ if (vectorOffset == 2) {
+ return vec3(tex1.z, tex1.w, tex2.x);
+ } else {
+ return vec3(tex1.w, tex2.x, tex2.y);
+ }
+ }
+}
+
+vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ return getImage2D(tex, texSize, texDim, z, y, x);
+}
+
+vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int channel = integerMod(index, 2);
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture2D(tex, st / vec2(texSize));
+ return vec4(texel.r, texel.g, texel.b, texel.a);
+}
+
+vec4 actualColor;
+void color(float r, float g, float b, float a) {
+ actualColor = vec4(r,g,b,a);
+}
+
+void color(float r, float g, float b) {
+ color(r,g,b,1.0);
+}
+
+void color(sampler2D image) {
+ actualColor = texture2D(image, vTexCoord);
+}
+
+float modulo(float number, float divisor) {
+ if (number < 0.0) {
+ number = abs(number);
+ if (divisor < 0.0) {
+ divisor = abs(divisor);
+ }
+ return -mod(number, divisor);
+ }
+ if (divisor < 0.0) {
+ divisor = abs(divisor);
+ }
+ return mod(number, divisor);
+}
+
+__INJECTED_NATIVE__;
+__MAIN_CONSTANTS__;
+__MAIN_ARGUMENTS__;
+__KERNEL__;
+
+void main(void) {
+ index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;
+ __MAIN_RESULT__;
+}`;
+
+module.exports = {
+ fragmentShader
+};
+},{}],37:[function(require,module,exports){
+const { utils } = require('../../utils');
+const { FunctionNode } = require('../function-node');
+
+class WebGLFunctionNode extends FunctionNode {
+ constructor(source, settings) {
+ super(source, settings);
+ if (settings && settings.hasOwnProperty('fixIntegerDivisionAccuracy')) {
+ this.fixIntegerDivisionAccuracy = settings.fixIntegerDivisionAccuracy;
+ }
+ }
+
+ 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;
+ }
+ retArr.push('(');
+ this.astGeneric(ast.test, retArr);
+ retArr.push('?');
+ this.astGeneric(ast.consequent, retArr);
+ retArr.push(':');
+ this.astGeneric(ast.alternate, retArr);
+ retArr.push(')');
+ return retArr;
+ }
+
+ astFunction(ast, retArr) {
+ if (this.isRootKernel) {
+ retArr.push('void');
+ } else {
+ 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;
+ if (!returnType) {
+ retArr.push('void');
+ } else {
+ const type = typeMap[returnType];
+ if (!type) {
+ throw new Error(`unknown type ${returnType}`);
+ }
+ retArr.push(type);
+ }
+ }
+ retArr.push(' ');
+ retArr.push(this.name);
+ retArr.push('(');
+
+ if (!this.isRootKernel) {
+ 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 type = typeMap[argumentType];
+ if (!type) {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ const name = utils.sanitizeName(argumentName);
+ if (type === 'sampler2D' || type === 'sampler2DArray') {
+ retArr.push(`${type} user_${name},ivec2 user_${name}Size,ivec3 user_${name}Dim`);
+ } else {
+ retArr.push(`${type} user_${name}`);
+ }
+ }
+ }
+
+ 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('float(');
+ this.astGeneric(ast.argument, result);
+ result.push(')');
+ break;
+ case 'LiteralInteger':
+ this.castLiteralToFloat(ast.argument, result);
+
+ if (this.getType(ast) === 'Integer') {
+ result.unshift('float(');
+ 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 'Array(4)':
+ case 'Array(3)':
+ case 'Array(2)':
+ case 'Matrix(2)':
+ case 'Matrix(3)':
+ case 'Matrix(4)':
+ case 'Input':
+ this.astGeneric(ast.argument, result);
+ break;
+ default:
+ throw this.astErrorOutput(`unhandled return type ${this.returnType}`, ast);
+ }
+
+ if (this.isRootKernel) {
+ retArr.push(`kernelResult = ${ result.join('') };`);
+ retArr.push('return;');
+ } else if (this.isSubKernel) {
+ retArr.push(`subKernelResult_${ this.name } = ${ result.join('') };`);
+ retArr.push(`return subKernelResult_${ this.name };`);
+ } else {
+ retArr.push(`return ${ result.join('') };`);
+ }
+ return retArr;
+ }
+
+ astLiteral(ast, 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(`${ast.value}`);
+ } else if (this.isState('casting-to-float') || this.isState('building-float')) {
+ this.literalTypes[key] = 'Number';
+ retArr.push(`${ast.value}.0`);
+ } else {
+ this.literalTypes[key] = 'Number';
+ retArr.push(`${ast.value}.0`);
+ }
+ } else if (this.isState('casting-to-integer') || this.isState('building-integer')) {
+ this.literalTypes[key] = 'Integer';
+ retArr.push(Math.round(ast.value));
+ } else {
+ this.literalTypes[key] = 'Number';
+ retArr.push(`${ast.value}`);
+ }
+ return retArr;
+ }
+
+ astBinaryExpression(ast, retArr) {
+ if (this.checkAndUpconvertOperator(ast, retArr)) {
+ return retArr;
+ }
+
+ if (this.fixIntegerDivisionAccuracy && ast.operator === '/') {
+ retArr.push('divWithIntCheck(');
+ 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(', ');
+ 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';
+ if (!leftType || !rightType) {
+ throw this.astErrorOutput(`Unhandled binary expression`, ast);
+ }
+ 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);
+ 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('int(');
+ 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.astGeneric(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) {
+ const bitwiseResult = this.checkAndUpconvertBitwiseOperators(ast, retArr);
+ if (bitwiseResult) {
+ return bitwiseResult;
+ }
+ const upconvertableOperators = {
+ '%': this.fixIntegerDivisionAccuracy ? 'integerCorrectionModulo' : 'modulo',
+ '**': 'pow',
+ };
+ const foundOperator = upconvertableOperators[ast.operator];
+ if (!foundOperator) return null;
+ retArr.push(foundOperator);
+ 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 upconvertableOperators = {
+ '&': 'bitwiseAnd',
+ '|': 'bitwiseOr',
+ '^': 'bitwiseXOR',
+ '<<': 'bitwiseZeroFillLeftShift',
+ '>>': 'bitwiseSignedRightShift',
+ '>>>': 'bitwiseZeroFillRightShift',
+ };
+ const foundOperator = upconvertableOperators[ast.operator];
+ if (!foundOperator) return null;
+ retArr.push(foundOperator);
+ retArr.push('(');
+ const leftType = this.getType(ast.left);
+ switch (leftType) {
+ case 'Number':
+ case 'Float':
+ this.castValueToInteger(ast.left, retArr);
+ break;
+ case 'LiteralInteger':
+ this.castLiteralToInteger(ast.left, retArr);
+ break;
+ default:
+ this.astGeneric(ast.left, retArr);
+ }
+ retArr.push(',');
+ const rightType = this.getType(ast.right);
+ switch (rightType) {
+ case 'Number':
+ case 'Float':
+ this.castValueToInteger(ast.right, retArr);
+ break;
+ case 'LiteralInteger':
+ this.castLiteralToInteger(ast.right, retArr);
+ break;
+ default:
+ this.astGeneric(ast.right, retArr);
+ }
+ retArr.push(')');
+ return retArr;
+ }
+
+ checkAndUpconvertBitwiseUnary(ast, retArr) {
+ const upconvertableOperators = {
+ '~': 'bitwiseNot',
+ };
+ const foundOperator = upconvertableOperators[ast.operator];
+ if (!foundOperator) return null;
+ retArr.push(foundOperator);
+ 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;
+ }
+
+ 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('int(');
+ this.astGeneric(ast, retArr);
+ retArr.push(')');
+ this.popState('casting-to-integer');
+ return retArr;
+ }
+
+ castValueToFloat(ast, retArr) {
+ this.pushState('casting-to-float');
+ retArr.push('float(');
+ 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('3.402823466e+38');
+ } else if (type === 'Boolean') {
+ if (this.argumentNames.indexOf(name) > -1) {
+ retArr.push(`bool(user_${name})`);
+ } else {
+ retArr.push(`user_${name}`);
+ }
+ } else {
+ 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) {
+ 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 (int ${iVariableName}=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 (int ${iVariableName}=0;${iVariableName} 0) {
+ declarationSets.push(declarationSet.join(','));
+ }
+
+ result.push(declarationSets.join(';'));
+
+ retArr.push(result.join(''));
+ retArr.push(';');
+ return retArr;
+ }
+
+ astIfStatement(ifNode, retArr) {
+ retArr.push('if (');
+ this.astGeneric(ifNode.test, retArr);
+ retArr.push(')');
+ if (ifNode.consequent.type === 'BlockStatement') {
+ this.astGeneric(ifNode.consequent, retArr);
+ } else {
+ retArr.push(' {\n');
+ this.astGeneric(ifNode.consequent, retArr);
+ retArr.push('\n}\n');
+ }
+
+ if (ifNode.alternate) {
+ retArr.push('else ');
+ if (ifNode.alternate.type === 'BlockStatement' || ifNode.alternate.type === 'IfStatement') {
+ this.astGeneric(ifNode.alternate, retArr);
+ } else {
+ retArr.push(' {\n');
+ this.astGeneric(ifNode.alternate, retArr);
+ retArr.push('\n}\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(`float ${varName} = `);
+ this.astGeneric(discriminant, retArr);
+ retArr.push(';\n');
+ break;
+ case 'Integer':
+ retArr.push(`int ${varName} = `);
+ this.astGeneric(discriminant, retArr);
+ retArr.push(';\n');
+ break;
+ }
+ if (cases.length === 1 && !cases[0].test) {
+ this.astGeneric(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.astGeneric(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 if (type === 'Float') {
+ 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;
+ }
+ } else {
+ throw new Error('unhanlded');
+ }
+ if (!cases[i].consequent || cases[i].consequent.length === 0) {
+ fallingThrough = true;
+ retArr.push(' || ');
+ continue;
+ }
+ retArr.push(`) {\n`);
+ }
+ this.astGeneric(cases[i].consequent, retArr);
+ retArr.push('\n}');
+ }
+ if (movingDefaultToEnd) {
+ retArr.push(' else {');
+ retArr.push(defaultResult.join(''));
+ retArr.push('}');
+ }
+ return retArr;
+ }
+
+ astThisExpression(tNode, retArr) {
+ retArr.push('this');
+ return retArr;
+ }
+
+ 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);
+ }
+ retArr.push(`threadId.${name}`);
+ return retArr;
+ case 'this.output.value':
+ if (this.dynamicOutput) {
+ switch (name) {
+ case 'x':
+ if (this.isState('casting-to-float')) {
+ retArr.push('float(uOutputDim.x)');
+ } else {
+ retArr.push('uOutputDim.x');
+ }
+ break;
+ case 'y':
+ if (this.isState('casting-to-float')) {
+ retArr.push('float(uOutputDim.y)');
+ } else {
+ retArr.push('uOutputDim.y');
+ }
+ break;
+ case 'z':
+ if (this.isState('casting-to-float')) {
+ retArr.push('float(uOutputDim.z)');
+ } else {
+ retArr.push('uOutputDim.z');
+ }
+ break;
+ default:
+ throw this.astErrorOutput('Unexpected expression', mNode);
+ }
+ } else {
+ switch (name) {
+ case 'x':
+ if (this.isState('casting-to-integer')) {
+ retArr.push(this.output[0]);
+ } else {
+ retArr.push(this.output[0], '.0');
+ }
+ break;
+ case 'y':
+ if (this.isState('casting-to-integer')) {
+ retArr.push(this.output[1]);
+ } else {
+ retArr.push(this.output[1], '.0');
+ }
+ break;
+ case 'z':
+ if (this.isState('casting-to-integer')) {
+ retArr.push(this.output[2]);
+ } else {
+ retArr.push(this.output[2], '.0');
+ }
+ break;
+ default:
+ throw this.astErrorOutput('Unexpected expression', mNode);
+ }
+ }
+ 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(Math[name]);
+ return retArr;
+ }
+ const cleanName = utils.sanitizeName(name);
+ switch (property) {
+ case 'r':
+ retArr.push(`user_${ cleanName }.r`);
+ return retArr;
+ case 'g':
+ retArr.push(`user_${ cleanName }.g`);
+ return retArr;
+ case 'b':
+ retArr.push(`user_${ cleanName }.b`);
+ return retArr;
+ case 'a':
+ retArr.push(`user_${ cleanName }.a`);
+ return retArr;
+ }
+ break;
+ case 'this.constants.value':
+ if (typeof xProperty === 'undefined') {
+ switch (type) {
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ retArr.push(`constants_${ utils.sanitizeName(name) }`);
+ return retArr;
+ }
+ }
+ 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;
+ case 'fn()[][]':
+ this.astCallExpression(mNode.object.object, retArr);
+ retArr.push('[');
+ retArr.push(this.memberExpressionPropertyMarkup(mNode.object.property));
+ retArr.push(']');
+ retArr.push('[');
+ retArr.push(this.memberExpressionPropertyMarkup(mNode.property));
+ retArr.push(']');
+ return retArr;
+ case '[][]':
+ this.astArrayExpression(mNode.object, retArr);
+ retArr.push('[');
+ retArr.push(this.memberExpressionPropertyMarkup(property));
+ retArr.push(']');
+ return retArr;
+ default:
+ throw this.astErrorOutput('Unexpected expression', mNode);
+ }
+
+ if (mNode.computed === false) {
+ switch (type) {
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ case 'Boolean':
+ retArr.push(`${origin}_${utils.sanitizeName(name)}`);
+ return retArr;
+ }
+ }
+
+ 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 'HTMLImageArray':
+ retArr.push(`getImage3D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'ArrayTexture(1)':
+ retArr.push(`getFloatFromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'Array1D(2)':
+ case 'Array2D(2)':
+ case 'Array3D(2)':
+ retArr.push(`getMemoryOptimizedVec2(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'ArrayTexture(2)':
+ retArr.push(`getVec2FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'Array1D(3)':
+ case 'Array2D(3)':
+ case 'Array3D(3)':
+ retArr.push(`getMemoryOptimizedVec3(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'ArrayTexture(3)':
+ retArr.push(`getVec3FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'Array1D(4)':
+ case 'Array2D(4)':
+ case 'Array3D(4)':
+ retArr.push(`getMemoryOptimizedVec4(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'ArrayTexture(4)':
+ case 'HTMLCanvas':
+ case 'OffscreenCanvas':
+ case 'HTMLImage':
+ case 'ImageBitmap':
+ case 'ImageData':
+ case 'HTMLVideo':
+ retArr.push(`getVec4FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'NumberTexture':
+ case 'Array':
+ case 'Array2D':
+ case 'Array3D':
+ case 'Array4D':
+ case 'Input':
+ case 'Number':
+ case 'Float':
+ case 'Integer':
+ if (this.precision === 'single') {
+ retArr.push(`getMemoryOptimized32(${markupName}, ${markupName}Size, ${markupName}Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ } else {
+ const bitRatio = (origin === 'user' ?
+ this.lookupFunctionArgumentBitRatio(this.name, name) :
+ this.constantBitRatios[name]
+ );
+ switch (bitRatio) {
+ case 1:
+ retArr.push(`get8(${markupName}, ${markupName}Size, ${markupName}Dim, `);
+ break;
+ case 2:
+ retArr.push(`get16(${markupName}, ${markupName}Size, ${markupName}Dim, `);
+ break;
+ case 4:
+ case 0:
+ retArr.push(`get32(${markupName}, ${markupName}Size, ${markupName}Dim, `);
+ break;
+ default:
+ throw new Error(`unhandled bit ratio of ${bitRatio}`);
+ }
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ }
+ break;
+ case 'MemoryOptimizedNumberTexture':
+ retArr.push(`getMemoryOptimized32(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'Matrix(2)':
+ case 'Matrix(3)':
+ case 'Matrix(4)':
+ retArr.push(`${markupName}[${this.memberExpressionPropertyMarkup(yProperty)}]`);
+ if (yProperty) {
+ retArr.push(`[${this.memberExpressionPropertyMarkup(xProperty)}]`);
+ }
+ break;
+ default:
+ throw new Error(`unhandled member expression "${ type }"`);
+ }
+ 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);
+ }
+
+ switch (functionName) {
+ case 'pow':
+ functionName = '_pow';
+ break;
+ case 'round':
+ functionName = '_round';
+ break;
+ }
+
+ if (this.calledFunctions.indexOf(functionName) < 0) {
+ this.calledFunctions.push(functionName);
+ }
+
+ if (functionName === 'random' && this.plugins && this.plugins.length > 0) {
+ for (let i = 0; i < this.plugins.length; i++) {
+ const plugin = this.plugins[i];
+ if (plugin.functionMatch === 'Math.random()' && plugin.functionReplace) {
+ retArr.push(plugin.functionReplace);
+ return retArr;
+ }
+ }
+ }
+
+ if (this.onFunctionCall) {
+ this.onFunctionCall(this.name, functionName, ast.arguments);
+ }
+
+ retArr.push(functionName);
+
+ 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;
+ 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('int(');
+ 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('float(');
+ 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 if (argument.type === 'ArrayExpression' || argument.type === 'MemberExpression' || argument.type === 'CallExpression') {
+ this.astGeneric(argument, retArr);
+ } else {
+ throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast);
+ }
+ 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 (targetType === argumentType) {
+ if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast);
+ this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i);
+ const name = utils.sanitizeName(argument.name);
+ retArr.push(`user_${name},user_${name}Size,user_${name}Dim`);
+ continue;
+ }
+ break;
+ }
+ throw this.astErrorOutput(`Unhandled argument combination of ${ argumentType } and ${ targetType } for argument named "${ argument.name }"`, ast);
+ }
+ }
+ retArr.push(')');
+
+ return retArr;
+ }
+
+ astArrayExpression(arrNode, retArr) {
+ const returnType = this.getType(arrNode);
+
+ const arrLen = arrNode.elements.length;
+
+ switch (returnType) {
+ case 'Matrix(2)':
+ case 'Matrix(3)':
+ case 'Matrix(4)':
+ retArr.push(`mat${arrLen}(`);
+ break;
+ default:
+ retArr.push(`vec${arrLen}(`);
+ }
+ for (let i = 0; i < arrLen; ++i) {
+ if (i > 0) {
+ retArr.push(', ');
+ }
+ const subNode = arrNode.elements[i];
+ 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;
+ default:
+ this.astGeneric(property, result);
+ }
+ return result.join('');
+ }
+}
+
+const typeMap = {
+ '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',
+};
+
+const operatorMap = {
+ '===': '==',
+ '!==': '!='
+};
+
+module.exports = {
+ WebGLFunctionNode
+};
+},{"../../utils":113,"../function-node":9}],38:[function(require,module,exports){
+const { WebGLKernelValueBoolean } = require('./kernel-value/boolean');
+const { WebGLKernelValueFloat } = require('./kernel-value/float');
+const { WebGLKernelValueInteger } = require('./kernel-value/integer');
+
+const { WebGLKernelValueHTMLImage } = require('./kernel-value/html-image');
+const { WebGLKernelValueDynamicHTMLImage } = require('./kernel-value/dynamic-html-image');
+
+const { WebGLKernelValueHTMLVideo } = require('./kernel-value/html-video');
+const { WebGLKernelValueDynamicHTMLVideo } = require('./kernel-value/dynamic-html-video');
+
+const { WebGLKernelValueSingleInput } = require('./kernel-value/single-input');
+const { WebGLKernelValueDynamicSingleInput } = require('./kernel-value/dynamic-single-input');
+
+const { WebGLKernelValueUnsignedInput } = require('./kernel-value/unsigned-input');
+const { WebGLKernelValueDynamicUnsignedInput } = require('./kernel-value/dynamic-unsigned-input');
+
+const { WebGLKernelValueMemoryOptimizedNumberTexture } = require('./kernel-value/memory-optimized-number-texture');
+const { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } = require('./kernel-value/dynamic-memory-optimized-number-texture');
+
+const { WebGLKernelValueNumberTexture } = require('./kernel-value/number-texture');
+const { WebGLKernelValueDynamicNumberTexture } = require('./kernel-value/dynamic-number-texture');
+
+const { WebGLKernelValueSingleArray } = require('./kernel-value/single-array');
+const { WebGLKernelValueDynamicSingleArray } = require('./kernel-value/dynamic-single-array');
+
+const { WebGLKernelValueSingleArray1DI } = require('./kernel-value/single-array1d-i');
+const { WebGLKernelValueDynamicSingleArray1DI } = require('./kernel-value/dynamic-single-array1d-i');
+
+const { WebGLKernelValueSingleArray2DI } = require('./kernel-value/single-array2d-i');
+const { WebGLKernelValueDynamicSingleArray2DI } = require('./kernel-value/dynamic-single-array2d-i');
+
+const { WebGLKernelValueSingleArray3DI } = require('./kernel-value/single-array3d-i');
+const { WebGLKernelValueDynamicSingleArray3DI } = require('./kernel-value/dynamic-single-array3d-i');
+
+const { WebGLKernelValueArray2 } = require('./kernel-value/array2');
+const { WebGLKernelValueArray3 } = require('./kernel-value/array3');
+const { WebGLKernelValueArray4 } = require('./kernel-value/array4');
+
+const { WebGLKernelValueUnsignedArray } = require('./kernel-value/unsigned-array');
+const { WebGLKernelValueDynamicUnsignedArray } = require('./kernel-value/dynamic-unsigned-array');
+
+const kernelValueMaps = {
+ unsigned: {
+ dynamic: {
+ 'Boolean': WebGLKernelValueBoolean,
+ 'Integer': WebGLKernelValueInteger,
+ 'Float': WebGLKernelValueFloat,
+ 'Array': WebGLKernelValueDynamicUnsignedArray,
+ 'Array(2)': WebGLKernelValueArray2,
+ 'Array(3)': WebGLKernelValueArray3,
+ 'Array(4)': WebGLKernelValueArray4,
+ 'Array1D(2)': false,
+ 'Array1D(3)': false,
+ 'Array1D(4)': false,
+ 'Array2D(2)': false,
+ 'Array2D(3)': false,
+ 'Array2D(4)': false,
+ 'Array3D(2)': false,
+ 'Array3D(3)': false,
+ 'Array3D(4)': false,
+ 'Input': WebGLKernelValueDynamicUnsignedInput,
+ 'NumberTexture': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGLKernelValueDynamicHTMLImage,
+ 'OffscreenCanvas': WebGLKernelValueDynamicHTMLImage,
+ 'HTMLImage': WebGLKernelValueDynamicHTMLImage,
+ 'ImageBitmap': WebGLKernelValueDynamicHTMLImage,
+ 'ImageData': WebGLKernelValueDynamicHTMLImage,
+ 'HTMLImageArray': false,
+ 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo,
+ },
+ static: {
+ 'Boolean': WebGLKernelValueBoolean,
+ 'Float': WebGLKernelValueFloat,
+ 'Integer': WebGLKernelValueInteger,
+ 'Array': WebGLKernelValueUnsignedArray,
+ 'Array(2)': WebGLKernelValueArray2,
+ 'Array(3)': WebGLKernelValueArray3,
+ 'Array(4)': WebGLKernelValueArray4,
+ 'Array1D(2)': false,
+ 'Array1D(3)': false,
+ 'Array1D(4)': false,
+ 'Array2D(2)': false,
+ 'Array2D(3)': false,
+ 'Array2D(4)': false,
+ 'Array3D(2)': false,
+ 'Array3D(3)': false,
+ 'Array3D(4)': false,
+ 'Input': WebGLKernelValueUnsignedInput,
+ 'NumberTexture': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(1)': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(2)': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(3)': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(4)': WebGLKernelValueNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGLKernelValueHTMLImage,
+ 'OffscreenCanvas': WebGLKernelValueHTMLImage,
+ 'HTMLImage': WebGLKernelValueHTMLImage,
+ 'ImageBitmap': WebGLKernelValueHTMLImage,
+ 'ImageData': WebGLKernelValueHTMLImage,
+ 'HTMLImageArray': false,
+ 'HTMLVideo': WebGLKernelValueHTMLVideo,
+ }
+ },
+ single: {
+ dynamic: {
+ 'Boolean': WebGLKernelValueBoolean,
+ 'Integer': WebGLKernelValueInteger,
+ 'Float': WebGLKernelValueFloat,
+ 'Array': WebGLKernelValueDynamicSingleArray,
+ 'Array(2)': WebGLKernelValueArray2,
+ 'Array(3)': WebGLKernelValueArray3,
+ 'Array(4)': WebGLKernelValueArray4,
+ 'Array1D(2)': WebGLKernelValueDynamicSingleArray1DI,
+ 'Array1D(3)': WebGLKernelValueDynamicSingleArray1DI,
+ 'Array1D(4)': WebGLKernelValueDynamicSingleArray1DI,
+ 'Array2D(2)': WebGLKernelValueDynamicSingleArray2DI,
+ 'Array2D(3)': WebGLKernelValueDynamicSingleArray2DI,
+ 'Array2D(4)': WebGLKernelValueDynamicSingleArray2DI,
+ 'Array3D(2)': WebGLKernelValueDynamicSingleArray3DI,
+ 'Array3D(3)': WebGLKernelValueDynamicSingleArray3DI,
+ 'Array3D(4)': WebGLKernelValueDynamicSingleArray3DI,
+ 'Input': WebGLKernelValueDynamicSingleInput,
+ 'NumberTexture': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGLKernelValueDynamicHTMLImage,
+ 'OffscreenCanvas': WebGLKernelValueDynamicHTMLImage,
+ 'HTMLImage': WebGLKernelValueDynamicHTMLImage,
+ 'ImageBitmap': WebGLKernelValueDynamicHTMLImage,
+ 'ImageData': WebGLKernelValueDynamicHTMLImage,
+ 'HTMLImageArray': false,
+ 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo,
+ },
+ static: {
+ 'Boolean': WebGLKernelValueBoolean,
+ 'Float': WebGLKernelValueFloat,
+ 'Integer': WebGLKernelValueInteger,
+ 'Array': WebGLKernelValueSingleArray,
+ 'Array(2)': WebGLKernelValueArray2,
+ 'Array(3)': WebGLKernelValueArray3,
+ 'Array(4)': WebGLKernelValueArray4,
+ 'Array1D(2)': WebGLKernelValueSingleArray1DI,
+ 'Array1D(3)': WebGLKernelValueSingleArray1DI,
+ 'Array1D(4)': WebGLKernelValueSingleArray1DI,
+ 'Array2D(2)': WebGLKernelValueSingleArray2DI,
+ 'Array2D(3)': WebGLKernelValueSingleArray2DI,
+ 'Array2D(4)': WebGLKernelValueSingleArray2DI,
+ 'Array3D(2)': WebGLKernelValueSingleArray3DI,
+ 'Array3D(3)': WebGLKernelValueSingleArray3DI,
+ 'Array3D(4)': WebGLKernelValueSingleArray3DI,
+ 'Input': WebGLKernelValueSingleInput,
+ 'NumberTexture': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(1)': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(2)': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(3)': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(4)': WebGLKernelValueNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGLKernelValueHTMLImage,
+ 'OffscreenCanvas': WebGLKernelValueHTMLImage,
+ 'HTMLImage': WebGLKernelValueHTMLImage,
+ 'ImageBitmap': WebGLKernelValueHTMLImage,
+ 'ImageData': WebGLKernelValueHTMLImage,
+ 'HTMLImageArray': false,
+ 'HTMLVideo': WebGLKernelValueHTMLVideo,
+ }
+ },
+};
+
+function lookupKernelValueType(type, dynamic, precision, value) {
+ if (!type) {
+ throw new Error('type missing');
+ }
+ if (!dynamic) {
+ throw new Error('dynamic missing');
+ }
+ if (!precision) {
+ throw new Error('precision missing');
+ }
+ if (value.type) {
+ type = value.type;
+ }
+ const types = kernelValueMaps[precision][dynamic];
+ if (types[type] === false) {
+ return null;
+ } else if (types[type] === undefined) {
+ throw new Error(`Could not find a KernelValue for ${ type }`);
+ }
+ return types[type];
+}
+
+module.exports = {
+ lookupKernelValueType,
+ kernelValueMaps,
+};
+},{"./kernel-value/array2":40,"./kernel-value/array3":41,"./kernel-value/array4":42,"./kernel-value/boolean":43,"./kernel-value/dynamic-html-image":44,"./kernel-value/dynamic-html-video":45,"./kernel-value/dynamic-memory-optimized-number-texture":46,"./kernel-value/dynamic-number-texture":47,"./kernel-value/dynamic-single-array":48,"./kernel-value/dynamic-single-array1d-i":49,"./kernel-value/dynamic-single-array2d-i":50,"./kernel-value/dynamic-single-array3d-i":51,"./kernel-value/dynamic-single-input":52,"./kernel-value/dynamic-unsigned-array":53,"./kernel-value/dynamic-unsigned-input":54,"./kernel-value/float":55,"./kernel-value/html-image":56,"./kernel-value/html-video":57,"./kernel-value/integer":59,"./kernel-value/memory-optimized-number-texture":60,"./kernel-value/number-texture":61,"./kernel-value/single-array":62,"./kernel-value/single-array1d-i":63,"./kernel-value/single-array2d-i":64,"./kernel-value/single-array3d-i":65,"./kernel-value/single-input":66,"./kernel-value/unsigned-array":67,"./kernel-value/unsigned-input":68}],39:[function(require,module,exports){
+const { WebGLKernelValue } = require('./index');
+const { Input } = require('../../../input');
+
+class WebGLKernelArray extends WebGLKernelValue {
+ checkSize(width, height) {
+ if (!this.kernel.validate) return;
+ const { maxTextureSize } = this.kernel.constructor.features;
+ if (width > maxTextureSize || height > maxTextureSize) {
+ if (width > height) {
+ throw new Error(`Argument texture width of ${width} larger than maximum size of ${maxTextureSize} for your GPU`);
+ } else if (width < height) {
+ throw new Error(`Argument texture height of ${height} larger than maximum size of ${maxTextureSize} for your GPU`);
+ } else {
+ throw new Error(`Argument texture height and width of ${height} larger than maximum size of ${maxTextureSize} for your GPU`);
+ }
+ }
+ }
+
+ setup() {
+ this.requestTexture();
+ this.setupTexture();
+ this.defineTexture();
+ }
+
+ requestTexture() {
+ this.texture = this.onRequestTexture();
+ }
+
+ defineTexture() {
+ const { context: gl } = this;
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ }
+
+ setupTexture() {
+ this.contextHandle = this.onRequestContextHandle();
+ this.index = this.onRequestIndex();
+ this.dimensionsId = this.id + 'Dim';
+ this.sizeId = this.id + 'Size';
+ }
+
+ getBitRatio(value) {
+ if (Array.isArray(value[0])) {
+ return this.getBitRatio(value[0]);
+ } else if (value.constructor === Input) {
+ return this.getBitRatio(value.value);
+ }
+ switch (value.constructor) {
+ case Uint8ClampedArray:
+ case Uint8Array:
+ case Int8Array:
+ return 1;
+ case Uint16Array:
+ case Int16Array:
+ return 2;
+ case Float32Array:
+ case Int32Array:
+ default:
+ return 4;
+ }
+ }
+
+ destroy() {
+ if (this.prevArg) {
+ this.prevArg.delete();
+ }
+ this.context.deleteTexture(this.texture);
+ }
+}
+
+module.exports = {
+ WebGLKernelArray
+};
+},{"../../../input":109,"./index":58}],40:[function(require,module,exports){
+const { WebGLKernelValue } = require('./index');
+
+class WebGLKernelValueArray2 extends WebGLKernelValue {
+ constructor(value, settings) {
+ super(value, settings);
+ this.uploadValue = value;
+ }
+ getSource(value) {
+ if (this.origin === 'constants') {
+ return `const vec2 ${this.id} = vec2(${value[0]},${value[1]});\n`;
+ }
+ return `uniform vec2 ${this.id};\n`;
+ }
+
+ getStringValueHandler() {
+ if (this.origin === 'constants') return '';
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+
+ updateValue(value) {
+ if (this.origin === 'constants') return;
+ this.kernel.setUniform2fv(this.id, this.uploadValue = value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueArray2
+};
+},{"./index":58}],41:[function(require,module,exports){
+const { WebGLKernelValue } = require('./index');
+
+class WebGLKernelValueArray3 extends WebGLKernelValue {
+ constructor(value, settings) {
+ super(value, settings);
+ this.uploadValue = value;
+ }
+ getSource(value) {
+ if (this.origin === 'constants') {
+ return `const vec3 ${this.id} = vec3(${value[0]},${value[1]},${value[2]});\n`;
+ }
+ return `uniform vec3 ${this.id};\n`;
+ }
+
+ getStringValueHandler() {
+ if (this.origin === 'constants') return '';
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+
+ updateValue(value) {
+ if (this.origin === 'constants') return;
+ this.kernel.setUniform3fv(this.id, this.uploadValue = value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueArray3
+};
+},{"./index":58}],42:[function(require,module,exports){
+const { WebGLKernelValue } = require('./index');
+
+class WebGLKernelValueArray4 extends WebGLKernelValue {
+ constructor(value, settings) {
+ super(value, settings);
+ this.uploadValue = value;
+ }
+ getSource(value) {
+ if (this.origin === 'constants') {
+ return `const vec4 ${this.id} = vec4(${value[0]},${value[1]},${value[2]},${value[3]});\n`;
+ }
+ return `uniform vec4 ${this.id};\n`;
+ }
+
+ getStringValueHandler() {
+ if (this.origin === 'constants') return '';
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+
+ updateValue(value) {
+ if (this.origin === 'constants') return;
+ this.kernel.setUniform4fv(this.id, this.uploadValue = value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueArray4
+};
+},{"./index":58}],43:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValue } = require('./index');
+
+class WebGLKernelValueBoolean extends WebGLKernelValue {
+ constructor(value, settings) {
+ super(value, settings);
+ this.uploadValue = value;
+ }
+ getSource(value) {
+ if (this.origin === 'constants') {
+ return `const bool ${this.id} = ${value};\n`;
+ }
+ return `uniform bool ${this.id};\n`;
+ }
+
+ getStringValueHandler() {
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+
+ updateValue(value) {
+ if (this.origin === 'constants') return;
+ this.kernel.setUniform1i(this.id, this.uploadValue = value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueBoolean
+};
+},{"../../../utils":113,"./index":58}],44:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueHTMLImage } = require('./html-image');
+
+class WebGLKernelValueDynamicHTMLImage extends WebGLKernelValueHTMLImage {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ const { width, height } = value;
+ this.checkSize(width, height);
+ this.dimensions = [width, height, 1];
+ this.textureSize = [width, height];
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicHTMLImage
+};
+},{"../../../utils":113,"./html-image":56}],45:[function(require,module,exports){
+const { WebGLKernelValueDynamicHTMLImage } = require('./dynamic-html-image');
+
+class WebGLKernelValueDynamicHTMLVideo extends WebGLKernelValueDynamicHTMLImage {}
+
+module.exports = {
+ WebGLKernelValueDynamicHTMLVideo
+};
+},{"./dynamic-html-image":44}],46:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueMemoryOptimizedNumberTexture } = require('./memory-optimized-number-texture');
+
+class WebGLKernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(inputTexture) {
+ this.dimensions = inputTexture.dimensions;
+ this.checkSize(inputTexture.size[0], inputTexture.size[1]);
+ this.textureSize = inputTexture.size;
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(inputTexture);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicMemoryOptimizedNumberTexture
+};
+},{"../../../utils":113,"./memory-optimized-number-texture":60}],47:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueNumberTexture } = require('./number-texture');
+
+class WebGLKernelValueDynamicNumberTexture extends WebGLKernelValueNumberTexture {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.dimensions = value.dimensions;
+ this.checkSize(value.size[0], value.size[1]);
+ this.textureSize = value.size;
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicNumberTexture
+};
+},{"../../../utils":113,"./number-texture":61}],48:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray } = require('./single-array');
+
+class WebGLKernelValueDynamicSingleArray extends WebGLKernelValueSingleArray {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.dimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.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(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicSingleArray
+};
+},{"../../../utils":113,"./single-array":62}],49:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray1DI } = require('./single-array1d-i');
+
+class WebGLKernelValueDynamicSingleArray1DI extends WebGLKernelValueSingleArray1DI {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.setShape(value);
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicSingleArray1DI
+};
+},{"../../../utils":113,"./single-array1d-i":63}],50:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray2DI } = require('./single-array2d-i');
+
+class WebGLKernelValueDynamicSingleArray2DI extends WebGLKernelValueSingleArray2DI {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.setShape(value);
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicSingleArray2DI
+};
+},{"../../../utils":113,"./single-array2d-i":64}],51:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray3DI } = require('./single-array3d-i');
+
+class WebGLKernelValueDynamicSingleArray3DI extends WebGLKernelValueSingleArray3DI {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.setShape(value);
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicSingleArray3DI
+};
+},{"../../../utils":113,"./single-array3d-i":65}],52:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleInput } = require('./single-input');
+
+class WebGLKernelValueDynamicSingleInput extends WebGLKernelValueSingleInput {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ let [w, h, d] = value.size;
+ this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);
+ this.textureSize = utils.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(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicSingleInput
+};
+},{"../../../utils":113,"./single-input":66}],53:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueUnsignedArray } = require('./unsigned-array');
+
+class WebGLKernelValueDynamicUnsignedArray extends WebGLKernelValueUnsignedArray {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.dimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.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 Type = this.getTransferArrayType(value);
+ this.preUploadValue = new Type(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(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicUnsignedArray
+};
+},{"../../../utils":113,"./unsigned-array":67}],54:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueUnsignedInput } = require('./unsigned-input');
+
+class WebGLKernelValueDynamicUnsignedInput extends WebGLKernelValueUnsignedInput {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ let [w, h, d] = value.size;
+ this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);
+ this.textureSize = utils.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 Type = this.getTransferArrayType(value.value);
+ this.preUploadValue = new Type(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(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicUnsignedInput
+};
+},{"../../../utils":113,"./unsigned-input":68}],55:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValue } = require('./index');
+
+class WebGLKernelValueFloat extends WebGLKernelValue {
+ constructor(value, settings) {
+ super(value, settings);
+ this.uploadValue = value;
+ }
+ getStringValueHandler() {
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+ getSource(value) {
+ if (this.origin === 'constants') {
+ if (Number.isInteger(value)) {
+ return `const float ${this.id} = ${value}.0;\n`;
+ }
+ return `const float ${this.id} = ${value};\n`;
+ }
+ return `uniform float ${this.id};\n`;
+ }
+
+ updateValue(value) {
+ if (this.origin === 'constants') return;
+ this.kernel.setUniform1f(this.id, this.uploadValue = value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueFloat
+};
+},{"../../../utils":113,"./index":58}],56:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueHTMLImage extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ const { width, height } = value;
+ this.checkSize(width, height);
+ this.dimensions = [width, height, 1];
+ this.textureSize = [width, height];
+ this.uploadValue = value;
+ }
+
+ getStringValueHandler() {
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+
+ getSource() {
+ return utils.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(inputImage) {
+ if (inputImage.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(inputImage.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue = inputImage);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueHTMLImage
+};
+},{"../../../utils":113,"./array":39}],57:[function(require,module,exports){
+const { WebGLKernelValueHTMLImage } = require('./html-image');
+
+class WebGLKernelValueHTMLVideo extends WebGLKernelValueHTMLImage {}
+
+module.exports = {
+ WebGLKernelValueHTMLVideo
+};
+},{"./html-image":56}],58:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { KernelValue } = require('../../kernel-value');
+
+class WebGLKernelValue extends KernelValue {
+ constructor(value, settings) {
+ super(value, settings);
+ this.dimensionsId = null;
+ this.sizeId = null;
+ this.initialValueConstructor = value.constructor;
+ this.onRequestTexture = settings.onRequestTexture;
+ this.onRequestIndex = settings.onRequestIndex;
+ this.uploadValue = null;
+ this.textureSize = null;
+ this.bitRatio = null;
+ this.prevArg = null;
+ }
+
+ get id() {
+ return `${this.origin}_${utils.sanitizeName(this.name)}`;
+ }
+
+ setup() {}
+
+ getTransferArrayType(value) {
+ if (Array.isArray(value[0])) {
+ return this.getTransferArrayType(value[0]);
+ }
+ switch (value.constructor) {
+ case Array:
+ case Int32Array:
+ case Int16Array:
+ case Int8Array:
+ return Float32Array;
+ case Uint8ClampedArray:
+ case Uint8Array:
+ case Uint16Array:
+ case Uint32Array:
+ case Float32Array:
+ case Float64Array:
+ return value.constructor;
+ }
+ console.warn('Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros');
+ return value.constructor;
+ }
+
+ getStringValueHandler() {
+ throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`);
+ }
+
+ getVariablePrecisionString() {
+ return this.kernel.getVariablePrecisionString(this.textureSize || undefined, this.tactic || undefined);
+ }
+
+ destroy() {}
+}
+
+module.exports = {
+ WebGLKernelValue
+};
+},{"../../../utils":113,"../../kernel-value":34}],59:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValue } = require('./index');
+
+class WebGLKernelValueInteger extends WebGLKernelValue {
+ constructor(value, settings) {
+ super(value, settings);
+ this.uploadValue = value;
+ }
+ getStringValueHandler() {
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+ getSource(value) {
+ if (this.origin === 'constants') {
+ return `const int ${this.id} = ${ parseInt(value) };\n`;
+ }
+ return `uniform int ${this.id};\n`;
+ }
+
+ updateValue(value) {
+ if (this.origin === 'constants') return;
+ this.kernel.setUniform1i(this.id, this.uploadValue = value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueInteger
+};
+},{"../../../utils":113,"./index":58}],60:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+const sameError = `Source and destination textures are the same. Use immutable = true and manually cleanup kernel output texture memory with texture.delete()`;
+
+class WebGLKernelValueMemoryOptimizedNumberTexture extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ const [width, height] = value.size;
+ this.checkSize(width, height);
+ this.dimensions = value.dimensions;
+ this.textureSize = value.size;
+ this.uploadValue = value.texture;
+ this.forceUploadEachRun = true;
+ }
+
+ setup() {
+ this.setupTexture();
+ }
+
+ getStringValueHandler() {
+ return `const uploadValue_${this.name} = ${this.varName}.texture;\n`;
+ }
+
+ getSource() {
+ return utils.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(inputTexture) {
+ if (inputTexture.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(inputTexture.constructor);
+ return;
+ }
+ if (this.checkContext && inputTexture.context !== this.context) {
+ throw new Error(`Value ${this.name} (${this.type}) must be from same context`);
+ }
+
+ const { kernel, context: gl } = this;
+ if (kernel.pipeline) {
+ if (kernel.immutable) {
+ kernel.updateTextureArgumentRefs(this, inputTexture);
+ } else {
+ if (kernel.texture && kernel.texture.texture === inputTexture.texture) {
+ throw new Error(sameError);
+ } else if (kernel.mappedTextures) {
+ const { mappedTextures } = kernel;
+ for (let i = 0; i < mappedTextures.length; i++) {
+ if (mappedTextures[i].texture === inputTexture.texture) {
+ throw new Error(sameError);
+ }
+ }
+ }
+ }
+ }
+
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueMemoryOptimizedNumberTexture,
+ sameError
+};
+},{"../../../utils":113,"./array":39}],61:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+const { sameError } = require('./memory-optimized-number-texture');
+
+class WebGLKernelValueNumberTexture extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ const [width, height] = value.size;
+ this.checkSize(width, height);
+ const { size: textureSize, dimensions } = value;
+ this.bitRatio = this.getBitRatio(value);
+ this.dimensions = dimensions;
+ this.textureSize = textureSize;
+ this.uploadValue = value.texture;
+ this.forceUploadEachRun = true;
+ }
+
+ setup() {
+ this.setupTexture();
+ }
+
+ getStringValueHandler() {
+ return `const uploadValue_${this.name} = ${this.varName}.texture;\n`;
+ }
+
+ getSource() {
+ return utils.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(inputTexture) {
+ if (inputTexture.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(inputTexture.constructor);
+ return;
+ }
+ if (this.checkContext && inputTexture.context !== this.context) {
+ throw new Error(`Value ${this.name} (${this.type}) must be from same context`);
+ }
+
+ const { kernel, context: gl } = this;
+ if (kernel.pipeline) {
+ if (kernel.immutable) {
+ kernel.updateTextureArgumentRefs(this, inputTexture);
+ } else {
+ if (kernel.texture && kernel.texture.texture === inputTexture.texture) {
+ throw new Error(sameError);
+ } else if (kernel.mappedTextures) {
+ const { mappedTextures } = kernel;
+ for (let i = 0; i < mappedTextures.length; i++) {
+ if (mappedTextures[i].texture === inputTexture.texture) {
+ throw new Error(sameError);
+ }
+ }
+ }
+ }
+ }
+
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueNumberTexture
+};
+},{"../../../utils":113,"./array":39,"./memory-optimized-number-texture":60}],62:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueSingleArray extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.bitRatio = 4;
+ this.dimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.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 utils.linesToString([
+ `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,
+ `flattenTo(${this.varName}, uploadValue_${this.name})`,
+ ]);
+ }
+
+ getSource() {
+ return utils.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(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueSingleArray
+};
+},{"../../../utils":113,"./array":39}],63:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueSingleArray1DI extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.bitRatio = 4;
+ this.setShape(value);
+ }
+
+ setShape(value) {
+ const valueDimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio);
+ this.dimensions = new Int32Array([valueDimensions[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 utils.linesToString([
+ `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,
+ `flattenTo(${this.varName}, uploadValue_${this.name})`,
+ ]);
+ }
+
+ getSource() {
+ return utils.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(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flatten2dArrayTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueSingleArray1DI
+};
+},{"../../../utils":113,"./array":39}],64:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueSingleArray2DI extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.bitRatio = 4;
+ this.setShape(value);
+ }
+
+ setShape(value) {
+ const valueDimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio);
+ this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[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 utils.linesToString([
+ `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,
+ `flattenTo(${this.varName}, uploadValue_${this.name})`,
+ ]);
+ }
+
+ getSource() {
+ return utils.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(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flatten3dArrayTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueSingleArray2DI
+};
+},{"../../../utils":113,"./array":39}],65:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueSingleArray3DI extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.bitRatio = 4;
+ this.setShape(value);
+ }
+
+ setShape(value) {
+ const valueDimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio);
+ this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], valueDimensions[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 utils.linesToString([
+ `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,
+ `flattenTo(${this.varName}, uploadValue_${this.name})`,
+ ]);
+ }
+
+ getSource() {
+ return utils.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(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flatten4dArrayTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueSingleArray3DI
+};
+},{"../../../utils":113,"./array":39}],66:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueSingleInput extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.bitRatio = 4;
+ let [w, h, d] = value.size;
+ this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);
+ this.textureSize = utils.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 utils.linesToString([
+ `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,
+ `flattenTo(${this.varName}.value, uploadValue_${this.name})`,
+ ]);
+ }
+
+ getSource() {
+ return utils.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(input) {
+ if (input.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(input.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(input.value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueSingleInput
+};
+},{"../../../utils":113,"./array":39}],67:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueUnsignedArray extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.bitRatio = this.getBitRatio(value);
+ this.dimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.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(value);
+ this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength);
+ this.uploadValue = new Uint8Array(this.preUploadValue.buffer);
+ }
+
+ getStringValueHandler() {
+ return utils.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 utils.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(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(value, this.preUploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueUnsignedArray
+};
+},{"../../../utils":113,"./array":39}],68:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueUnsignedInput extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.bitRatio = this.getBitRatio(value);
+ const [w, h, d] = value.size;
+ this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);
+ this.textureSize = utils.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(value.value);
+ this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength);
+ this.uploadValue = new Uint8Array(this.preUploadValue.buffer);
+ }
+
+ getStringValueHandler() {
+ return utils.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 utils.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(input) {
+ if (input.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(input.value, this.preUploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueUnsignedInput
+};
+},{"../../../utils":113,"./array":39}],69:[function(require,module,exports){
+const { GLKernel } = require('../gl/kernel');
+const { FunctionBuilder } = require('../function-builder');
+const { WebGLFunctionNode } = require('./function-node');
+const { utils } = require('../../utils');
+const mrud = require('../../plugins/math-random-uniformly-distributed');
+const { fragmentShader } = require('./fragment-shader');
+const { vertexShader } = require('./vertex-shader');
+const { glKernelString } = require('../gl/kernel-string');
+const { lookupKernelValueType } = require('./kernel-value-maps');
+
+let isSupported = null;
+let testCanvas = null;
+let testContext = null;
+let testExtensions = null;
+let features = null;
+
+const plugins = [mrud];
+const canvases = [];
+const maxTexSizes = {};
+
+
+class WebGLKernel extends GLKernel {
+ static get isSupported() {
+ if (isSupported !== null) {
+ return isSupported;
+ }
+ this.setupFeatureChecks();
+ isSupported = this.isContextMatch(testContext);
+ return isSupported;
+ }
+
+ static setupFeatureChecks() {
+ if (typeof document !== 'undefined') {
+ testCanvas = document.createElement('canvas');
+ } else if (typeof OffscreenCanvas !== 'undefined') {
+ testCanvas = new OffscreenCanvas(0, 0);
+ }
+ if (!testCanvas) return;
+ testContext = testCanvas.getContext('webgl') || testCanvas.getContext('experimental-webgl');
+ if (!testContext || !testContext.getExtension) return;
+ testExtensions = {
+ OES_texture_float: testContext.getExtension('OES_texture_float'),
+ OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'),
+ OES_element_index_uint: testContext.getExtension('OES_element_index_uint'),
+ WEBGL_draw_buffers: testContext.getExtension('WEBGL_draw_buffers'),
+ };
+ features = this.getFeatures();
+ }
+
+ static isContextMatch(context) {
+ if (typeof WebGLRenderingContext !== 'undefined') {
+ return context instanceof WebGLRenderingContext;
+ }
+ return false;
+ }
+
+ static getIsTextureFloat() {
+ return Boolean(testExtensions.OES_texture_float);
+ }
+
+ static getIsDrawBuffers() {
+ return Boolean(testExtensions.WEBGL_draw_buffers);
+ }
+
+ static getChannelCount() {
+ return testExtensions.WEBGL_draw_buffers ?
+ testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) :
+ 1;
+ }
+
+ static getMaxTextureSize() {
+ return testContext.getParameter(testContext.MAX_TEXTURE_SIZE);
+ }
+
+ static lookupKernelValueType(type, dynamic, precision, value) {
+ return lookupKernelValueType(type, dynamic, precision, value);
+ }
+
+ static get testCanvas() {
+ return testCanvas;
+ }
+
+ static get testContext() {
+ return testContext;
+ }
+
+ static get features() {
+ return features;
+ }
+
+ static get fragmentShader() {
+ return fragmentShader;
+ }
+
+ static get vertexShader() {
+ return vertexShader;
+ }
+
+ constructor(source, settings) {
+ super(source, settings);
+ this.program = null;
+ this.pipeline = settings.pipeline;
+ this.endianness = utils.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(source.settings || settings);
+
+ 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 (typeof document !== 'undefined') {
+ const canvas = document.createElement('canvas');
+ canvas.width = 2;
+ canvas.height = 2;
+ return canvas;
+ } else if (typeof OffscreenCanvas !== 'undefined') {
+ return new OffscreenCanvas(0, 0);
+ }
+ }
+
+ initContext() {
+ const settings = {
+ alpha: false,
+ depth: false,
+ antialias: false
+ };
+ return this.canvas.getContext('webgl', settings) || this.canvas.getContext('experimental-webgl', settings);
+ }
+
+ initPlugins(settings) {
+ const pluginsToUse = [];
+ const { source } = this;
+ if (typeof source === 'string') {
+ for (let i = 0; i < plugins.length; i++) {
+ const plugin = plugins[i];
+ if (source.match(plugin.functionMatch)) {
+ pluginsToUse.push(plugin);
+ }
+ }
+ } else if (typeof source === 'object') {
+ if (settings.pluginNames) {
+ for (let i = 0; i < plugins.length; i++) {
+ const plugin = plugins[i];
+ const usePlugin = settings.pluginNames.some(pluginName => pluginName === plugin.name);
+ if (usePlugin) {
+ pluginsToUse.push(plugin);
+ }
+ }
+ }
+ }
+ return pluginsToUse;
+ }
+
+ 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(args) {
+ if (!this.validate) {
+ this.texSize = utils.getKernelTextureSize({
+ optimizeFloatMemory: this.optimizeFloatMemory,
+ precision: this.precision,
+ }, this.output);
+ return;
+ }
+
+ const { features } = this.constructor;
+
+ if (this.optimizeFloatMemory === true && !features.isTextureFloat) {
+ throw new Error('Float textures are not supported');
+ } else if (this.precision === 'single' && !features.isFloatRead) {
+ throw new Error('Single precision not supported');
+ } else if (!this.graphical && this.precision === null && features.isTextureFloat) {
+ this.precision = features.isFloatRead ? 'single' : 'unsigned';
+ }
+
+ if (this.subKernels && this.subKernels.length > 0 && !this.extensions.WEBGL_draw_buffers) {
+ throw new Error('could not instantiate draw buffers extension');
+ }
+
+ if (this.fixIntegerDivisionAccuracy === null) {
+ this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate;
+ } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) {
+ this.fixIntegerDivisionAccuracy = false;
+ }
+
+ this.checkOutput();
+
+ 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);
+ switch (argType) {
+ case 'Array':
+ this.output = utils.getDimensions(argType);
+ break;
+ case 'NumberTexture':
+ case 'MemoryOptimizedNumberTexture':
+ case 'ArrayTexture(1)':
+ case 'ArrayTexture(2)':
+ case 'ArrayTexture(3)':
+ case 'ArrayTexture(4)':
+ this.output = args[0].output;
+ break;
+ default:
+ throw new Error('Auto output not supported for input type: ' + argType);
+ }
+ }
+
+ if (this.graphical) {
+ if (this.output.length !== 2) {
+ throw new Error('Output must have 2 dimensions on graphical mode');
+ }
+
+ if (this.precision === 'precision') {
+ this.precision = 'unsigned';
+ console.warn('Cannot use graphical mode and single precision at the same time');
+ }
+
+ this.texSize = utils.clone(this.output);
+ return;
+ } else if (this.precision === null && features.isTextureFloat) {
+ this.precision = 'single';
+ }
+
+ this.texSize = utils.getKernelTextureSize({
+ optimizeFloatMemory: this.optimizeFloatMemory,
+ precision: this.precision,
+ }, this.output);
+
+ this.checkTextureSize();
+ }
+
+ updateMaxTexSize() {
+ const { texSize, canvas } = this;
+ if (this.maxTexSize === null) {
+ let canvasIndex = canvases.indexOf(canvas);
+ if (canvasIndex === -1) {
+ canvasIndex = canvases.length;
+ canvases.push(canvas);
+ maxTexSizes[canvasIndex] = [texSize[0], texSize[1]];
+ }
+ this.maxTexSize = maxTexSizes[canvasIndex];
+ }
+ if (this.maxTexSize[0] < texSize[0]) {
+ this.maxTexSize[0] = texSize[0];
+ }
+ if (this.maxTexSize[1] < texSize[1]) {
+ this.maxTexSize[1] = texSize[1];
+ }
+ }
+
+ setupArguments(args) {
+ this.kernelArguments = [];
+ this.argumentTextureCount = 0;
+ const needsArgumentTypes = this.argumentTypes === null;
+ if (needsArgumentTypes) {
+ this.argumentTypes = [];
+ }
+ this.argumentSizes = [];
+ this.argumentBitRatios = [];
+
+ if (args.length < this.argumentNames.length) {
+ throw new Error('not enough arguments for kernel');
+ } else if (args.length > this.argumentNames.length) {
+ throw new Error('too many arguments for kernel');
+ }
+
+ const { context: gl } = this;
+ let textureIndexes = 0;
+
+ const onRequestTexture = () => {
+ return this.createTexture();
+ };
+ const onRequestIndex = () => {
+ return this.constantTextureCount + textureIndexes++;
+ };
+ const onUpdateValueMismatch = (constructor) => {
+ this.switchKernels({
+ type: 'argumentMismatch',
+ needed: constructor
+ });
+ };
+ const onRequestContextHandle = () => {
+ return gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount++;
+ };
+
+ for (let index = 0; index < args.length; index++) {
+ const value = args[index];
+ const name = this.argumentNames[index];
+ let type;
+ if (needsArgumentTypes) {
+ type = utils.getVariableType(value, this.strictIntegers);
+ this.argumentTypes.push(type);
+ } else {
+ type = this.argumentTypes[index];
+ }
+ const KernelValue = this.constructor.lookupKernelValueType(type, this.dynamicArguments ? 'dynamic' : 'static', this.precision, args[index]);
+ if (KernelValue === null) {
+ return this.requestFallback(args);
+ }
+ const kernelArgument = new KernelValue(value, {
+ name,
+ type,
+ tactic: this.tactic,
+ origin: 'user',
+ context: gl,
+ checkContext: this.checkContext,
+ kernel: this,
+ strictIntegers: this.strictIntegers,
+ onRequestTexture,
+ onRequestIndex,
+ onUpdateValueMismatch,
+ onRequestContextHandle,
+ });
+ this.kernelArguments.push(kernelArgument);
+ kernelArgument.setup();
+ this.argumentSizes.push(kernelArgument.textureSize);
+ this.argumentBitRatios[index] = kernelArgument.bitRatio;
+ }
+ }
+
+ createTexture() {
+ const texture = this.context.createTexture();
+ this.textureCache.push(texture);
+ return texture;
+ }
+
+ setupConstants(args) {
+ const { context: gl } = this;
+ this.kernelConstants = [];
+ this.forceUploadKernelConstants = [];
+ let needsConstantTypes = this.constantTypes === null;
+ if (needsConstantTypes) {
+ this.constantTypes = {};
+ }
+ this.constantBitRatios = {};
+ let textureIndexes = 0;
+ for (const name in this.constants) {
+ const value = this.constants[name];
+ let type;
+ if (needsConstantTypes) {
+ type = utils.getVariableType(value, this.strictIntegers);
+ this.constantTypes[name] = type;
+ } else {
+ type = this.constantTypes[name];
+ }
+ const KernelValue = this.constructor.lookupKernelValueType(type, 'static', this.precision, value);
+ if (KernelValue === null) {
+ return this.requestFallback(args);
+ }
+ const kernelValue = new KernelValue(value, {
+ name,
+ type,
+ tactic: this.tactic,
+ origin: 'constants',
+ context: this.context,
+ checkContext: this.checkContext,
+ kernel: this,
+ strictIntegers: this.strictIntegers,
+ onRequestTexture: () => {
+ return this.createTexture();
+ },
+ onRequestIndex: () => {
+ return textureIndexes++;
+ },
+ onRequestContextHandle: () => {
+ return gl.TEXTURE0 + this.constantTextureCount++;
+ }
+ });
+ this.constantBitRatios[name] = kernelValue.bitRatio;
+ this.kernelConstants.push(kernelValue);
+ kernelValue.setup();
+ if (kernelValue.forceUploadEachRun) {
+ this.forceUploadKernelConstants.push(kernelValue);
+ }
+ }
+ }
+
+ build() {
+ if (this.built) return;
+ this.initExtensions();
+ this.validateSettings(arguments);
+ this.setupConstants(arguments);
+ if (this.fallbackRequested) return;
+ this.setupArguments(arguments);
+ if (this.fallbackRequested) return;
+ this.updateMaxTexSize();
+ this.translateSource();
+ const failureResult = this.pickRenderStrategy(arguments);
+ if (failureResult) {
+ return failureResult;
+ }
+ const { texSize, context: gl, canvas } = this;
+ gl.enable(gl.SCISSOR_TEST);
+ if (this.pipeline && this.precision === 'single') {
+ gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);
+ canvas.width = this.maxTexSize[0];
+ canvas.height = this.maxTexSize[1];
+ } else {
+ gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);
+ canvas.width = this.maxTexSize[0];
+ canvas.height = this.maxTexSize[1];
+ }
+ const threadDim = this.threadDim = Array.from(this.output);
+ while (threadDim.length < 3) {
+ threadDim.push(1);
+ }
+
+ const compiledVertexShader = this.getVertexShader(arguments);
+ const vertShader = gl.createShader(gl.VERTEX_SHADER);
+ gl.shaderSource(vertShader, compiledVertexShader);
+ gl.compileShader(vertShader);
+ this.vertShader = vertShader;
+
+ const compiledFragmentShader = this.getFragmentShader(arguments);
+ const fragShader = gl.createShader(gl.FRAGMENT_SHADER);
+ gl.shaderSource(fragShader, compiledFragmentShader);
+ gl.compileShader(fragShader);
+ this.fragShader = fragShader;
+
+ if (this.debug) {
+ console.log('GLSL Shader Output:');
+ console.log(compiledFragmentShader);
+ }
+
+ if (!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) {
+ throw new Error('Error compiling vertex shader: ' + gl.getShaderInfoLog(vertShader));
+ }
+ if (!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) {
+ throw new Error('Error compiling fragment shader: ' + gl.getShaderInfoLog(fragShader));
+ }
+
+ const program = this.program = gl.createProgram();
+ gl.attachShader(program, vertShader);
+ gl.attachShader(program, fragShader);
+ gl.linkProgram(program);
+ this.framebuffer = gl.createFramebuffer();
+ this.framebuffer.width = texSize[0];
+ this.framebuffer.height = texSize[1];
+ this.rawValueFramebuffers = {};
+
+ const vertices = new Float32Array([-1, -1,
+ 1, -1, -1, 1,
+ 1, 1
+ ]);
+ const texCoords = new Float32Array([
+ 0, 0,
+ 1, 0,
+ 0, 1,
+ 1, 1
+ ]);
+
+ const texCoordOffset = vertices.byteLength;
+
+ let buffer = this.buffer;
+ if (!buffer) {
+ buffer = this.buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, vertices.byteLength + texCoords.byteLength, gl.STATIC_DRAW);
+ } else {
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ }
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices);
+ gl.bufferSubData(gl.ARRAY_BUFFER, texCoordOffset, texCoords);
+
+ const aPosLoc = gl.getAttribLocation(this.program, 'aPos');
+ gl.enableVertexAttribArray(aPosLoc);
+ gl.vertexAttribPointer(aPosLoc, 2, gl.FLOAT, false, 0, 0);
+ const aTexCoordLoc = gl.getAttribLocation(this.program, 'aTexCoord');
+ gl.enableVertexAttribArray(aTexCoordLoc);
+ gl.vertexAttribPointer(aTexCoordLoc, 2, gl.FLOAT, false, 0, texCoordOffset);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
+
+ let i = 0;
+ gl.useProgram(this.program);
+ for (let p in this.constants) {
+ this.kernelConstants[i++].updateValue(this.constants[p]);
+ }
+
+ this._setupOutputTexture();
+ if (
+ this.subKernels !== null &&
+ this.subKernels.length > 0
+ ) {
+ this._mappedTextureSwitched = {};
+ this._setupSubOutputTextures();
+ }
+ this.buildSignature(arguments);
+ this.built = true;
+ }
+
+ translateSource() {
+ const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, {
+ fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy
+ });
+ this.translatedSource = functionBuilder.getPrototypeString('kernel');
+ this.setupReturnTypes(functionBuilder);
+ }
+
+ setupReturnTypes(functionBuilder) {
+ if (!this.graphical && !this.returnType) {
+ this.returnType = functionBuilder.getKernelResultType();
+ }
+
+ if (this.subKernels && this.subKernels.length > 0) {
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const subKernel = this.subKernels[i];
+ if (!subKernel.returnType) {
+ subKernel.returnType = functionBuilder.getSubKernelResultType(i);
+ }
+ }
+ }
+ }
+
+ run() {
+ const { kernelArguments, texSize, forceUploadKernelConstants, context: gl } = this;
+
+ gl.useProgram(this.program);
+ gl.scissor(0, 0, texSize[0], texSize[1]);
+ if (this.dynamicOutput) {
+ this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim));
+ this.setUniform2iv('uTexSize', texSize);
+ }
+
+ this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]);
+
+ for (let i = 0; i < forceUploadKernelConstants.length; i++) {
+ const constant = forceUploadKernelConstants[i];
+ constant.updateValue(this.constants[constant.name]);
+ if (this.switchingKernels) return;
+ }
+ for (let i = 0; i < kernelArguments.length; i++) {
+ kernelArguments[i].updateValue(arguments[i]);
+ if (this.switchingKernels) return;
+ }
+
+ if (this.plugins) {
+ for (let i = 0; i < this.plugins.length; i++) {
+ const plugin = this.plugins[i];
+ if (plugin.onBeforeRun) {
+ plugin.onBeforeRun(this);
+ }
+ }
+ }
+
+ if (this.graphical) {
+ if (this.pipeline) {
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
+ if (this.immutable) {
+ this._replaceOutputTexture();
+ }
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+ return this.immutable ? this.texture.clone() : this.texture;
+ }
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+ return;
+ }
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
+ if (this.immutable) {
+ this._replaceOutputTexture();
+ }
+
+ if (this.subKernels !== null) {
+ if (this.immutable) {
+ this._replaceSubOutputTextures();
+ }
+ this.drawBuffers();
+ }
+
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+ }
+
+ drawBuffers() {
+ this.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(this.drawBuffersMap);
+ }
+
+ getInternalFormat() {
+ return this.context.RGBA;
+ }
+ getTextureFormat() {
+ const { context: gl } = this;
+ switch (this.getInternalFormat()) {
+ case gl.RGBA:
+ return gl.RGBA;
+ default:
+ throw new Error('Unknown internal format');
+ }
+ }
+
+ _replaceOutputTexture() {
+ if (this.texture.beforeMutate() || this._textureSwitched) {
+ const gl = this.context;
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture.texture, 0);
+ this._textureSwitched = false;
+ }
+ }
+
+ _setupOutputTexture() {
+ const gl = this.context;
+ const texSize = this.texSize;
+ if (this.texture) {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture.texture, 0);
+ return;
+ }
+ const texture = this.createTexture();
+ gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ const format = this.getInternalFormat();
+ if (this.precision === 'single') {
+ gl.texImage2D(gl.TEXTURE_2D, 0, format, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);
+ } else {
+ gl.texImage2D(gl.TEXTURE_2D, 0, format, texSize[0], texSize[1], 0, format, gl.UNSIGNED_BYTE, null);
+ }
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ this.texture = new this.TextureConstructor({
+ texture,
+ size: texSize,
+ dimensions: this.threadDim,
+ output: this.output,
+ context: this.context,
+ internalFormat: this.getInternalFormat(),
+ textureFormat: this.getTextureFormat(),
+ kernel: this,
+ });
+ }
+
+ _replaceSubOutputTextures() {
+ const gl = this.context;
+ for (let i = 0; i < this.mappedTextures.length; i++) {
+ const mappedTexture = this.mappedTextures[i];
+ if (mappedTexture.beforeMutate() || this._mappedTextureSwitched[i]) {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, mappedTexture.texture, 0);
+ this._mappedTextureSwitched[i] = false;
+ }
+ }
+ }
+
+ _setupSubOutputTextures() {
+ const gl = this.context;
+ if (this.mappedTextures) {
+ for (let i = 0; i < this.subKernels.length; i++) {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, this.mappedTextures[i].texture, 0);
+ }
+ return;
+ }
+ const texSize = this.texSize;
+ this.drawBuffersMap = [gl.COLOR_ATTACHMENT0];
+ this.mappedTextures = [];
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const texture = this.createTexture();
+ this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1);
+ gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ if (this.precision === 'single') {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);
+ } else {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ }
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0);
+
+ this.mappedTextures.push(new this.TextureConstructor({
+ texture,
+ size: texSize,
+ dimensions: this.threadDim,
+ output: this.output,
+ context: this.context,
+ internalFormat: this.getInternalFormat(),
+ textureFormat: this.getTextureFormat(),
+ kernel: this,
+ }));
+ }
+ }
+
+ setUniform1f(name, value) {
+ if (this.uniform1fCache.hasOwnProperty(name)) {
+ const cache = this.uniform1fCache[name];
+ if (value === cache) {
+ return;
+ }
+ }
+ this.uniform1fCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform1f(loc, value);
+ }
+
+ setUniform1i(name, value) {
+ if (this.uniform1iCache.hasOwnProperty(name)) {
+ const cache = this.uniform1iCache[name];
+ if (value === cache) {
+ return;
+ }
+ }
+ this.uniform1iCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform1i(loc, value);
+ }
+
+ setUniform2f(name, value1, value2) {
+ if (this.uniform2fCache.hasOwnProperty(name)) {
+ const cache = this.uniform2fCache[name];
+ if (
+ value1 === cache[0] &&
+ value2 === cache[1]
+ ) {
+ return;
+ }
+ }
+ this.uniform2fCache[name] = [value1, value2];
+ const loc = this.getUniformLocation(name);
+ this.context.uniform2f(loc, value1, value2);
+ }
+
+ setUniform2fv(name, value) {
+ if (this.uniform2fvCache.hasOwnProperty(name)) {
+ const cache = this.uniform2fvCache[name];
+ if (
+ value[0] === cache[0] &&
+ value[1] === cache[1]
+ ) {
+ return;
+ }
+ }
+ this.uniform2fvCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform2fv(loc, value);
+ }
+
+ setUniform2iv(name, value) {
+ if (this.uniform2ivCache.hasOwnProperty(name)) {
+ const cache = this.uniform2ivCache[name];
+ if (
+ value[0] === cache[0] &&
+ value[1] === cache[1]
+ ) {
+ return;
+ }
+ }
+ this.uniform2ivCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform2iv(loc, value);
+ }
+
+ setUniform3fv(name, value) {
+ if (this.uniform3fvCache.hasOwnProperty(name)) {
+ const cache = this.uniform3fvCache[name];
+ if (
+ value[0] === cache[0] &&
+ value[1] === cache[1] &&
+ value[2] === cache[2]
+ ) {
+ return;
+ }
+ }
+ this.uniform3fvCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform3fv(loc, value);
+ }
+
+ setUniform3iv(name, value) {
+ if (this.uniform3ivCache.hasOwnProperty(name)) {
+ const cache = this.uniform3ivCache[name];
+ if (
+ value[0] === cache[0] &&
+ value[1] === cache[1] &&
+ value[2] === cache[2]
+ ) {
+ return;
+ }
+ }
+ this.uniform3ivCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform3iv(loc, value);
+ }
+
+ setUniform4fv(name, value) {
+ if (this.uniform4fvCache.hasOwnProperty(name)) {
+ const cache = this.uniform4fvCache[name];
+ if (
+ value[0] === cache[0] &&
+ value[1] === cache[1] &&
+ value[2] === cache[2] &&
+ value[3] === cache[3]
+ ) {
+ return;
+ }
+ }
+ this.uniform4fvCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform4fv(loc, value);
+ }
+
+ setUniform4iv(name, value) {
+ if (this.uniform4ivCache.hasOwnProperty(name)) {
+ const cache = this.uniform4ivCache[name];
+ if (
+ value[0] === cache[0] &&
+ value[1] === cache[1] &&
+ value[2] === cache[2] &&
+ value[3] === cache[3]
+ ) {
+ return;
+ }
+ }
+ this.uniform4ivCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform4iv(loc, value);
+ }
+
+ getUniformLocation(name) {
+ if (this.programUniformLocationCache.hasOwnProperty(name)) {
+ return this.programUniformLocationCache[name];
+ }
+ return this.programUniformLocationCache[name] = this.context.getUniformLocation(this.program, name);
+ }
+
+ _getFragShaderArtifactMap(args) {
+ return {
+ HEADER: this._getHeaderString(),
+ LOOP_MAX: this._getLoopMaxString(),
+ PLUGINS: this._getPluginsString(),
+ CONSTANTS: this._getConstantsString(),
+ DECODE32_ENDIANNESS: this._getDecode32EndiannessString(),
+ ENCODE32_ENDIANNESS: this._getEncode32EndiannessString(),
+ DIVIDE_WITH_INTEGER_CHECK: this._getDivideWithIntegerCheckString(),
+ INJECTED_NATIVE: this._getInjectedNative(),
+ MAIN_CONSTANTS: this._getMainConstantsString(),
+ MAIN_ARGUMENTS: this._getMainArgumentsString(args),
+ KERNEL: this.getKernelString(),
+ MAIN_RESULT: this.getMainResultString(),
+ FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(),
+ INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(),
+ SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(),
+ SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(),
+ };
+ }
+
+ _getVertShaderArtifactMap(args) {
+ return {
+ FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(),
+ INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(),
+ SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(),
+ SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(),
+ };
+ }
+
+ _getHeaderString() {
+ return (
+ this.subKernels !== null ?
+ '#extension GL_EXT_draw_buffers : require\n' :
+ ''
+ );
+ }
+
+ _getLoopMaxString() {
+ return (
+ this.loopMaxIterations ?
+ ` ${parseInt(this.loopMaxIterations)};\n` :
+ ' 1000;\n'
+ );
+ }
+
+ _getPluginsString() {
+ if (!this.plugins) return '\n';
+ return this.plugins.map(plugin => plugin.source && this.source.match(plugin.functionMatch) ? plugin.source : '').join('\n');
+ }
+
+ _getConstantsString() {
+ const result = [];
+ const { threadDim, texSize } = this;
+ if (this.dynamicOutput) {
+ result.push(
+ 'uniform ivec3 uOutputDim',
+ 'uniform ivec2 uTexSize'
+ );
+ } else {
+ result.push(
+ `ivec3 uOutputDim = ivec3(${threadDim[0]}, ${threadDim[1]}, ${threadDim[2]})`,
+ `ivec2 uTexSize = ivec2(${texSize[0]}, ${texSize[1]})`
+ );
+ }
+ return utils.linesToString(result);
+ }
+
+ _getTextureCoordinate() {
+ const subKernels = this.subKernels;
+ if (subKernels === null || subKernels.length < 1) {
+ return 'varying vec2 vTexCoord;\n';
+ } else {
+ return 'out vec2 vTexCoord;\n';
+ }
+ }
+
+ _getDecode32EndiannessString() {
+ return (
+ this.endianness === 'LE' ?
+ '' :
+ ' texel.rgba = texel.abgr;\n'
+ );
+ }
+
+ _getEncode32EndiannessString() {
+ return (
+ this.endianness === 'LE' ?
+ '' :
+ ' texel.rgba = texel.abgr;\n'
+ );
+ }
+
+ _getDivideWithIntegerCheckString() {
+ return this.fixIntegerDivisionAccuracy ?
+ `float divWithIntCheck(float x, float y) {
+ if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) {
+ return float(int(x) / int(y));
+ }
+ return x / y;
+}
+
+float integerCorrectionModulo(float number, float divisor) {
+ if (number < 0.0) {
+ number = abs(number);
+ if (divisor < 0.0) {
+ divisor = abs(divisor);
+ }
+ return -(number - (divisor * floor(divWithIntCheck(number, divisor))));
+ }
+ if (divisor < 0.0) {
+ divisor = abs(divisor);
+ }
+ return number - (divisor * floor(divWithIntCheck(number, divisor)));
+}` :
+ '';
+ }
+
+ _getMainArgumentsString(args) {
+ const results = [];
+ const { argumentNames } = this;
+ for (let i = 0; i < argumentNames.length; i++) {
+ results.push(this.kernelArguments[i].getSource(args[i]));
+ }
+ return results.join('');
+ }
+
+ _getInjectedNative() {
+ return this.injectedNative || '';
+ }
+
+ _getMainConstantsString() {
+ const result = [];
+ const { constants } = this;
+ if (constants) {
+ let i = 0;
+ for (const name in constants) {
+ if (!this.constants.hasOwnProperty(name)) continue;
+ result.push(this.kernelConstants[i++].getSource(this.constants[name]));
+ }
+ }
+ return result.join('');
+ }
+
+ getRawValueFramebuffer(width, height) {
+ if (!this.rawValueFramebuffers[width]) {
+ this.rawValueFramebuffers[width] = {};
+ }
+ if (!this.rawValueFramebuffers[width][height]) {
+ const framebuffer = this.context.createFramebuffer();
+ framebuffer.width = width;
+ framebuffer.height = height;
+ this.rawValueFramebuffers[width][height] = framebuffer;
+ }
+ return this.rawValueFramebuffers[width][height];
+ }
+
+ getKernelResultDeclaration() {
+ switch (this.returnType) {
+ case 'Array(2)':
+ return 'vec2 kernelResult';
+ case 'Array(3)':
+ return 'vec3 kernelResult';
+ case 'Array(4)':
+ return 'vec4 kernelResult';
+ case 'LiteralInteger':
+ case 'Float':
+ case 'Number':
+ case 'Integer':
+ return 'float kernelResult';
+ default:
+ if (this.graphical) {
+ return 'float kernelResult';
+ } else {
+ throw new Error(`unrecognized output type "${ this.returnType }"`);
+ }
+ }
+ }
+ getKernelString() {
+ const result = [this.getKernelResultDeclaration()];
+ const { subKernels } = this;
+ if (subKernels !== null) {
+ switch (this.returnType) {
+ case 'Number':
+ case 'Float':
+ case 'Integer':
+ for (let i = 0; i < subKernels.length; i++) {
+ const subKernel = subKernels[i];
+ result.push(
+ subKernel.returnType === 'Integer' ?
+ `int subKernelResult_${ subKernel.name } = 0` :
+ `float subKernelResult_${ subKernel.name } = 0.0`
+ );
+ }
+ break;
+ case 'Array(2)':
+ for (let i = 0; i < subKernels.length; i++) {
+ result.push(
+ `vec2 subKernelResult_${ subKernels[i].name }`
+ );
+ }
+ break;
+ case 'Array(3)':
+ for (let i = 0; i < subKernels.length; i++) {
+ result.push(
+ `vec3 subKernelResult_${ subKernels[i].name }`
+ );
+ }
+ break;
+ case 'Array(4)':
+ for (let i = 0; i < subKernels.length; i++) {
+ result.push(
+ `vec4 subKernelResult_${ subKernels[i].name }`
+ );
+ }
+ break;
+ }
+ }
+
+ return utils.linesToString(result) + this.translatedSource;
+ }
+
+ getMainResultGraphical() {
+ return utils.linesToString([
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' gl_FragColor = actualColor',
+ ]);
+ }
+
+ getMainResultPackedPixels() {
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ return this.getMainResultKernelPackedPixels() +
+ this.getMainResultSubKernelPackedPixels();
+ default:
+ throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`);
+ }
+ }
+
+ getMainResultKernelPackedPixels() {
+ return utils.linesToString([
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ` gl_FragData[0] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)`
+ ]);
+ }
+
+ getMainResultSubKernelPackedPixels() {
+ const result = [];
+ if (!this.subKernels) return '';
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const subKernel = this.subKernels[i];
+ if (subKernel.returnType === 'Integer') {
+ result.push(
+ ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))`
+ );
+ } else {
+ result.push(
+ ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})`
+ );
+ }
+ }
+ return utils.linesToString(result);
+ }
+
+ getMainResultMemoryOptimizedFloats() {
+ const result = [
+ ' index *= 4',
+ ];
+
+ switch (this.returnType) {
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ const channels = ['r', 'g', 'b', 'a'];
+ for (let i = 0; i < channels.length; i++) {
+ const channel = channels[i];
+ this.getMainResultKernelMemoryOptimizedFloats(result, channel);
+ this.getMainResultSubKernelMemoryOptimizedFloats(result, channel);
+ if (i + 1 < channels.length) {
+ result.push(' index += 1');
+ }
+ }
+ break;
+ default:
+ throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`);
+ }
+
+ return utils.linesToString(result);
+ }
+
+ getMainResultKernelMemoryOptimizedFloats(result, channel) {
+ result.push(
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ` gl_FragData[0].${channel} = kernelResult`
+ );
+ }
+
+ getMainResultSubKernelMemoryOptimizedFloats(result, channel) {
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const subKernel = this.subKernels[i];
+ if (subKernel.returnType === 'Integer') {
+ result.push(
+ ` gl_FragData[${i + 1}].${channel} = float(subKernelResult_${this.subKernels[i].name})`
+ );
+ } else {
+ result.push(
+ ` gl_FragData[${i + 1}].${channel} = subKernelResult_${this.subKernels[i].name}`
+ );
+ }
+ }
+ }
+
+ getMainResultKernelNumberTexture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' gl_FragData[0][0] = kernelResult',
+ ];
+ }
+
+ getMainResultSubKernelNumberTexture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ const subKernel = this.subKernels[i];
+ if (subKernel.returnType === 'Integer') {
+ result.push(
+ ` gl_FragData[${i + 1}][0] = float(subKernelResult_${subKernel.name})`
+ );
+ } else {
+ result.push(
+ ` gl_FragData[${i + 1}][0] = subKernelResult_${subKernel.name}`
+ );
+ }
+ }
+ return result;
+ }
+
+ getMainResultKernelArray2Texture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' gl_FragData[0][0] = kernelResult[0]',
+ ' gl_FragData[0][1] = kernelResult[1]',
+ ];
+ }
+
+ getMainResultSubKernelArray2Texture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ result.push(
+ ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,
+ ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`
+ );
+ }
+ return result;
+ }
+
+ getMainResultKernelArray3Texture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' gl_FragData[0][0] = kernelResult[0]',
+ ' gl_FragData[0][1] = kernelResult[1]',
+ ' gl_FragData[0][2] = kernelResult[2]',
+ ];
+ }
+
+ getMainResultSubKernelArray3Texture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ result.push(
+ ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,
+ ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,
+ ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`
+ );
+ }
+ return result;
+ }
+
+ getMainResultKernelArray4Texture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' gl_FragData[0] = kernelResult',
+ ];
+ }
+
+ getMainResultSubKernelArray4Texture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ switch (this.returnType) {
+ case 'Number':
+ case 'Float':
+ case 'Integer':
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ const subKernel = this.subKernels[i];
+ if (subKernel.returnType === 'Integer') {
+ result.push(
+ ` gl_FragData[${i + 1}] = float(subKernelResult_${this.subKernels[i].name})`
+ );
+ } else {
+ result.push(
+ ` gl_FragData[${i + 1}] = subKernelResult_${this.subKernels[i].name}`
+ );
+ }
+ }
+ break;
+ case 'Array(2)':
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ result.push(
+ ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,
+ ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`
+ );
+ }
+ break;
+ case 'Array(3)':
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ result.push(
+ ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,
+ ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,
+ ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`
+ );
+ }
+ break;
+ case 'Array(4)':
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ result.push(
+ ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,
+ ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,
+ ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`,
+ ` gl_FragData[${i + 1}][3] = subKernelResult_${this.subKernels[i].name}[3]`
+ );
+ }
+ break;
+ }
+
+ return result;
+ }
+
+ replaceArtifacts(src, map) {
+ return src.replace(/[ ]*__([A-Z]+[0-9]*([_]?[A-Z]*[0-9]?)*)__;\n/g, (match, artifact) => {
+ if (map.hasOwnProperty(artifact)) {
+ return map[artifact];
+ }
+ throw `unhandled artifact ${artifact}`;
+ });
+ }
+
+ getFragmentShader(args) {
+ if (this.compiledFragmentShader !== null) {
+ return this.compiledFragmentShader;
+ }
+ return this.compiledFragmentShader = this.replaceArtifacts(this.constructor.fragmentShader, this._getFragShaderArtifactMap(args));
+ }
+
+ getVertexShader(args) {
+ if (this.compiledVertexShader !== null) {
+ return this.compiledVertexShader;
+ }
+ return this.compiledVertexShader = this.replaceArtifacts(this.constructor.vertexShader, this._getVertShaderArtifactMap(args));
+ }
+
+ toString() {
+ const setupContextString = utils.linesToString([
+ `const gl = context`,
+ ]);
+ return glKernelString(this.constructor, arguments, this, setupContextString);
+ }
+
+ destroy(removeCanvasReferences) {
+ if (!this.context) return;
+ if (this.buffer) {
+ this.context.deleteBuffer(this.buffer);
+ }
+ if (this.framebuffer) {
+ this.context.deleteFramebuffer(this.framebuffer);
+ }
+ for (const width in this.rawValueFramebuffers) {
+ for (const height in this.rawValueFramebuffers[width]) {
+ this.context.deleteFramebuffer(this.rawValueFramebuffers[width][height]);
+ delete this.rawValueFramebuffers[width][height];
+ }
+ delete this.rawValueFramebuffers[width];
+ }
+ if (this.vertShader) {
+ this.context.deleteShader(this.vertShader);
+ }
+ if (this.fragShader) {
+ this.context.deleteShader(this.fragShader);
+ }
+ if (this.program) {
+ this.context.deleteProgram(this.program);
+ }
+ if (this.texture) {
+ this.texture.delete();
+ const textureCacheIndex = this.textureCache.indexOf(this.texture.texture);
+ if (textureCacheIndex > -1) {
+ this.textureCache.splice(textureCacheIndex, 1);
+ }
+ this.texture = null;
+ }
+ if (this.mappedTextures && this.mappedTextures.length) {
+ for (let i = 0; i < this.mappedTextures.length; i++) {
+ const mappedTexture = this.mappedTextures[i];
+ mappedTexture.delete();
+ const textureCacheIndex = this.textureCache.indexOf(mappedTexture.texture);
+ if (textureCacheIndex > -1) {
+ this.textureCache.splice(textureCacheIndex, 1);
+ }
+ }
+ this.mappedTextures = null;
+ }
+ if (this.kernelArguments) {
+ for (let i = 0; i < this.kernelArguments.length; i++) {
+ this.kernelArguments[i].destroy();
+ }
+ }
+ if (this.kernelConstants) {
+ for (let i = 0; i < this.kernelConstants.length; i++) {
+ this.kernelConstants[i].destroy();
+ }
+ }
+ while (this.textureCache.length > 0) {
+ const texture = this.textureCache.pop();
+ this.context.deleteTexture(texture);
+ }
+ if (removeCanvasReferences) {
+ const idx = canvases.indexOf(this.canvas);
+ if (idx >= 0) {
+ canvases[idx] = null;
+ maxTexSizes[idx] = null;
+ }
+ }
+ this.destroyExtensions();
+ delete this.context;
+ delete this.canvas;
+ if (!this.gpu) return;
+ const i = this.gpu.kernels.indexOf(this);
+ if (i === -1) return;
+ this.gpu.kernels.splice(i, 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(context) {
+ const extension = context.getExtension('WEBGL_lose_context');
+ if (extension) {
+ extension.loseContext();
+ }
+ }
+
+ toJSON() {
+ const json = super.toJSON();
+ json.functionNodes = FunctionBuilder.fromKernel(this, WebGLFunctionNode).toJSON();
+ json.settings.threadDim = this.threadDim;
+ return json;
+ }
+}
+
+module.exports = {
+ WebGLKernel
+};
+},{"../../plugins/math-random-uniformly-distributed":111,"../../utils":113,"../function-builder":8,"../gl/kernel":12,"../gl/kernel-string":11,"./fragment-shader":36,"./function-node":37,"./kernel-value-maps":38,"./vertex-shader":70}],70:[function(require,module,exports){
+const vertexShader = `__FLOAT_TACTIC_DECLARATION__;
+__INT_TACTIC_DECLARATION__;
+__SAMPLER_2D_TACTIC_DECLARATION__;
+
+attribute vec2 aPos;
+attribute vec2 aTexCoord;
+
+varying vec2 vTexCoord;
+uniform vec2 ratio;
+
+void main(void) {
+ gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);
+ vTexCoord = aTexCoord;
+}`;
+
+module.exports = {
+ vertexShader
+};
+},{}],71:[function(require,module,exports){
+const fragmentShader = `#version 300 es
+__HEADER__;
+__FLOAT_TACTIC_DECLARATION__;
+__INT_TACTIC_DECLARATION__;
+__SAMPLER_2D_TACTIC_DECLARATION__;
+__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__;
+
+const int LOOP_MAX = __LOOP_MAX__;
+
+__PLUGINS__;
+__CONSTANTS__;
+
+in vec2 vTexCoord;
+
+float atan2(float v1, float v2) {
+ if (v1 == 0.0 || v2 == 0.0) return 0.0;
+ return atan(v1 / v2);
+}
+
+float cbrt(float x) {
+ if (x >= 0.0) {
+ return pow(x, 1.0 / 3.0);
+ } else {
+ return -pow(x, 1.0 / 3.0);
+ }
+}
+
+float expm1(float x) {
+ return pow(${Math.E}, x) - 1.0;
+}
+
+float fround(highp float x) {
+ return x;
+}
+
+float imul(float v1, float v2) {
+ return float(int(v1) * int(v2));
+}
+
+float log10(float x) {
+ return log2(x) * (1.0 / log2(10.0));
+}
+
+float log1p(float x) {
+ return log(1.0 + x);
+}
+
+float _pow(float v1, float v2) {
+ if (v2 == 0.0) return 1.0;
+ return pow(v1, v2);
+}
+
+float _round(float x) {
+ return floor(x + 0.5);
+}
+
+
+const int BIT_COUNT = 32;
+int modi(int x, int y) {
+ return x - y * (x / y);
+}
+
+int bitwiseOr(int a, int b) {
+ int result = 0;
+ int n = 1;
+
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {
+ result += n;
+ }
+ a = a / 2;
+ b = b / 2;
+ n = n * 2;
+ if(!(a > 0 || b > 0)) {
+ break;
+ }
+ }
+ return result;
+}
+int bitwiseXOR(int a, int b) {
+ int result = 0;
+ int n = 1;
+
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {
+ result += n;
+ }
+ a = a / 2;
+ b = b / 2;
+ n = n * 2;
+ if(!(a > 0 || b > 0)) {
+ break;
+ }
+ }
+ return result;
+}
+int bitwiseAnd(int a, int b) {
+ int result = 0;
+ int n = 1;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {
+ result += n;
+ }
+ a = a / 2;
+ b = b / 2;
+ n = n * 2;
+ if(!(a > 0 && b > 0)) {
+ break;
+ }
+ }
+ return result;
+}
+int bitwiseNot(int a) {
+ int result = 0;
+ int n = 1;
+
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (modi(a, 2) == 0) {
+ result += n;
+ }
+ a = a / 2;
+ n = n * 2;
+ }
+ return result;
+}
+int bitwiseZeroFillLeftShift(int n, int shift) {
+ int maxBytes = BIT_COUNT;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (maxBytes >= n) {
+ break;
+ }
+ maxBytes *= 2;
+ }
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= shift) {
+ break;
+ }
+ n *= 2;
+ }
+
+ int result = 0;
+ int byteVal = 1;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= maxBytes) break;
+ if (modi(n, 2) > 0) { result += byteVal; }
+ n = int(n / 2);
+ byteVal *= 2;
+ }
+ return result;
+}
+
+int bitwiseSignedRightShift(int num, int shifts) {
+ return int(floor(float(num) / pow(2.0, float(shifts))));
+}
+
+int bitwiseZeroFillRightShift(int n, int shift) {
+ int maxBytes = BIT_COUNT;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (maxBytes >= n) {
+ break;
+ }
+ maxBytes *= 2;
+ }
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= shift) {
+ break;
+ }
+ n /= 2;
+ }
+ int result = 0;
+ int byteVal = 1;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= maxBytes) break;
+ if (modi(n, 2) > 0) { result += byteVal; }
+ n = int(n / 2);
+ byteVal *= 2;
+ }
+ return result;
+}
+
+vec2 integerMod(vec2 x, float y) {
+ vec2 res = floor(mod(x, y));
+ return res * step(1.0 - floor(y), -res);
+}
+
+vec3 integerMod(vec3 x, float y) {
+ vec3 res = floor(mod(x, y));
+ return res * step(1.0 - floor(y), -res);
+}
+
+vec4 integerMod(vec4 x, vec4 y) {
+ vec4 res = floor(mod(x, y));
+ return res * step(1.0 - floor(y), -res);
+}
+
+float integerMod(float x, float y) {
+ float res = floor(mod(x, y));
+ return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);
+}
+
+int integerMod(int x, int y) {
+ return x - (y * int(x/y));
+}
+
+__DIVIDE_WITH_INTEGER_CHECK__;
+
+// Here be dragons!
+// DO NOT OPTIMIZE THIS CODE
+// YOU WILL BREAK SOMETHING ON SOMEBODY\'S MACHINE
+// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME
+const vec2 MAGIC_VEC = vec2(1.0, -256.0);
+const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);
+const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536
+float decode32(vec4 texel) {
+ __DECODE32_ENDIANNESS__;
+ texel *= 255.0;
+ vec2 gte128;
+ gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;
+ gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;
+ float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);
+ float res = exp2(round(exponent));
+ texel.b = texel.b - 128.0 * gte128.x;
+ res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;
+ res *= gte128.y * -2.0 + 1.0;
+ return res;
+}
+
+float decode16(vec4 texel, int index) {
+ int channel = integerMod(index, 2);
+ return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0;
+}
+
+float decode8(vec4 texel, int index) {
+ int channel = integerMod(index, 4);
+ return texel[channel] * 255.0;
+}
+
+vec4 legacyEncode32(float f) {
+ float F = abs(f);
+ float sign = f < 0.0 ? 1.0 : 0.0;
+ float exponent = floor(log2(F));
+ float mantissa = (exp2(-exponent) * F);
+ // exponent += floor(log2(mantissa));
+ vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;
+ texel.rg = integerMod(texel.rg, 256.0);
+ texel.b = integerMod(texel.b, 128.0);
+ texel.a = exponent*0.5 + 63.5;
+ texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;
+ texel = floor(texel);
+ texel *= 0.003921569; // 1/255
+ __ENCODE32_ENDIANNESS__;
+ return texel;
+}
+
+// https://github.com/gpujs/gpu.js/wiki/Encoder-details
+vec4 encode32(float value) {
+ if (value == 0.0) return vec4(0, 0, 0, 0);
+
+ float exponent;
+ float mantissa;
+ vec4 result;
+ float sgn;
+
+ sgn = step(0.0, -value);
+ value = abs(value);
+
+ exponent = floor(log2(value));
+
+ mantissa = value*pow(2.0, -exponent)-1.0;
+ exponent = exponent+127.0;
+ result = vec4(0,0,0,0);
+
+ result.a = floor(exponent/2.0);
+ exponent = exponent - result.a*2.0;
+ result.a = result.a + 128.0*sgn;
+
+ result.b = floor(mantissa * 128.0);
+ mantissa = mantissa - result.b / 128.0;
+ result.b = result.b + exponent*128.0;
+
+ result.g = floor(mantissa*32768.0);
+ mantissa = mantissa - result.g/32768.0;
+
+ result.r = floor(mantissa*8388608.0);
+ return result/255.0;
+}
+// Dragons end here
+
+int index;
+ivec3 threadId;
+
+ivec3 indexTo3D(int idx, ivec3 texDim) {
+ int z = int(idx / (texDim.x * texDim.y));
+ idx -= z * int(texDim.x * texDim.y);
+ int y = int(idx / texDim.x);
+ int x = int(integerMod(idx, texDim.x));
+ return ivec3(x, y, z);
+}
+
+float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture(tex, st / vec2(texSize));
+ return decode32(texel);
+}
+
+float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + (texDim.x * (y + (texDim.y * z)));
+ int w = texSize.x * 2;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y));
+ return decode16(texel, index);
+}
+
+float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + (texDim.x * (y + (texDim.y * z)));
+ int w = texSize.x * 4;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y));
+ return decode8(texel, index);
+}
+
+float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + (texDim.x * (y + (texDim.y * z)));
+ int channel = integerMod(index, 4);
+ index = index / 4;
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ index = index / 4;
+ vec4 texel = texture(tex, st / vec2(texSize));
+ return texel[channel];
+}
+
+vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ return texture(tex, st / vec2(texSize));
+}
+
+vec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ return texture(tex, vec3(st / vec2(texSize), z));
+}
+
+float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
+ return result[0];
+}
+
+vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
+ return vec2(result[0], result[1]);
+}
+
+vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int channel = integerMod(index, 2);
+ index = index / 2;
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture(tex, st / vec2(texSize));
+ if (channel == 0) return vec2(texel.r, texel.g);
+ if (channel == 1) return vec2(texel.b, texel.a);
+ return vec2(0.0, 0.0);
+}
+
+vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
+ return vec3(result[0], result[1], result[2]);
+}
+
+vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));
+ int vectorIndex = fieldIndex / 4;
+ int vectorOffset = fieldIndex - vectorIndex * 4;
+ int readY = vectorIndex / texSize.x;
+ int readX = vectorIndex - readY * texSize.x;
+ vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));
+
+ if (vectorOffset == 0) {
+ return tex1.xyz;
+ } else if (vectorOffset == 1) {
+ return tex1.yzw;
+ } else {
+ readX++;
+ if (readX >= texSize.x) {
+ readX = 0;
+ readY++;
+ }
+ vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize));
+ if (vectorOffset == 2) {
+ return vec3(tex1.z, tex1.w, tex2.x);
+ } else {
+ return vec3(tex1.w, tex2.x, tex2.y);
+ }
+ }
+}
+
+vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ return getImage2D(tex, texSize, texDim, z, y, x);
+}
+
+vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int channel = integerMod(index, 2);
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture(tex, st / vec2(texSize));
+ return vec4(texel.r, texel.g, texel.b, texel.a);
+}
+
+vec4 actualColor;
+void color(float r, float g, float b, float a) {
+ actualColor = vec4(r,g,b,a);
+}
+
+void color(float r, float g, float b) {
+ color(r,g,b,1.0);
+}
+
+float modulo(float number, float divisor) {
+ if (number < 0.0) {
+ number = abs(number);
+ if (divisor < 0.0) {
+ divisor = abs(divisor);
+ }
+ return -mod(number, divisor);
+ }
+ if (divisor < 0.0) {
+ divisor = abs(divisor);
+ }
+ return mod(number, divisor);
+}
+
+__INJECTED_NATIVE__;
+__MAIN_CONSTANTS__;
+__MAIN_ARGUMENTS__;
+__KERNEL__;
+
+void main(void) {
+ index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;
+ __MAIN_RESULT__;
+}`;
+
+module.exports = {
+ fragmentShader
+};
+},{}],72:[function(require,module,exports){
+const { utils } = require('../../utils');
+const { WebGLFunctionNode } = require('../web-gl/function-node');
+
+class WebGL2FunctionNode extends WebGLFunctionNode {
+
+ 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('intBitsToFloat(2139095039)');
+ } else if (type === 'Boolean') {
+ if (this.argumentNames.indexOf(name) > -1) {
+ retArr.push(`bool(user_${name})`);
+ } else {
+ retArr.push(`user_${name}`);
+ }
+ } else {
+ retArr.push(`user_${name}`);
+ }
+
+ return retArr;
+ }
+}
+
+module.exports = {
+ WebGL2FunctionNode
+};
+},{"../../utils":113,"../web-gl/function-node":37}],73:[function(require,module,exports){
+const { WebGL2KernelValueBoolean } = require('./kernel-value/boolean');
+const { WebGL2KernelValueFloat } = require('./kernel-value/float');
+const { WebGL2KernelValueInteger } = require('./kernel-value/integer');
+
+const { WebGL2KernelValueHTMLImage } = require('./kernel-value/html-image');
+const { WebGL2KernelValueDynamicHTMLImage } = require('./kernel-value/dynamic-html-image');
+
+const { WebGL2KernelValueHTMLImageArray } = require('./kernel-value/html-image-array');
+const { WebGL2KernelValueDynamicHTMLImageArray } = require('./kernel-value/dynamic-html-image-array');
+
+const { WebGL2KernelValueHTMLVideo } = require('./kernel-value/html-video');
+const { WebGL2KernelValueDynamicHTMLVideo } = require('./kernel-value/dynamic-html-video');
+
+const { WebGL2KernelValueSingleInput } = require('./kernel-value/single-input');
+const { WebGL2KernelValueDynamicSingleInput } = require('./kernel-value/dynamic-single-input');
+
+const { WebGL2KernelValueUnsignedInput } = require('./kernel-value/unsigned-input');
+const { WebGL2KernelValueDynamicUnsignedInput } = require('./kernel-value/dynamic-unsigned-input');
+
+const { WebGL2KernelValueMemoryOptimizedNumberTexture } = require('./kernel-value/memory-optimized-number-texture');
+const { WebGL2KernelValueDynamicMemoryOptimizedNumberTexture } = require('./kernel-value/dynamic-memory-optimized-number-texture');
+
+const { WebGL2KernelValueNumberTexture } = require('./kernel-value/number-texture');
+const { WebGL2KernelValueDynamicNumberTexture } = require('./kernel-value/dynamic-number-texture');
+
+const { WebGL2KernelValueSingleArray } = require('./kernel-value/single-array');
+const { WebGL2KernelValueDynamicSingleArray } = require('./kernel-value/dynamic-single-array');
+
+const { WebGL2KernelValueSingleArray1DI } = require('./kernel-value/single-array1d-i');
+const { WebGL2KernelValueDynamicSingleArray1DI } = require('./kernel-value/dynamic-single-array1d-i');
+
+const { WebGL2KernelValueSingleArray2DI } = require('./kernel-value/single-array2d-i');
+const { WebGL2KernelValueDynamicSingleArray2DI } = require('./kernel-value/dynamic-single-array2d-i');
+
+const { WebGL2KernelValueSingleArray3DI } = require('./kernel-value/single-array3d-i');
+const { WebGL2KernelValueDynamicSingleArray3DI } = require('./kernel-value/dynamic-single-array3d-i');
+
+const { WebGL2KernelValueArray2 } = require('./kernel-value/array2');
+const { WebGL2KernelValueArray3 } = require('./kernel-value/array3');
+const { WebGL2KernelValueArray4 } = require('./kernel-value/array4');
+
+const { WebGL2KernelValueUnsignedArray } = require('./kernel-value/unsigned-array');
+const { WebGL2KernelValueDynamicUnsignedArray } = require('./kernel-value/dynamic-unsigned-array');
+
+const kernelValueMaps = {
+ unsigned: {
+ dynamic: {
+ 'Boolean': WebGL2KernelValueBoolean,
+ 'Integer': WebGL2KernelValueInteger,
+ 'Float': WebGL2KernelValueFloat,
+ 'Array': WebGL2KernelValueDynamicUnsignedArray,
+ 'Array(2)': WebGL2KernelValueArray2,
+ 'Array(3)': WebGL2KernelValueArray3,
+ 'Array(4)': WebGL2KernelValueArray4,
+ 'Array1D(2)': false,
+ 'Array1D(3)': false,
+ 'Array1D(4)': false,
+ 'Array2D(2)': false,
+ 'Array2D(3)': false,
+ 'Array2D(4)': false,
+ 'Array3D(2)': false,
+ 'Array3D(3)': false,
+ 'Array3D(4)': false,
+ 'Input': WebGL2KernelValueDynamicUnsignedInput,
+ 'NumberTexture': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGL2KernelValueDynamicHTMLImage,
+ 'OffscreenCanvas': WebGL2KernelValueDynamicHTMLImage,
+ 'HTMLImage': WebGL2KernelValueDynamicHTMLImage,
+ 'ImageBitmap': WebGL2KernelValueDynamicHTMLImage,
+ 'ImageData': WebGL2KernelValueDynamicHTMLImage,
+ 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray,
+ 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo,
+ },
+ static: {
+ 'Boolean': WebGL2KernelValueBoolean,
+ 'Float': WebGL2KernelValueFloat,
+ 'Integer': WebGL2KernelValueInteger,
+ 'Array': WebGL2KernelValueUnsignedArray,
+ 'Array(2)': WebGL2KernelValueArray2,
+ 'Array(3)': WebGL2KernelValueArray3,
+ 'Array(4)': WebGL2KernelValueArray4,
+ 'Array1D(2)': false,
+ 'Array1D(3)': false,
+ 'Array1D(4)': false,
+ 'Array2D(2)': false,
+ 'Array2D(3)': false,
+ 'Array2D(4)': false,
+ 'Array3D(2)': false,
+ 'Array3D(3)': false,
+ 'Array3D(4)': false,
+ 'Input': WebGL2KernelValueUnsignedInput,
+ 'NumberTexture': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(1)': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(2)': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(3)': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(4)': WebGL2KernelValueNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGL2KernelValueHTMLImage,
+ 'OffscreenCanvas': WebGL2KernelValueHTMLImage,
+ 'HTMLImage': WebGL2KernelValueHTMLImage,
+ 'ImageBitmap': WebGL2KernelValueHTMLImage,
+ 'ImageData': WebGL2KernelValueHTMLImage,
+ 'HTMLImageArray': WebGL2KernelValueHTMLImageArray,
+ 'HTMLVideo': WebGL2KernelValueHTMLVideo,
+ }
+ },
+ single: {
+ dynamic: {
+ 'Boolean': WebGL2KernelValueBoolean,
+ 'Integer': WebGL2KernelValueInteger,
+ 'Float': WebGL2KernelValueFloat,
+ 'Array': WebGL2KernelValueDynamicSingleArray,
+ 'Array(2)': WebGL2KernelValueArray2,
+ 'Array(3)': WebGL2KernelValueArray3,
+ 'Array(4)': WebGL2KernelValueArray4,
+ 'Array1D(2)': WebGL2KernelValueDynamicSingleArray1DI,
+ 'Array1D(3)': WebGL2KernelValueDynamicSingleArray1DI,
+ 'Array1D(4)': WebGL2KernelValueDynamicSingleArray1DI,
+ 'Array2D(2)': WebGL2KernelValueDynamicSingleArray2DI,
+ 'Array2D(3)': WebGL2KernelValueDynamicSingleArray2DI,
+ 'Array2D(4)': WebGL2KernelValueDynamicSingleArray2DI,
+ 'Array3D(2)': WebGL2KernelValueDynamicSingleArray3DI,
+ 'Array3D(3)': WebGL2KernelValueDynamicSingleArray3DI,
+ 'Array3D(4)': WebGL2KernelValueDynamicSingleArray3DI,
+ 'Input': WebGL2KernelValueDynamicSingleInput,
+ 'NumberTexture': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGL2KernelValueDynamicHTMLImage,
+ 'OffscreenCanvas': WebGL2KernelValueDynamicHTMLImage,
+ 'HTMLImage': WebGL2KernelValueDynamicHTMLImage,
+ 'ImageBitmap': WebGL2KernelValueDynamicHTMLImage,
+ 'ImageData': WebGL2KernelValueDynamicHTMLImage,
+ 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray,
+ 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo,
+ },
+ static: {
+ 'Boolean': WebGL2KernelValueBoolean,
+ 'Float': WebGL2KernelValueFloat,
+ 'Integer': WebGL2KernelValueInteger,
+ 'Array': WebGL2KernelValueSingleArray,
+ 'Array(2)': WebGL2KernelValueArray2,
+ 'Array(3)': WebGL2KernelValueArray3,
+ 'Array(4)': WebGL2KernelValueArray4,
+ 'Array1D(2)': WebGL2KernelValueSingleArray1DI,
+ 'Array1D(3)': WebGL2KernelValueSingleArray1DI,
+ 'Array1D(4)': WebGL2KernelValueSingleArray1DI,
+ 'Array2D(2)': WebGL2KernelValueSingleArray2DI,
+ 'Array2D(3)': WebGL2KernelValueSingleArray2DI,
+ 'Array2D(4)': WebGL2KernelValueSingleArray2DI,
+ 'Array3D(2)': WebGL2KernelValueSingleArray3DI,
+ 'Array3D(3)': WebGL2KernelValueSingleArray3DI,
+ 'Array3D(4)': WebGL2KernelValueSingleArray3DI,
+ 'Input': WebGL2KernelValueSingleInput,
+ 'NumberTexture': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(1)': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(2)': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(3)': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(4)': WebGL2KernelValueNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGL2KernelValueMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGL2KernelValueHTMLImage,
+ 'OffscreenCanvas': WebGL2KernelValueHTMLImage,
+ 'HTMLImage': WebGL2KernelValueHTMLImage,
+ 'ImageBitmap': WebGL2KernelValueHTMLImage,
+ 'ImageData': WebGL2KernelValueHTMLImage,
+ 'HTMLImageArray': WebGL2KernelValueHTMLImageArray,
+ 'HTMLVideo': WebGL2KernelValueHTMLVideo,
+ }
+ },
+};
+
+function lookupKernelValueType(type, dynamic, precision, value) {
+ if (!type) {
+ throw new Error('type missing');
+ }
+ if (!dynamic) {
+ throw new Error('dynamic missing');
+ }
+ if (!precision) {
+ throw new Error('precision missing');
+ }
+ if (value.type) {
+ type = value.type;
+ }
+ const types = kernelValueMaps[precision][dynamic];
+ if (types[type] === false) {
+ return null;
+ } else if (types[type] === undefined) {
+ throw new Error(`Could not find a KernelValue for ${ type }`);
+ }
+ return types[type];
+}
+
+module.exports = {
+ kernelValueMaps,
+ lookupKernelValueType
+};
+},{"./kernel-value/array2":74,"./kernel-value/array3":75,"./kernel-value/array4":76,"./kernel-value/boolean":77,"./kernel-value/dynamic-html-image":79,"./kernel-value/dynamic-html-image-array":78,"./kernel-value/dynamic-html-video":80,"./kernel-value/dynamic-memory-optimized-number-texture":81,"./kernel-value/dynamic-number-texture":82,"./kernel-value/dynamic-single-array":83,"./kernel-value/dynamic-single-array1d-i":84,"./kernel-value/dynamic-single-array2d-i":85,"./kernel-value/dynamic-single-array3d-i":86,"./kernel-value/dynamic-single-input":87,"./kernel-value/dynamic-unsigned-array":88,"./kernel-value/dynamic-unsigned-input":89,"./kernel-value/float":90,"./kernel-value/html-image":92,"./kernel-value/html-image-array":91,"./kernel-value/html-video":93,"./kernel-value/integer":94,"./kernel-value/memory-optimized-number-texture":95,"./kernel-value/number-texture":96,"./kernel-value/single-array":97,"./kernel-value/single-array1d-i":98,"./kernel-value/single-array2d-i":99,"./kernel-value/single-array3d-i":100,"./kernel-value/single-input":101,"./kernel-value/unsigned-array":102,"./kernel-value/unsigned-input":103}],74:[function(require,module,exports){
+const { WebGLKernelValueArray2 } = require('../../web-gl/kernel-value/array2');
+
+class WebGL2KernelValueArray2 extends WebGLKernelValueArray2 {}
+
+module.exports = {
+ WebGL2KernelValueArray2
+};
+},{"../../web-gl/kernel-value/array2":40}],75:[function(require,module,exports){
+const { WebGLKernelValueArray3 } = require('../../web-gl/kernel-value/array3');
+
+class WebGL2KernelValueArray3 extends WebGLKernelValueArray3 {}
+
+module.exports = {
+ WebGL2KernelValueArray3
+};
+},{"../../web-gl/kernel-value/array3":41}],76:[function(require,module,exports){
+const { WebGLKernelValueArray4 } = require('../../web-gl/kernel-value/array4');
+
+class WebGL2KernelValueArray4 extends WebGLKernelValueArray4 {}
+
+module.exports = {
+ WebGL2KernelValueArray4
+};
+},{"../../web-gl/kernel-value/array4":42}],77:[function(require,module,exports){
+const { WebGLKernelValueBoolean } = require('../../web-gl/kernel-value/boolean');
+
+class WebGL2KernelValueBoolean extends WebGLKernelValueBoolean {}
+
+module.exports = {
+ WebGL2KernelValueBoolean
+};
+},{"../../web-gl/kernel-value/boolean":43}],78:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueHTMLImageArray } = require('./html-image-array');
+
+class WebGL2KernelValueDynamicHTMLImageArray extends WebGL2KernelValueHTMLImageArray {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2DArray ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(images) {
+ const { width, height } = images[0];
+ this.checkSize(width, height);
+ this.dimensions = [width, height, images.length];
+ this.textureSize = [width, height];
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(images);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicHTMLImageArray
+};
+},{"../../../utils":113,"./html-image-array":91}],79:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueDynamicHTMLImage } = require('../../web-gl/kernel-value/dynamic-html-image');
+
+class WebGL2KernelValueDynamicHTMLImage extends WebGLKernelValueDynamicHTMLImage {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicHTMLImage
+};
+},{"../../../utils":113,"../../web-gl/kernel-value/dynamic-html-image":44}],80:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueDynamicHTMLImage } = require('./dynamic-html-image');
+
+class WebGL2KernelValueDynamicHTMLVideo extends WebGL2KernelValueDynamicHTMLImage {}
+
+module.exports = {
+ WebGL2KernelValueDynamicHTMLVideo
+};
+},{"../../../utils":113,"./dynamic-html-image":79}],81:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } = require('../../web-gl/kernel-value/dynamic-memory-optimized-number-texture');
+
+class WebGL2KernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueDynamicMemoryOptimizedNumberTexture {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicMemoryOptimizedNumberTexture
+};
+},{"../../../utils":113,"../../web-gl/kernel-value/dynamic-memory-optimized-number-texture":46}],82:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueDynamicNumberTexture } = require('../../web-gl/kernel-value/dynamic-number-texture');
+
+class WebGL2KernelValueDynamicNumberTexture extends WebGLKernelValueDynamicNumberTexture {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicNumberTexture
+};
+},{"../../../utils":113,"../../web-gl/kernel-value/dynamic-number-texture":47}],83:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueSingleArray } = require('../../web-gl2/kernel-value/single-array');
+
+class WebGL2KernelValueDynamicSingleArray extends WebGL2KernelValueSingleArray {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.dimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.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(value);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicSingleArray
+};
+},{"../../../utils":113,"../../web-gl2/kernel-value/single-array":97}],84:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueSingleArray1DI } = require('../../web-gl2/kernel-value/single-array1d-i');
+
+class WebGL2KernelValueDynamicSingleArray1DI extends WebGL2KernelValueSingleArray1DI {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.setShape(value);
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicSingleArray1DI
+};
+},{"../../../utils":113,"../../web-gl2/kernel-value/single-array1d-i":98}],85:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueSingleArray2DI } = require('../../web-gl2/kernel-value/single-array2d-i');
+
+class WebGL2KernelValueDynamicSingleArray2DI extends WebGL2KernelValueSingleArray2DI {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.setShape(value);
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicSingleArray2DI
+};
+},{"../../../utils":113,"../../web-gl2/kernel-value/single-array2d-i":99}],86:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueSingleArray3DI } = require('../../web-gl2/kernel-value/single-array3d-i');
+
+class WebGL2KernelValueDynamicSingleArray3DI extends WebGL2KernelValueSingleArray3DI {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.setShape(value);
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicSingleArray3DI
+};
+},{"../../../utils":113,"../../web-gl2/kernel-value/single-array3d-i":100}],87:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueSingleInput } = require('../../web-gl2/kernel-value/single-input');
+
+class WebGL2KernelValueDynamicSingleInput extends WebGL2KernelValueSingleInput {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ let [w, h, d] = value.size;
+ this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);
+ this.textureSize = utils.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(value);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicSingleInput
+};
+},{"../../../utils":113,"../../web-gl2/kernel-value/single-input":101}],88:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueDynamicUnsignedArray } = require('../../web-gl/kernel-value/dynamic-unsigned-array');
+
+class WebGL2KernelValueDynamicUnsignedArray extends WebGLKernelValueDynamicUnsignedArray {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicUnsignedArray
+};
+},{"../../../utils":113,"../../web-gl/kernel-value/dynamic-unsigned-array":53}],89:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueDynamicUnsignedInput } = require('../../web-gl/kernel-value/dynamic-unsigned-input');
+
+class WebGL2KernelValueDynamicUnsignedInput extends WebGLKernelValueDynamicUnsignedInput {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicUnsignedInput
+};
+},{"../../../utils":113,"../../web-gl/kernel-value/dynamic-unsigned-input":54}],90:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueFloat } = require('../../web-gl/kernel-value/float');
+
+class WebGL2KernelValueFloat extends WebGLKernelValueFloat {}
+
+module.exports = {
+ WebGL2KernelValueFloat
+};
+},{"../../../utils":113,"../../web-gl/kernel-value/float":55}],91:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('../../web-gl/kernel-value/array');
+
+class WebGL2KernelValueHTMLImageArray extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.checkSize(value[0].width, value[0].height);
+ this.dimensions = [value[0].width, value[0].height, value.length];
+ this.textureSize = [value[0].width, value[0].height];
+ }
+ defineTexture() {
+ const { context: gl } = this;
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.texture);
+ gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ }
+
+ getStringValueHandler() {
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2DArray ${this.id}`,
+ `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,
+ ]);
+ }
+
+ updateValue(images) {
+ const { context: gl } = this;
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
+ gl.texImage3D(
+ gl.TEXTURE_2D_ARRAY,
+ 0,
+ gl.RGBA,
+ images[0].width,
+ images[0].height,
+ images.length,
+ 0,
+ gl.RGBA,
+ gl.UNSIGNED_BYTE,
+ null
+ );
+ for (let i = 0; i < images.length; i++) {
+ const xOffset = 0;
+ const yOffset = 0;
+ const imageDepth = 1;
+ gl.texSubImage3D(
+ gl.TEXTURE_2D_ARRAY,
+ 0,
+ xOffset,
+ yOffset,
+ i,
+ images[i].width,
+ images[i].height,
+ imageDepth,
+ gl.RGBA,
+ gl.UNSIGNED_BYTE,
+ this.uploadValue = images[i]
+ );
+ }
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueHTMLImageArray
+};
+},{"../../../utils":113,"../../web-gl/kernel-value/array":39}],92:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueHTMLImage } = require('../../web-gl/kernel-value/html-image');
+
+class WebGL2KernelValueHTMLImage extends WebGLKernelValueHTMLImage {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueHTMLImage
+};
+},{"../../../utils":113,"../../web-gl/kernel-value/html-image":56}],93:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueHTMLImage } = require('./html-image');
+
+class WebGL2KernelValueHTMLVideo extends WebGL2KernelValueHTMLImage {}
+
+module.exports = {
+ WebGL2KernelValueHTMLVideo
+};
+},{"../../../utils":113,"./html-image":92}],94:[function(require,module,exports){
+const { WebGLKernelValueInteger } = require('../../web-gl/kernel-value/integer');
+
+class WebGL2KernelValueInteger extends WebGLKernelValueInteger {
+ getSource(value) {
+ const variablePrecision = this.getVariablePrecisionString();
+ if (this.origin === 'constants') {
+ return `const ${ variablePrecision } int ${this.id} = ${ parseInt(value) };\n`;
+ }
+ return `uniform ${ variablePrecision } int ${this.id};\n`;
+ }
+
+ updateValue(value) {
+ if (this.origin === 'constants') return;
+ this.kernel.setUniform1i(this.id, this.uploadValue = value);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueInteger
+};
+},{"../../web-gl/kernel-value/integer":59}],95:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueMemoryOptimizedNumberTexture } = require('../../web-gl/kernel-value/memory-optimized-number-texture');
+
+class WebGL2KernelValueMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture {
+ getSource() {
+ const { id, sizeId, textureSize, dimensionsId, dimensions } = this;
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform sampler2D ${id}`,
+ `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueMemoryOptimizedNumberTexture
+};
+},{"../../../utils":113,"../../web-gl/kernel-value/memory-optimized-number-texture":60}],96:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueNumberTexture } = require('../../web-gl/kernel-value/number-texture');
+
+class WebGL2KernelValueNumberTexture extends WebGLKernelValueNumberTexture {
+ getSource() {
+ const { id, sizeId, textureSize, dimensionsId, dimensions } = this;
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${id}`,
+ `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueNumberTexture
+};
+},{"../../../utils":113,"../../web-gl/kernel-value/number-texture":61}],97:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray } = require('../../web-gl/kernel-value/single-array');
+
+class WebGL2KernelValueSingleArray extends WebGLKernelValueSingleArray {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,
+ ]);
+ }
+
+ updateValue(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueSingleArray
+};
+},{"../../../utils":113,"../../web-gl/kernel-value/single-array":62}],98:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray1DI } = require('../../web-gl/kernel-value/single-array1d-i');
+
+class WebGL2KernelValueSingleArray1DI extends WebGLKernelValueSingleArray1DI {
+ updateValue(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueSingleArray1DI
+};
+},{"../../../utils":113,"../../web-gl/kernel-value/single-array1d-i":63}],99:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray2DI } = require('../../web-gl/kernel-value/single-array2d-i');
+
+class WebGL2KernelValueSingleArray2DI extends WebGLKernelValueSingleArray2DI {
+ updateValue(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueSingleArray2DI
+};
+},{"../../../utils":113,"../../web-gl/kernel-value/single-array2d-i":64}],100:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray3DI } = require('../../web-gl/kernel-value/single-array3d-i');
+
+class WebGL2KernelValueSingleArray3DI extends WebGLKernelValueSingleArray3DI {
+ updateValue(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueSingleArray3DI
+};
+},{"../../../utils":113,"../../web-gl/kernel-value/single-array3d-i":65}],101:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleInput } = require('../../web-gl/kernel-value/single-input');
+
+class WebGL2KernelValueSingleInput extends WebGLKernelValueSingleInput {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,
+ ]);
+ }
+
+ updateValue(input) {
+ const { context: gl } = this;
+ utils.flattenTo(input.value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueSingleInput
+};
+},{"../../../utils":113,"../../web-gl/kernel-value/single-input":66}],102:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueUnsignedArray } = require('../../web-gl/kernel-value/unsigned-array');
+
+class WebGL2KernelValueUnsignedArray extends WebGLKernelValueUnsignedArray {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueUnsignedArray
+};
+},{"../../../utils":113,"../../web-gl/kernel-value/unsigned-array":67}],103:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueUnsignedInput } = require('../../web-gl/kernel-value/unsigned-input');
+
+class WebGL2KernelValueUnsignedInput extends WebGLKernelValueUnsignedInput {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueUnsignedInput
+};
+},{"../../../utils":113,"../../web-gl/kernel-value/unsigned-input":68}],104:[function(require,module,exports){
+const { WebGLKernel } = require('../web-gl/kernel');
+const { WebGL2FunctionNode } = require('./function-node');
+const { FunctionBuilder } = require('../function-builder');
+const { utils } = require('../../utils');
+const { fragmentShader } = require('./fragment-shader');
+const { vertexShader } = require('./vertex-shader');
+const { lookupKernelValueType } = require('./kernel-value-maps');
+
+let isSupported = null;
+let testCanvas = null;
+let testContext = null;
+let testExtensions = null;
+
+let features = null;
+
+class WebGL2Kernel extends WebGLKernel {
+ static get isSupported() {
+ if (isSupported !== null) {
+ return isSupported;
+ }
+ this.setupFeatureChecks();
+ isSupported = this.isContextMatch(testContext);
+ return isSupported;
+ }
+
+ static setupFeatureChecks() {
+ if (typeof document !== 'undefined') {
+ testCanvas = document.createElement('canvas');
+ } else if (typeof OffscreenCanvas !== 'undefined') {
+ testCanvas = new OffscreenCanvas(0, 0);
+ }
+ if (!testCanvas) return;
+ testContext = testCanvas.getContext('webgl2');
+ if (!testContext || !testContext.getExtension) return;
+ testExtensions = {
+ EXT_color_buffer_float: testContext.getExtension('EXT_color_buffer_float'),
+ OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'),
+ };
+ features = this.getFeatures();
+ }
+
+ static isContextMatch(context) {
+ if (typeof WebGL2RenderingContext !== 'undefined') {
+ return context instanceof WebGL2RenderingContext;
+ }
+ return false;
+ }
+
+ static getFeatures() {
+ const gl = this.testContext;
+ return Object.freeze({
+ isFloatRead: this.getIsFloatRead(),
+ isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(),
+ isSpeedTacticSupported: this.getIsSpeedTacticSupported(),
+ kernelMap: true,
+ isTextureFloat: true,
+ isDrawBuffers: true,
+ channelCount: this.getChannelCount(),
+ maxTextureSize: this.getMaxTextureSize(),
+ lowIntPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_INT),
+ lowFloatPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_FLOAT),
+ mediumIntPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_INT),
+ mediumFloatPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT),
+ highIntPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_INT),
+ highFloatPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT),
+ });
+ }
+
+ static getIsTextureFloat() {
+ return true;
+ }
+
+ static getChannelCount() {
+ return testContext.getParameter(testContext.MAX_DRAW_BUFFERS);
+ }
+
+ static getMaxTextureSize() {
+ return testContext.getParameter(testContext.MAX_TEXTURE_SIZE);
+ }
+
+ static lookupKernelValueType(type, dynamic, precision, value) {
+ return lookupKernelValueType(type, dynamic, precision, value);
+ }
+
+ static get testCanvas() {
+ return testCanvas;
+ }
+
+ static get testContext() {
+ return testContext;
+ }
+
+ static get features() {
+ return features;
+ }
+
+ static get fragmentShader() {
+ return fragmentShader;
+ }
+ static get vertexShader() {
+ return vertexShader;
+ }
+
+ initContext() {
+ const settings = {
+ alpha: false,
+ depth: false,
+ antialias: false
+ };
+ return this.canvas.getContext('webgl2', settings);
+ }
+
+ 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(args) {
+ if (!this.validate) {
+ this.texSize = utils.getKernelTextureSize({
+ optimizeFloatMemory: this.optimizeFloatMemory,
+ precision: this.precision,
+ }, this.output);
+ return;
+ }
+
+ const { features } = this.constructor;
+ if (this.precision === 'single' && !features.isFloatRead) {
+ throw new Error('Float texture outputs are not supported');
+ } else if (!this.graphical && this.precision === null) {
+ this.precision = features.isFloatRead ? 'single' : 'unsigned';
+ }
+
+ if (this.fixIntegerDivisionAccuracy === null) {
+ this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate;
+ } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) {
+ this.fixIntegerDivisionAccuracy = false;
+ }
+
+ this.checkOutput();
+
+ 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);
+ switch (argType) {
+ case 'Array':
+ this.output = utils.getDimensions(argType);
+ break;
+ case 'NumberTexture':
+ case 'MemoryOptimizedNumberTexture':
+ case 'ArrayTexture(1)':
+ case 'ArrayTexture(2)':
+ case 'ArrayTexture(3)':
+ case 'ArrayTexture(4)':
+ this.output = args[0].output;
+ break;
+ default:
+ throw new Error('Auto output not supported for input type: ' + argType);
+ }
+ }
+
+ if (this.graphical) {
+ if (this.output.length !== 2) {
+ throw new Error('Output must have 2 dimensions on graphical mode');
+ }
+
+ if (this.precision === 'single') {
+ console.warn('Cannot use graphical mode and single precision at the same time');
+ this.precision = 'unsigned';
+ }
+
+ this.texSize = utils.clone(this.output);
+ return;
+ } else if (!this.graphical && this.precision === null && features.isTextureFloat) {
+ this.precision = 'single';
+ }
+
+ this.texSize = utils.getKernelTextureSize({
+ optimizeFloatMemory: this.optimizeFloatMemory,
+ precision: this.precision,
+ }, this.output);
+
+ this.checkTextureSize();
+ }
+
+ translateSource() {
+ const functionBuilder = FunctionBuilder.fromKernel(this, WebGL2FunctionNode, {
+ fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy
+ });
+ this.translatedSource = functionBuilder.getPrototypeString('kernel');
+ this.setupReturnTypes(functionBuilder);
+ }
+
+ drawBuffers() {
+ this.context.drawBuffers(this.drawBuffersMap);
+ }
+
+ getTextureFormat() {
+ const { context: gl } = this;
+ switch (this.getInternalFormat()) {
+ case gl.R32F:
+ return gl.RED;
+ case gl.RG32F:
+ return gl.RG;
+ case gl.RGBA32F:
+ return gl.RGBA;
+ case gl.RGBA:
+ return gl.RGBA;
+ default:
+ throw new Error('Unknown internal format');
+ }
+ }
+ getInternalFormat() {
+ const { context: gl } = this;
+
+ if (this.precision === 'single') {
+ if (this.pipeline) {
+ switch (this.returnType) {
+ case 'Number':
+ case 'Float':
+ case 'Integer':
+ if (this.optimizeFloatMemory) {
+ return gl.RGBA32F;
+ } else {
+ return gl.R32F;
+ }
+ case 'Array(2)':
+ return gl.RG32F;
+ case 'Array(3)':
+ case 'Array(4)':
+ return gl.RGBA32F;
+ default:
+ throw new Error('Unhandled return type');
+ }
+ }
+ return gl.RGBA32F;
+ }
+ return gl.RGBA;
+ }
+
+ _setupOutputTexture() {
+ const gl = this.context;
+ if (this.texture) {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture.texture, 0);
+ return;
+ }
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
+ const texture = gl.createTexture();
+ const texSize = this.texSize;
+ gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ const format = this.getInternalFormat();
+ if (this.precision === 'single') {
+ gl.texStorage2D(gl.TEXTURE_2D, 1, format, texSize[0], texSize[1]);
+ } else {
+ gl.texImage2D(gl.TEXTURE_2D, 0, format, texSize[0], texSize[1], 0, format, gl.UNSIGNED_BYTE, null);
+ }
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ this.texture = new this.TextureConstructor({
+ texture,
+ size: texSize,
+ dimensions: this.threadDim,
+ output: this.output,
+ context: this.context,
+ internalFormat: this.getInternalFormat(),
+ textureFormat: this.getTextureFormat(),
+ kernel: this,
+ });
+ }
+
+ _setupSubOutputTextures() {
+ const gl = this.context;
+ if (this.mappedTextures) {
+ for (let i = 0; i < this.subKernels.length; i++) {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, this.mappedTextures[i].texture, 0);
+ }
+ return;
+ }
+ const texSize = this.texSize;
+ this.drawBuffersMap = [gl.COLOR_ATTACHMENT0];
+ this.mappedTextures = [];
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const texture = this.createTexture();
+ this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1);
+ gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ const format = this.getInternalFormat();
+ if (this.precision === 'single') {
+ gl.texStorage2D(gl.TEXTURE_2D, 1, format, texSize[0], texSize[1]);
+ } else {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ }
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0);
+
+ this.mappedTextures.push(new this.TextureConstructor({
+ texture,
+ size: texSize,
+ dimensions: this.threadDim,
+ output: this.output,
+ context: this.context,
+ internalFormat: this.getInternalFormat(),
+ textureFormat: this.getTextureFormat(),
+ kernel: this,
+ }));
+ }
+ }
+
+ _getHeaderString() {
+ return '';
+ }
+
+ _getTextureCoordinate() {
+ const subKernels = this.subKernels;
+ const variablePrecision = this.getVariablePrecisionString(this.texSize, this.tactic);
+ if (subKernels === null || subKernels.length < 1) {
+ return `in ${ variablePrecision } vec2 vTexCoord;\n`;
+ } else {
+ return `out ${ variablePrecision } vec2 vTexCoord;\n`;
+ }
+ }
+
+ _getMainArgumentsString(args) {
+ const result = [];
+ const argumentNames = this.argumentNames;
+ for (let i = 0; i < argumentNames.length; i++) {
+ result.push(this.kernelArguments[i].getSource(args[i]));
+ }
+ return result.join('');
+ }
+
+ getKernelString() {
+ const result = [this.getKernelResultDeclaration()];
+ const subKernels = this.subKernels;
+ if (subKernels !== null) {
+ result.push(
+ 'layout(location = 0) out vec4 data0'
+ );
+ switch (this.returnType) {
+ case 'Number':
+ case 'Float':
+ case 'Integer':
+ for (let i = 0; i < subKernels.length; i++) {
+ const subKernel = subKernels[i];
+ result.push(
+ subKernel.returnType === 'Integer' ?
+ `int subKernelResult_${ subKernel.name } = 0` :
+ `float subKernelResult_${ subKernel.name } = 0.0`,
+ `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }`
+ );
+ }
+ break;
+ case 'Array(2)':
+ for (let i = 0; i < subKernels.length; i++) {
+ result.push(
+ `vec2 subKernelResult_${ subKernels[i].name }`,
+ `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }`
+ );
+ }
+ break;
+ case 'Array(3)':
+ for (let i = 0; i < subKernels.length; i++) {
+ result.push(
+ `vec3 subKernelResult_${ subKernels[i].name }`,
+ `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }`
+ );
+ }
+ break;
+ case 'Array(4)':
+ for (let i = 0; i < subKernels.length; i++) {
+ result.push(
+ `vec4 subKernelResult_${ subKernels[i].name }`,
+ `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }`
+ );
+ }
+ break;
+ }
+ } else {
+ result.push(
+ 'out vec4 data0'
+ );
+ }
+
+ return utils.linesToString(result) + this.translatedSource;
+ }
+
+ getMainResultGraphical() {
+ return utils.linesToString([
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' data0 = actualColor',
+ ]);
+ }
+
+ getMainResultPackedPixels() {
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ return this.getMainResultKernelPackedPixels() +
+ this.getMainResultSubKernelPackedPixels();
+ default:
+ throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`);
+ }
+ }
+
+ getMainResultKernelPackedPixels() {
+ return utils.linesToString([
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ` data0 = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)`
+ ]);
+ }
+
+ getMainResultSubKernelPackedPixels() {
+ const result = [];
+ if (!this.subKernels) return '';
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const subKernel = this.subKernels[i];
+ if (subKernel.returnType === 'Integer') {
+ result.push(
+ ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))`
+ );
+ } else {
+ result.push(
+ ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})`
+ );
+ }
+ }
+ return utils.linesToString(result);
+ }
+
+ getMainResultKernelMemoryOptimizedFloats(result, channel) {
+ result.push(
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ` data0.${channel} = kernelResult`
+ );
+ }
+
+ getMainResultSubKernelMemoryOptimizedFloats(result, channel) {
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const subKernel = this.subKernels[i];
+ if (subKernel.returnType === 'Integer') {
+ result.push(
+ ` data${i + 1}.${channel} = float(subKernelResult_${subKernel.name})`
+ );
+ } else {
+ result.push(
+ ` data${i + 1}.${channel} = subKernelResult_${subKernel.name}`
+ );
+ }
+ }
+ }
+
+ getMainResultKernelNumberTexture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' data0[0] = kernelResult',
+ ];
+ }
+
+ getMainResultSubKernelNumberTexture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ const subKernel = this.subKernels[i];
+ if (subKernel.returnType === 'Integer') {
+ result.push(
+ ` data${i + 1}[0] = float(subKernelResult_${subKernel.name})`
+ );
+ } else {
+ result.push(
+ ` data${i + 1}[0] = subKernelResult_${subKernel.name}`
+ );
+ }
+ }
+ return result;
+ }
+
+ getMainResultKernelArray2Texture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' data0[0] = kernelResult[0]',
+ ' data0[1] = kernelResult[1]',
+ ];
+ }
+
+ getMainResultSubKernelArray2Texture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ const subKernel = this.subKernels[i];
+ result.push(
+ ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`,
+ ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`
+ );
+ }
+ return result;
+ }
+
+ getMainResultKernelArray3Texture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' data0[0] = kernelResult[0]',
+ ' data0[1] = kernelResult[1]',
+ ' data0[2] = kernelResult[2]',
+ ];
+ }
+
+ getMainResultSubKernelArray3Texture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ const subKernel = this.subKernels[i];
+ result.push(
+ ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`,
+ ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`,
+ ` data${i + 1}[2] = subKernelResult_${subKernel.name}[2]`
+ );
+ }
+ return result;
+ }
+
+ getMainResultKernelArray4Texture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' data0 = kernelResult',
+ ];
+ }
+
+ getMainResultSubKernelArray4Texture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ result.push(
+ ` data${i + 1} = subKernelResult_${this.subKernels[i].name}`
+ );
+ }
+ return result;
+ }
+
+ destroyExtensions() {
+ this.extensions.EXT_color_buffer_float = null;
+ this.extensions.OES_texture_float_linear = null;
+ }
+
+ toJSON() {
+ const json = super.toJSON();
+ json.functionNodes = FunctionBuilder.fromKernel(this, WebGL2FunctionNode).toJSON();
+ json.settings.threadDim = this.threadDim;
+ return json;
+ }
+}
+
+module.exports = {
+ WebGL2Kernel
+};
+},{"../../utils":113,"../function-builder":8,"../web-gl/kernel":69,"./fragment-shader":71,"./function-node":72,"./kernel-value-maps":73,"./vertex-shader":105}],105:[function(require,module,exports){
+const vertexShader = `#version 300 es
+__FLOAT_TACTIC_DECLARATION__;
+__INT_TACTIC_DECLARATION__;
+__SAMPLER_2D_TACTIC_DECLARATION__;
+
+in vec2 aPos;
+in vec2 aTexCoord;
+
+out vec2 vTexCoord;
+uniform vec2 ratio;
+
+void main(void) {
+ gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);
+ vTexCoord = aTexCoord;
+}`;
+
+module.exports = {
+ vertexShader
+};
+},{}],106:[function(require,module,exports){
+const lib = require('./index');
+const GPU = lib.GPU;
+for (const p in lib) {
+ if (!lib.hasOwnProperty(p)) continue;
+ if (p === 'GPU') continue;
+ GPU[p] = lib[p];
+}
+
+if (typeof window !== 'undefined') {
+ bindTo(window);
+}
+if (typeof self !== 'undefined') {
+ bindTo(self);
+}
+
+function bindTo(target) {
+ if (target.GPU) return;
+ Object.defineProperty(target, 'GPU', {
+ get() {
+ return GPU;
+ }
+ });
+}
+
+module.exports = lib;
+},{"./index":108}],107:[function(require,module,exports){
+const { gpuMock } = require('gpu-mock.js');
+const { utils } = require('./utils');
+const { Kernel } = require('./backend/kernel');
+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 { 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;
+
+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 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, 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 === '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 = {};
+ const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings) || {};
+ if (settings && typeof settings.argumentTypes === 'object') {
+ settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]);
+ }
+
+ function onRequestFallback(args) {
+ console.warn('Falling back to CPU');
+ const fallbackKernel = new CPUKernel(source, {
+ argumentTypes: kernelRun.argumentTypes,
+ constantTypes: kernelRun.constantTypes,
+ graphical: kernelRun.graphical,
+ loopMaxIterations: kernelRun.loopMaxIterations,
+ constants: kernelRun.constants,
+ dynamicOutput: kernelRun.dynamicOutput,
+ dynamicArgument: kernelRun.dynamicArguments,
+ output: kernelRun.output,
+ precision: kernelRun.precision,
+ pipeline: kernelRun.pipeline,
+ immutable: kernelRun.immutable,
+ optimizeFloatMemory: kernelRun.optimizeFloatMemory,
+ fixIntegerDivisionAccuracy: kernelRun.fixIntegerDivisionAccuracy,
+ functions: kernelRun.functions,
+ nativeFunctions: kernelRun.nativeFunctions,
+ injectedNative: kernelRun.injectedNative,
+ subKernels: kernelRun.subKernels,
+ strictIntegers: kernelRun.strictIntegers,
+ debug: kernelRun.debug,
+ });
+ fallbackKernel.build.apply(fallbackKernel, args);
+ const result = fallbackKernel.run.apply(fallbackKernel, args);
+ kernelRun.replaceKernel(fallbackKernel);
+ return result;
+ }
+
+ function onRequestSwitchKernel(reasons, args, _kernel) {
+ if (_kernel.debug) {
+ console.warn('Switching kernels');
+ }
+ let newOutput = null;
+ if (_kernel.signature && !switchableKernels[_kernel.signature]) {
+ switchableKernels[_kernel.signature] = _kernel;
+ }
+ if (_kernel.dynamicOutput) {
+ for (let i = reasons.length - 1; i >= 0; i--) {
+ const reason = reasons[i];
+ if (reason.type === 'outputPrecisionMismatch') {
+ newOutput = reason.needed;
+ }
+ }
+ }
+
+ const Constructor = _kernel.constructor;
+ const argumentTypes = Constructor.getArgumentTypes(_kernel, args);
+ const signature = Constructor.getSignature(_kernel, argumentTypes);
+ const existingKernel = switchableKernels[signature];
+ if (existingKernel) {
+ existingKernel.onActivate(_kernel);
+ return existingKernel;
+ }
+
+ const newKernel = switchableKernels[signature] = new Constructor(source, {
+ argumentTypes,
+ constantTypes: _kernel.constantTypes,
+ graphical: _kernel.graphical,
+ loopMaxIterations: _kernel.loopMaxIterations,
+ constants: _kernel.constants,
+ dynamicOutput: _kernel.dynamicOutput,
+ dynamicArgument: _kernel.dynamicArguments,
+ context: _kernel.context,
+ canvas: _kernel.canvas,
+ output: newOutput || _kernel.output,
+ precision: _kernel.precision,
+ pipeline: _kernel.pipeline,
+ immutable: _kernel.immutable,
+ optimizeFloatMemory: _kernel.optimizeFloatMemory,
+ fixIntegerDivisionAccuracy: _kernel.fixIntegerDivisionAccuracy,
+ functions: _kernel.functions,
+ nativeFunctions: _kernel.nativeFunctions,
+ injectedNative: _kernel.injectedNative,
+ subKernels: _kernel.subKernels,
+ strictIntegers: _kernel.strictIntegers,
+ debug: _kernel.debug,
+ gpu: _kernel.gpu,
+ validate,
+ returnType: _kernel.returnType,
+ tactic: _kernel.tactic,
+ onRequestFallback,
+ onRequestSwitchKernel,
+ texture: _kernel.texture,
+ mappedTextures: _kernel.mappedTextures,
+ drawBuffersMap: _kernel.drawBuffersMap,
+ });
+ newKernel.build.apply(newKernel, args);
+ kernelRun.replaceKernel(newKernel);
+ kernels.push(newKernel);
+ return newKernel;
+ }
+ const mergedSettings = Object.assign({
+ context: this.context,
+ canvas: this.canvas,
+ functions: this.functions,
+ nativeFunctions: this.nativeFunctions,
+ injectedNative: this.injectedNative,
+ gpu: this,
+ validate,
+ onRequestFallback,
+ onRequestSwitchKernel
+ }, settingsCopy);
+
+ const kernel = new this.Kernel(source, mergedSettings);
+ const kernelRun = kernelRunShortcut(kernel);
+
+ if (!this.canvas) {
+ this.canvas = kernel.canvas;
+ }
+
+ if (!this.context) {
+ this.context = kernel.context;
+ }
+
+ kernels.push(kernel);
+
+ return kernelRun;
+ }
+
+ createKernelMap() {
+ let fn;
+ let settings;
+ const argument2Type = typeof arguments[arguments.length - 2];
+ if (argument2Type === 'function' || argument2Type === 'string') {
+ fn = arguments[arguments.length - 2];
+ settings = arguments[arguments.length - 1];
+ } else {
+ fn = arguments[arguments.length - 1];
+ }
+
+ if (this.mode !== 'dev') {
+ if (!this.Kernel.isSupported || !this.Kernel.features.kernelMap) {
+ if (this.mode && kernelTypes.indexOf(this.mode) < 0) {
+ throw new Error(`kernelMap not supported on ${this.Kernel.name}`);
+ }
+ }
+ }
+
+ const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings);
+ if (settings && typeof settings.argumentTypes === 'object') {
+ settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]);
+ }
+
+ if (Array.isArray(arguments[0])) {
+ settingsCopy.subKernels = [];
+ const functions = arguments[0];
+ for (let i = 0; i < functions.length; i++) {
+ const source = functions[i].toString();
+ const name = utils.getFunctionNameFromString(source);
+ settingsCopy.subKernels.push({
+ name,
+ source,
+ property: i,
+ });
+ }
+ } else {
+ settingsCopy.subKernels = [];
+ const functions = arguments[0];
+ for (let p in functions) {
+ if (!functions.hasOwnProperty(p)) continue;
+ const source = functions[p].toString();
+ const name = utils.getFunctionNameFromString(source);
+ settingsCopy.subKernels.push({
+ name: name || p,
+ source,
+ property: p,
+ });
+ }
+ }
+ return this.createKernel(fn, settingsCopy);
+ }
+
+ combineKernels() {
+ const firstKernel = arguments[0];
+ const combinedKernel = arguments[arguments.length - 1];
+ if (firstKernel.kernel.constructor.mode === 'cpu') return combinedKernel;
+ const canvas = arguments[0].canvas;
+ const context = arguments[0].context;
+ const max = arguments.length - 1;
+ for (let i = 0; i < max; i++) {
+ arguments[i]
+ .setCanvas(canvas)
+ .setContext(context)
+ .setPipeline(true);
+ }
+
+ return function() {
+ const texture = combinedKernel.apply(this, arguments);
+ if (texture.toArray) {
+ return texture.toArray();
+ }
+ return texture;
+ };
+ }
+
+ setFunctions(functions) {
+ this.functions = functions;
+ return this;
+ }
+
+ setNativeFunctions(nativeFunctions) {
+ this.nativeFunctions = nativeFunctions;
+ return this;
+ }
+
+ addFunction(source, settings) {
+ this.functions.push({ source, settings });
+ return this;
+ }
+
+ addNativeFunction(name, source, settings) {
+ if (this.kernels.length > 0) {
+ throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.');
+ }
+ this.nativeFunctions.push(Object.assign({ name, source }, settings));
+ return this;
+ }
+
+ injectNative(source) {
+ this.injectedNative = source;
+ return this;
+ }
+
+ destroy() {
+ return new Promise((resolve, reject) => {
+ if (!this.kernels) {
+ resolve();
+ }
+ setTimeout(() => {
+ try {
+ for (let i = 0; i < this.kernels.length; i++) {
+ this.kernels[i].destroy(true);
+ }
+ let firstKernel = this.kernels[0];
+ if (firstKernel) {
+ if (firstKernel.kernel) {
+ firstKernel = firstKernel.kernel;
+ }
+ if (firstKernel.constructor.destroyContext) {
+ firstKernel.constructor.destroyContext(this.context);
+ }
+ }
+ } catch (e) {
+ reject(e);
+ }
+ resolve();
+ }, 0);
+ });
+ }
+}
+
+
+function upgradeDeprecatedCreateKernelSettings(settings) {
+ if (!settings) {
+ return {};
+ }
+ const upgradedSettings = Object.assign({}, settings);
+
+ if (settings.hasOwnProperty('floatOutput')) {
+ utils.warnDeprecated('setting', 'floatOutput', 'precision');
+ upgradedSettings.precision = settings.floatOutput ? 'single' : 'unsigned';
+ }
+ if (settings.hasOwnProperty('outputToTexture')) {
+ utils.warnDeprecated('setting', 'outputToTexture', 'pipeline');
+ upgradedSettings.pipeline = Boolean(settings.outputToTexture);
+ }
+ if (settings.hasOwnProperty('outputImmutable')) {
+ utils.warnDeprecated('setting', 'outputImmutable', 'immutable');
+ upgradedSettings.immutable = Boolean(settings.outputImmutable);
+ }
+ if (settings.hasOwnProperty('floatTextures')) {
+ utils.warnDeprecated('setting', 'floatTextures', 'optimizeFloatMemory');
+ upgradedSettings.optimizeFloatMemory = Boolean(settings.floatTextures);
+ }
+ return upgradedSettings;
+}
+
+module.exports = {
+ GPU,
+ kernelOrder,
+ kernelTypes
+};
+},{"./backend/cpu/kernel":7,"./backend/headless-gl/kernel":33,"./backend/kernel":35,"./backend/web-gl/kernel":69,"./backend/web-gl2/kernel":104,"./kernel-run-shortcut":110,"./utils":113,"gpu-mock.js":3}],108:[function(require,module,exports){
+const { GPU } = require('./gpu');
+const { alias } = require('./alias');
+const { utils } = require('./utils');
+const { Input, input } = require('./input');
+const { Texture } = require('./texture');
+const { FunctionBuilder } = require('./backend/function-builder');
+const { FunctionNode } = require('./backend/function-node');
+const { CPUFunctionNode } = require('./backend/cpu/function-node');
+const { CPUKernel } = require('./backend/cpu/kernel');
+
+const { HeadlessGLKernel } = require('./backend/headless-gl/kernel');
+
+const { WebGLFunctionNode } = require('./backend/web-gl/function-node');
+const { WebGLKernel } = require('./backend/web-gl/kernel');
+const { kernelValueMaps: webGLKernelValueMaps } = require('./backend/web-gl/kernel-value-maps');
+
+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 { GLKernel } = require('./backend/gl/kernel');
+
+const { Kernel } = require('./backend/kernel');
+
+const { FunctionTracer } = require('./backend/function-tracer');
+
+const mathRandom = require('./plugins/math-random-uniformly-distributed');
+
+module.exports = {
+ alias,
+ CPUFunctionNode,
+ CPUKernel,
+ GPU,
+ FunctionBuilder,
+ FunctionNode,
+ HeadlessGLKernel,
+ Input,
+ input,
+ Texture,
+ utils,
+
+ WebGL2FunctionNode,
+ WebGL2Kernel,
+ webGL2KernelValueMaps,
+
+ WebGLFunctionNode,
+ WebGLKernel,
+ webGLKernelValueMaps,
+
+ GLKernel,
+ Kernel,
+ FunctionTracer,
+
+ plugins: {
+ mathRandom
+ }
+};
+},{"./alias":4,"./backend/cpu/function-node":5,"./backend/cpu/kernel":7,"./backend/function-builder":8,"./backend/function-node":9,"./backend/function-tracer":10,"./backend/gl/kernel":12,"./backend/headless-gl/kernel":33,"./backend/kernel":35,"./backend/web-gl/function-node":37,"./backend/web-gl/kernel":69,"./backend/web-gl/kernel-value-maps":38,"./backend/web-gl2/function-node":72,"./backend/web-gl2/kernel":104,"./backend/web-gl2/kernel-value-maps":73,"./gpu":107,"./input":109,"./plugins/math-random-uniformly-distributed":111,"./texture":112,"./utils":113}],109:[function(require,module,exports){
+class Input {
+ constructor(value, size) {
+ this.value = value;
+ if (Array.isArray(size)) {
+ this.size = size;
+ } else {
+ this.size = new Int32Array(3);
+ if (size.z) {
+ this.size = new Int32Array([size.x, size.y, size.z]);
+ } else if (size.y) {
+ this.size = new Int32Array([size.x, size.y]);
+ } else {
+ this.size = new Int32Array([size.x]);
+ }
+ }
+
+ const [w, h, d] = this.size;
+ if (d) {
+ if (this.value.length !== (w * h * d)) {
+ throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} * ${d} = ${(h * w * d)}`);
+ }
+ } else if (h) {
+ if (this.value.length !== (w * h)) {
+ throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} = ${(h * w)}`);
+ }
+ } else {
+ if (this.value.length !== w) {
+ throw new Error(`Input size ${this.value.length} does not match ${w}`);
+ }
+ }
+
+ }
+
+ toArray() {
+ const { utils } = require('./utils');
+ const [w, h, d] = this.size;
+ if (d) {
+ return utils.erectMemoryOptimized3DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h, d);
+ } else if (h) {
+ return utils.erectMemoryOptimized2DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h);
+ } else {
+ return this.value;
+ }
+ }
+}
+
+function input(value, size) {
+ return new Input(value, size);
+}
+
+module.exports = {
+ Input,
+ input
+};
+},{"./utils":113}],110:[function(require,module,exports){
+const { 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
+};
+},{"./utils":113}],111:[function(require,module,exports){
+const source = `// https://www.shadertoy.com/view/4t2SDh
+//note: uniformly distributed, normalized rand, [0,1]
+highp float randomSeedShift = 1.0;
+highp float slide = 1.0;
+uniform highp float randomSeed1;
+uniform highp float randomSeed2;
+
+highp float nrand(highp vec2 n) {
+ highp float result = fract(sin(dot((n.xy + 1.0) * vec2(randomSeed1 * slide, randomSeed2 * randomSeedShift), vec2(12.9898, 78.233))) * 43758.5453);
+ randomSeedShift = result;
+ if (randomSeedShift > 0.5) {
+ slide += 0.00009;
+ } else {
+ slide += 0.0009;
+ }
+ return result;
+}`;
+
+const name = 'math-random-uniformly-distributed';
+
+const functionMatch = `Math.random()`;
+
+const functionReplace = `nrand(vTexCoord)`;
+
+const functionReturnType = 'Number';
+const onBeforeRun = (kernel) => {
+ kernel.setUniform1f('randomSeed1', Math.random());
+ kernel.setUniform1f('randomSeed2', Math.random());
+};
+
+const plugin = {
+ name,
+ onBeforeRun,
+ functionMatch,
+ functionReplace,
+ functionReturnType,
+ source
+};
+
+module.exports = plugin;
+},{}],112:[function(require,module,exports){
+class Texture {
+ constructor(settings) {
+ const {
+ texture,
+ size,
+ dimensions,
+ output,
+ context,
+ type = 'NumberTexture',
+ kernel,
+ internalFormat,
+ textureFormat
+ } = settings;
+ if (!output) throw new Error('settings property "output" required.');
+ if (!context) throw new Error('settings property "context" required.');
+ if (!texture) throw new Error('settings property "texture" required.');
+ if (!kernel) throw new Error('settings property "kernel" required.');
+ this.texture = texture;
+ if (texture._refs) {
+ texture._refs++;
+ } else {
+ texture._refs = 1;
+ }
+ this.size = size;
+ this.dimensions = dimensions;
+ this.output = output;
+ this.context = context;
+ this.kernel = kernel;
+ this.type = type;
+ this._deleted = false;
+ this.internalFormat = internalFormat;
+ this.textureFormat = textureFormat;
+ }
+
+ 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}`);
+ }
+}
+
+module.exports = {
+ Texture
+};
+},{}],113:[function(require,module,exports){
+const acorn = require('acorn');
+const { Input } = require('./input');
+const { Texture } = require('./texture');
+
+const FUNCTION_NAME = /function ([^(]*)/;
+const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
+const ARGUMENT_NAMES = /([^\s,]+)/g;
+
+const utils = {
+ systemEndianness() {
+ return _systemEndianness;
+ },
+ getSystemEndianness() {
+ const b = new ArrayBuffer(4);
+ const a = new Uint32Array(b);
+ const c = new Uint8Array(b);
+ a[0] = 0xdeadbeef;
+ if (c[0] === 0xef) return 'LE';
+ if (c[0] === 0xde) return 'BE';
+ throw new Error('unknown endianness');
+ },
+
+ isFunction(funcObj) {
+ return typeof(funcObj) === 'function';
+ },
+
+ isFunctionString(fn) {
+ if (typeof fn === 'string') {
+ return (fn
+ .slice(0, 'function'.length)
+ .toLowerCase() === 'function');
+ }
+ return false;
+ },
+
+ getFunctionNameFromString(funcStr) {
+ const result = FUNCTION_NAME.exec(funcStr);
+ if (!result || result.length === 0) return null;
+ return result[1].trim();
+ },
+
+ getFunctionBodyFromString(funcStr) {
+ return funcStr.substring(funcStr.indexOf('{') + 1, funcStr.lastIndexOf('}'));
+ },
+
+ getArgumentNamesFromString(fn) {
+ const fnStr = fn.replace(STRIP_COMMENTS, '');
+ let result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
+ if (result === null) {
+ result = [];
+ }
+ return result;
+ },
+
+ clone(obj) {
+ if (obj === null || typeof obj !== 'object' || obj.hasOwnProperty('isActiveClone')) return obj;
+
+ const temp = obj.constructor();
+
+ for (let key in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
+ obj.isActiveClone = null;
+ temp[key] = utils.clone(obj[key]);
+ delete obj.isActiveClone;
+ }
+ }
+
+ return temp;
+ },
+
+ isArray(array) {
+ return !isNaN(array.length);
+ },
+
+ getVariableType(value, strictIntegers) {
+ if (utils.isArray(value)) {
+ if (value.length > 0 && value[0].nodeName === 'IMG') {
+ return 'HTMLImageArray';
+ }
+ return 'Array';
+ }
+
+ switch (value.constructor) {
+ case Boolean:
+ return 'Boolean';
+ case Number:
+ if (strictIntegers && Number.isInteger(value)) {
+ return 'Integer';
+ }
+ return 'Float';
+ case Texture:
+ return value.type;
+ case Input:
+ return 'Input';
+ }
+ if ('nodeName' in value) {
+ switch (value.nodeName) {
+ case 'IMG':
+ return 'HTMLImage';
+ case 'CANVAS':
+ return 'HTMLImage';
+ case 'VIDEO':
+ return 'HTMLVideo';
+ }
+ } else if (value.hasOwnProperty('type')) {
+ return value.type;
+ } else if (typeof OffscreenCanvas !== 'undefined' && value instanceof OffscreenCanvas) {
+ return 'OffscreenCanvas';
+ } else if (typeof ImageBitmap !== 'undefined' && value instanceof ImageBitmap) {
+ return 'ImageBitmap';
+ } else if (typeof ImageData !== 'undefined' && value instanceof ImageData) {
+ return 'ImageData';
+ }
+ return 'Unknown';
+ },
+
+ getKernelTextureSize(settings, dimensions) {
+ let [w, h, d] = dimensions;
+ let texelCount = (w || 1) * (h || 1) * (d || 1);
+
+ if (settings.optimizeFloatMemory && settings.precision === 'single') {
+ w = texelCount = Math.ceil(texelCount / 4);
+ }
+ if (h > 1 && w * h === texelCount) {
+ return new Int32Array([w, h]);
+ }
+ return utils.closestSquareDimensions(texelCount);
+ },
+
+ closestSquareDimensions(length) {
+ const sqrt = Math.sqrt(length);
+ let high = Math.ceil(sqrt);
+ let low = Math.floor(sqrt);
+ while (high * low < length) {
+ high--;
+ low = Math.ceil(length / high);
+ }
+ return new Int32Array([low, Math.ceil(length / low)]);
+ },
+
+ getMemoryOptimizedFloatTextureSize(dimensions, bitRatio) {
+ const totalArea = utils.roundTo((dimensions[0] || 1) * (dimensions[1] || 1) * (dimensions[2] || 1) * (dimensions[3] || 1), 4);
+ const texelCount = totalArea / bitRatio;
+ return utils.closestSquareDimensions(texelCount);
+ },
+
+ getMemoryOptimizedPackedTextureSize(dimensions, bitRatio) {
+ const [w, h, d] = dimensions;
+ const totalArea = utils.roundTo((w || 1) * (h || 1) * (d || 1), 4);
+ const texelCount = totalArea / (4 / bitRatio);
+ return utils.closestSquareDimensions(texelCount);
+ },
+
+ roundTo(n, d) {
+ return Math.floor((n + d - 1) / d) * d;
+ },
+ getDimensions(x, pad) {
+ let ret;
+ if (utils.isArray(x)) {
+ const dim = [];
+ let temp = x;
+ while (utils.isArray(temp)) {
+ dim.push(temp.length);
+ temp = temp[0];
+ }
+ ret = dim.reverse();
+ } else if (x instanceof Texture) {
+ ret = x.output;
+ } else if (x instanceof Input) {
+ ret = x.size;
+ } else {
+ throw new Error(`Unknown dimensions of ${x}`);
+ }
+
+ if (pad) {
+ ret = Array.from(ret);
+ while (ret.length < 3) {
+ ret.push(1);
+ }
+ }
+
+ return new Int32Array(ret);
+ },
+
+ flatten2dArrayTo(array, target) {
+ let offset = 0;
+ for (let y = 0; y < array.length; y++) {
+ target.set(array[y], offset);
+ offset += array[y].length;
+ }
+ },
+
+ flatten3dArrayTo(array, target) {
+ let offset = 0;
+ for (let z = 0; z < array.length; z++) {
+ for (let y = 0; y < array[z].length; y++) {
+ target.set(array[z][y], offset);
+ offset += array[z][y].length;
+ }
+ }
+ },
+
+ flatten4dArrayTo(array, target) {
+ let offset = 0;
+ for (let l = 0; l < array.length; l++) {
+ for (let z = 0; z < array[l].length; z++) {
+ for (let y = 0; y < array[l][z].length; y++) {
+ target.set(array[l][z][y], offset);
+ offset += array[l][z][y].length;
+ }
+ }
+ }
+ },
+
+ flattenTo(array, target) {
+ if (utils.isArray(array[0])) {
+ if (utils.isArray(array[0][0])) {
+ if (utils.isArray(array[0][0][0])) {
+ utils.flatten4dArrayTo(array, target);
+ } else {
+ utils.flatten3dArrayTo(array, target);
+ }
+ } else {
+ utils.flatten2dArrayTo(array, target);
+ }
+ } else {
+ target.set(array);
+ }
+ },
+
+ splitArray(array, part) {
+ const result = [];
+ for (let i = 0; i < array.length; i += part) {
+ result.push(new array.constructor(array.buffer, i * 4 + array.byteOffset, part));
+ }
+ return result;
+ },
+
+ getAstString(source, ast) {
+ const lines = Array.isArray(source) ? source : source.split(/\r?\n/g);
+ const start = ast.loc.start;
+ const end = ast.loc.end;
+ const result = [];
+ if (start.line === end.line) {
+ result.push(lines[start.line - 1].substring(start.column, end.column));
+ } else {
+ result.push(lines[start.line - 1].slice(start.column));
+ for (let i = start.line; i < end.line; i++) {
+ result.push(lines[i]);
+ }
+ result.push(lines[end.line - 1].slice(0, end.column));
+ }
+ return result.join('\n');
+ },
+
+ allPropertiesOf(obj) {
+ const props = [];
+
+ do {
+ props.push.apply(props, Object.getOwnPropertyNames(obj));
+ } while (obj = Object.getPrototypeOf(obj));
+
+ return props;
+ },
+
+ linesToString(lines) {
+ if (lines.length > 0) {
+ return lines.join(';\n') + ';\n';
+ } else {
+ return '\n';
+ }
+ },
+ warnDeprecated(type, oldName, newName) {
+ if (newName) {
+ console.warn(`You are using a deprecated ${ type } "${ oldName }". It has been replaced with "${ newName }". Fixing, but please upgrade as it will soon be removed.`);
+ } else {
+ console.warn(`You are using a deprecated ${ type } "${ oldName }". It has been removed. Fixing, but please upgrade as it will soon be removed.`);
+ }
+ },
+ flipPixels: (pixels, width, height) => {
+ const halfHeight = height / 2 | 0;
+ const bytesPerRow = width * 4;
+ const temp = new Uint8ClampedArray(width * 4);
+ const result = pixels.slice(0);
+ for (let y = 0; y < halfHeight; ++y) {
+ const topOffset = y * bytesPerRow;
+ const bottomOffset = (height - y - 1) * bytesPerRow;
+
+ temp.set(result.subarray(topOffset, topOffset + bytesPerRow));
+
+ result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow);
+
+ result.set(temp, bottomOffset);
+ }
+ return result;
+ },
+ erectPackedFloat: (array, width) => {
+ return array.subarray(0, width);
+ },
+ erect2DPackedFloat: (array, width, height) => {
+ const yResults = new Array(height);
+ for (let y = 0; y < height; y++) {
+ const xStart = y * width;
+ const xEnd = xStart + width;
+ yResults[y] = array.subarray(xStart, xEnd);
+ }
+ return yResults;
+ },
+ erect3DPackedFloat: (array, width, height, depth) => {
+ const zResults = new Array(depth);
+ for (let z = 0; z < depth; z++) {
+ const yResults = new Array(height);
+ for (let y = 0; y < height; y++) {
+ const xStart = (z * height * width) + y * width;
+ const xEnd = xStart + width;
+ yResults[y] = array.subarray(xStart, xEnd);
+ }
+ zResults[z] = yResults;
+ }
+ return zResults;
+ },
+ erectMemoryOptimizedFloat: (array, width) => {
+ return array.subarray(0, width);
+ },
+ erectMemoryOptimized2DFloat: (array, width, height) => {
+ const yResults = new Array(height);
+ for (let y = 0; y < height; y++) {
+ const offset = y * width;
+ yResults[y] = array.subarray(offset, offset + width);
+ }
+ return yResults;
+ },
+ erectMemoryOptimized3DFloat: (array, width, height, depth) => {
+ const zResults = new Array(depth);
+ for (let z = 0; z < depth; z++) {
+ const yResults = new Array(height);
+ for (let y = 0; y < height; y++) {
+ const offset = (z * height * width) + (y * width);
+ yResults[y] = array.subarray(offset, offset + width);
+ }
+ zResults[z] = yResults;
+ }
+ return zResults;
+ },
+ erectFloat: (array, width) => {
+ const xResults = new Float32Array(width);
+ let i = 0;
+ for (let x = 0; x < width; x++) {
+ xResults[x] = array[i];
+ i += 4;
+ }
+ return xResults;
+ },
+ erect2DFloat: (array, width, height) => {
+ const yResults = new Array(height);
+ let i = 0;
+ for (let y = 0; y < height; y++) {
+ const xResults = new Float32Array(width);
+ for (let x = 0; x < width; x++) {
+ xResults[x] = array[i];
+ i += 4;
+ }
+ yResults[y] = xResults;
+ }
+ return yResults;
+ },
+ erect3DFloat: (array, width, height, depth) => {
+ const zResults = new Array(depth);
+ let i = 0;
+ for (let z = 0; z < depth; z++) {
+ const yResults = new Array(height);
+ for (let y = 0; y < height; y++) {
+ const xResults = new Float32Array(width);
+ for (let x = 0; x < width; x++) {
+ xResults[x] = array[i];
+ i += 4;
+ }
+ yResults[y] = xResults;
+ }
+ zResults[z] = yResults;
+ }
+ return zResults;
+ },
+ erectArray2: (array, width) => {
+ const xResults = new Array(width);
+ const xResultsMax = width * 4;
+ let i = 0;
+ for (let x = 0; x < xResultsMax; x += 4) {
+ xResults[i++] = array.subarray(x, x + 2);
+ }
+ return xResults;
+ },
+ erect2DArray2: (array, width, height) => {
+ const yResults = new Array(height);
+ const XResultsMax = width * 4;
+ for (let y = 0; y < height; y++) {
+ const xResults = new Array(width);
+ const offset = y * XResultsMax;
+ let i = 0;
+ for (let x = 0; x < XResultsMax; x += 4) {
+ xResults[i++] = array.subarray(x + offset, x + offset + 2);
+ }
+ yResults[y] = xResults;
+ }
+ return yResults;
+ },
+ erect3DArray2: (array, width, height, depth) => {
+ const xResultsMax = width * 4;
+ const zResults = new Array(depth);
+ for (let z = 0; z < depth; z++) {
+ const yResults = new Array(height);
+ for (let y = 0; y < height; y++) {
+ const xResults = new Array(width);
+ const offset = (z * xResultsMax * height) + (y * xResultsMax);
+ let i = 0;
+ for (let x = 0; x < xResultsMax; x += 4) {
+ xResults[i++] = array.subarray(x + offset, x + offset + 2);
+ }
+ yResults[y] = xResults;
+ }
+ zResults[z] = yResults;
+ }
+ return zResults;
+ },
+ erectArray3: (array, width) => {
+ const xResults = new Array(width);
+ const xResultsMax = width * 4;
+ let i = 0;
+ for (let x = 0; x < xResultsMax; x += 4) {
+ xResults[i++] = array.subarray(x, x + 3);
+ }
+ return xResults;
+ },
+ erect2DArray3: (array, width, height) => {
+ const xResultsMax = width * 4;
+ const yResults = new Array(height);
+ for (let y = 0; y < height; y++) {
+ const xResults = new Array(width);
+ const offset = y * xResultsMax;
+ let i = 0;
+ for (let x = 0; x < xResultsMax; x += 4) {
+ xResults[i++] = array.subarray(x + offset, x + offset + 3);
+ }
+ yResults[y] = xResults;
+ }
+ return yResults;
+ },
+ erect3DArray3: (array, width, height, depth) => {
+ const xResultsMax = width * 4;
+ const zResults = new Array(depth);
+ for (let z = 0; z < depth; z++) {
+ const yResults = new Array(height);
+ for (let y = 0; y < height; y++) {
+ const xResults = new Array(width);
+ const offset = (z * xResultsMax * height) + (y * xResultsMax);
+ let i = 0;
+ for (let x = 0; x < xResultsMax; x += 4) {
+ xResults[i++] = array.subarray(x + offset, x + offset + 3);
+ }
+ yResults[y] = xResults;
+ }
+ zResults[z] = yResults;
+ }
+ return zResults;
+ },
+ erectArray4: (array, width) => {
+ const xResults = new Array(array);
+ const xResultsMax = width * 4;
+ let i = 0;
+ for (let x = 0; x < xResultsMax; x += 4) {
+ xResults[i++] = array.subarray(x, x + 4);
+ }
+ return xResults;
+ },
+ erect2DArray4: (array, width, height) => {
+ const xResultsMax = width * 4;
+ const yResults = new Array(height);
+ for (let y = 0; y < height; y++) {
+ const xResults = new Array(width);
+ const offset = y * xResultsMax;
+ let i = 0;
+ for (let x = 0; x < xResultsMax; x += 4) {
+ xResults[i++] = array.subarray(x + offset, x + offset + 4);
+ }
+ yResults[y] = xResults;
+ }
+ return yResults;
+ },
+ erect3DArray4: (array, width, height, depth) => {
+ const xResultsMax = width * 4;
+ const zResults = new Array(depth);
+ for (let z = 0; z < depth; z++) {
+ const yResults = new Array(height);
+ for (let y = 0; y < height; y++) {
+ const xResults = new Array(width);
+ const offset = (z * xResultsMax * height) + (y * xResultsMax);
+ let i = 0;
+ for (let x = 0; x < xResultsMax; x += 4) {
+ xResults[i++] = array.subarray(x + offset, x + offset + 4);
+ }
+ yResults[y] = xResults;
+ }
+ zResults[z] = yResults;
+ }
+ return zResults;
+ },
+
+ flattenFunctionToString: (source, settings) => {
+ const { findDependency, thisLookup, doNotDefine } = settings;
+ let flattened = settings.flattened;
+ if (!flattened) {
+ flattened = settings.flattened = {};
+ }
+ const ast = acorn.parse(source);
+ const functionDependencies = [];
+ let indent = 0;
+
+ function flatten(ast) {
+ if (Array.isArray(ast)) {
+ const results = [];
+ for (let i = 0; i < ast.length; i++) {
+ results.push(flatten(ast[i]));
+ }
+ return results.join('');
+ }
+ switch (ast.type) {
+ case 'Program':
+ return flatten(ast.body) + (ast.body[0].type === 'VariableDeclaration' ? ';' : '');
+ case 'FunctionDeclaration':
+ return `function ${ast.id.name}(${ast.params.map(flatten).join(', ')}) ${ flatten(ast.body) }`;
+ case 'BlockStatement': {
+ const result = [];
+ indent += 2;
+ for (let i = 0; i < ast.body.length; i++) {
+ const flat = flatten(ast.body[i]);
+ if (flat) {
+ result.push(' '.repeat(indent) + flat, ';\n');
+ }
+ }
+ indent -= 2;
+ return `{\n${result.join('')}}`;
+ }
+ case 'VariableDeclaration':
+ const declarations = utils.normalizeDeclarations(ast)
+ .map(flatten)
+ .filter(r => r !== null);
+ if (declarations.length < 1) {
+ return '';
+ } else {
+ return `${ast.kind} ${declarations.join(',')}`;
+ }
+ case 'VariableDeclarator':
+ if (ast.init.object && ast.init.object.type === 'ThisExpression') {
+ const lookup = thisLookup(ast.init.property.name, true);
+ if (lookup) {
+ return `${ast.id.name} = ${flatten(ast.init)}`;
+ } else {
+ return null;
+ }
+ } else {
+ return `${ast.id.name} = ${flatten(ast.init)}`;
+ }
+ case 'CallExpression': {
+ if (ast.callee.property.name === 'subarray') {
+ return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`;
+ }
+ if (ast.callee.object.name === 'gl' || ast.callee.object.name === 'context') {
+ return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`;
+ }
+ if (ast.callee.object.type === 'ThisExpression') {
+ functionDependencies.push(findDependency('this', ast.callee.property.name));
+ return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;
+ } else if (ast.callee.object.name) {
+ const foundSource = findDependency(ast.callee.object.name, ast.callee.property.name);
+ if (foundSource === null) {
+ return `${ast.callee.object.name}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;
+ } else {
+ functionDependencies.push(foundSource);
+ return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;
+ }
+ } else if (ast.callee.object.type === 'MemberExpression') {
+ return `${flatten(ast.callee.object)}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;
+ } else {
+ throw new Error('unknown ast.callee');
+ }
+ }
+ case 'ReturnStatement':
+ return `return ${flatten(ast.argument)}`;
+ case 'BinaryExpression':
+ return `(${flatten(ast.left)}${ast.operator}${flatten(ast.right)})`;
+ case 'UnaryExpression':
+ if (ast.prefix) {
+ return `${ast.operator} ${flatten(ast.argument)}`;
+ } else {
+ return `${flatten(ast.argument)} ${ast.operator}`;
+ }
+ case 'ExpressionStatement':
+ return `${flatten(ast.expression)}`;
+ case 'SequenceExpression':
+ return `(${flatten(ast.expressions)})`;
+ case 'ArrowFunctionExpression':
+ return `(${ast.params.map(flatten).join(', ')}) => ${flatten(ast.body)}`;
+ case 'Literal':
+ return ast.raw;
+ case 'Identifier':
+ return ast.name;
+ case 'MemberExpression':
+ if (ast.object.type === 'ThisExpression') {
+ return thisLookup(ast.property.name);
+ }
+ if (ast.computed) {
+ return `${flatten(ast.object)}[${flatten(ast.property)}]`;
+ }
+ return flatten(ast.object) + '.' + flatten(ast.property);
+ case 'ThisExpression':
+ return 'this';
+ case 'NewExpression':
+ return `new ${flatten(ast.callee)}(${ast.arguments.map(value => flatten(value)).join(', ')})`;
+ case 'ForStatement':
+ return `for (${flatten(ast.init)};${flatten(ast.test)};${flatten(ast.update)}) ${flatten(ast.body)}`;
+ case 'AssignmentExpression':
+ return `${flatten(ast.left)}${ast.operator}${flatten(ast.right)}`;
+ case 'UpdateExpression':
+ return `${flatten(ast.argument)}${ast.operator}`;
+ case 'IfStatement':
+ return `if (${flatten(ast.test)}) ${flatten(ast.consequent)}`;
+ case 'ThrowStatement':
+ return `throw ${flatten(ast.argument)}`;
+ case 'ObjectPattern':
+ return ast.properties.map(flatten).join(', ');
+ case 'ArrayPattern':
+ return ast.elements.map(flatten).join(', ');
+ case 'DebuggerStatement':
+ return 'debugger;';
+ case 'ConditionalExpression':
+ return `${flatten(ast.test)}?${flatten(ast.consequent)}:${flatten(ast.alternate)}`;
+ case 'Property':
+ if (ast.kind === 'init') {
+ return flatten(ast.key);
+ }
+ }
+ throw new Error(`unhandled ast.type of ${ ast.type }`);
+ }
+ const result = flatten(ast);
+ if (functionDependencies.length > 0) {
+ const flattenedFunctionDependencies = [];
+ for (let i = 0; i < functionDependencies.length; i++) {
+ const functionDependency = functionDependencies[i];
+ if (!flattened[functionDependency]) {
+ flattened[functionDependency] = true;
+ }
+ functionDependency ? flattenedFunctionDependencies.push(utils.flattenFunctionToString(functionDependency, settings) + '\n') : '';
+ }
+ return flattenedFunctionDependencies.join('') + result;
+ }
+ return result;
+ },
+
+ normalizeDeclarations: (ast) => {
+ if (ast.type !== 'VariableDeclaration') throw new Error('Ast is not of type "VariableDeclaration"');
+ const normalizedDeclarations = [];
+ for (let declarationIndex = 0; declarationIndex < ast.declarations.length; declarationIndex++) {
+ const declaration = ast.declarations[declarationIndex];
+ if (declaration.id && declaration.id.type === 'ObjectPattern' && declaration.id.properties) {
+ const { properties } = declaration.id;
+ for (let propertyIndex = 0; propertyIndex < properties.length; propertyIndex++) {
+ const property = properties[propertyIndex];
+ if (property.value.type === 'ObjectPattern' && property.value.properties) {
+ for (let subPropertyIndex = 0; subPropertyIndex < property.value.properties.length; subPropertyIndex++) {
+ const subProperty = property.value.properties[subPropertyIndex];
+ if (subProperty.type === 'Property') {
+ normalizedDeclarations.push({
+ type: 'VariableDeclarator',
+ id: {
+ type: 'Identifier',
+ name: subProperty.key.name
+ },
+ init: {
+ type: 'MemberExpression',
+ object: {
+ type: 'MemberExpression',
+ object: declaration.init,
+ property: {
+ type: 'Identifier',
+ name: property.key.name
+ },
+ computed: false
+ },
+ property: {
+ type: 'Identifier',
+ name: subProperty.key.name
+ },
+ computed: false
+ }
+ });
+ } else {
+ throw new Error('unexpected state');
+ }
+ }
+ } else if (property.value.type === 'Identifier') {
+ normalizedDeclarations.push({
+ type: 'VariableDeclarator',
+ id: {
+ type: 'Identifier',
+ name: property.value && property.value.name ? property.value.name : property.key.name
+ },
+ init: {
+ type: 'MemberExpression',
+ object: declaration.init,
+ property: {
+ type: 'Identifier',
+ name: property.key.name
+ },
+ computed: false
+ }
+ });
+ } else {
+ throw new Error('unexpected state');
+ }
+ }
+ } else if (declaration.id && declaration.id.type === 'ArrayPattern' && declaration.id.elements) {
+ const { elements } = declaration.id;
+ for (let elementIndex = 0; elementIndex < elements.length; elementIndex++) {
+ const element = elements[elementIndex];
+ if (element.type === 'Identifier') {
+ normalizedDeclarations.push({
+ type: 'VariableDeclarator',
+ id: {
+ type: 'Identifier',
+ name: element.name
+ },
+ init: {
+ type: 'MemberExpression',
+ object: declaration.init,
+ property: {
+ type: 'Literal',
+ value: elementIndex,
+ raw: elementIndex.toString(),
+ start: element.start,
+ end: element.end
+ },
+ computed: true
+ }
+ });
+ } else {
+ throw new Error('unexpected state');
+ }
+ }
+ } else {
+ normalizedDeclarations.push(declaration);
+ }
+ }
+ return normalizedDeclarations;
+ },
+
+ splitHTMLImageToRGB: (gpu, image) => {
+ const rKernel = gpu.createKernel(function(a) {
+ const pixel = a[this.thread.y][this.thread.x];
+ return pixel.r * 255;
+ }, {
+ output: [image.width, image.height],
+ precision: 'unsigned',
+ argumentTypes: { a: 'HTMLImage' },
+ });
+ const gKernel = gpu.createKernel(function(a) {
+ const pixel = a[this.thread.y][this.thread.x];
+ return pixel.g * 255;
+ }, {
+ output: [image.width, image.height],
+ precision: 'unsigned',
+ argumentTypes: { a: 'HTMLImage' },
+ });
+ const bKernel = gpu.createKernel(function(a) {
+ const pixel = a[this.thread.y][this.thread.x];
+ return pixel.b * 255;
+ }, {
+ output: [image.width, image.height],
+ precision: 'unsigned',
+ argumentTypes: { a: 'HTMLImage' },
+ });
+ const aKernel = gpu.createKernel(function(a) {
+ const pixel = a[this.thread.y][this.thread.x];
+ return pixel.a * 255;
+ }, {
+ output: [image.width, image.height],
+ precision: 'unsigned',
+ argumentTypes: { a: 'HTMLImage' },
+ });
+ const result = [
+ rKernel(image),
+ gKernel(image),
+ bKernel(image),
+ aKernel(image),
+ ];
+ result.rKernel = rKernel;
+ result.gKernel = gKernel;
+ result.bKernel = bKernel;
+ result.aKernel = aKernel;
+ result.gpu = gpu;
+ return result;
+ },
+
+ splitRGBAToCanvases: (gpu, rgba, width, height) => {
+ const visualKernelR = gpu.createKernel(function(v) {
+ const pixel = v[this.thread.y][this.thread.x];
+ this.color(pixel.r / 255, 0, 0, 255);
+ }, {
+ output: [width, height],
+ graphical: true,
+ argumentTypes: { v: 'Array2D(4)' }
+ });
+ visualKernelR(rgba);
+
+ const visualKernelG = gpu.createKernel(function(v) {
+ const pixel = v[this.thread.y][this.thread.x];
+ this.color(0, pixel.g / 255, 0, 255);
+ }, {
+ output: [width, height],
+ graphical: true,
+ argumentTypes: { v: 'Array2D(4)' }
+ });
+ visualKernelG(rgba);
+
+ const visualKernelB = gpu.createKernel(function(v) {
+ const pixel = v[this.thread.y][this.thread.x];
+ this.color(0, 0, pixel.b / 255, 255);
+ }, {
+ output: [width, height],
+ graphical: true,
+ argumentTypes: { v: 'Array2D(4)' }
+ });
+ visualKernelB(rgba);
+
+ const visualKernelA = gpu.createKernel(function(v) {
+ const pixel = v[this.thread.y][this.thread.x];
+ this.color(255, 255, 255, pixel.a / 255);
+ }, {
+ output: [width, height],
+ graphical: true,
+ argumentTypes: { v: 'Array2D(4)' }
+ });
+ visualKernelA(rgba);
+ return [
+ visualKernelR.canvas,
+ visualKernelG.canvas,
+ visualKernelB.canvas,
+ visualKernelA.canvas,
+ ];
+ },
+
+ getMinifySafeName: (fn) => {
+ try {
+ const ast = acorn.parse(`const value = ${fn.toString()}`);
+ const { init } = ast.body[0].declarations[0];
+ return init.body.name || init.body.body[0].argument.name;
+ } catch (e) {
+ throw new Error('Unrecognized function type. Please use `() => yourFunctionVariableHere` or function() { return yourFunctionVariableHere; }');
+ }
+ },
+ sanitizeName: function(name) {
+ if (dollarSign.test(name)) {
+ name = name.replace(dollarSign, 'S_S');
+ }
+ if (doubleUnderscore.test(name)) {
+ name = name.replace(doubleUnderscore, 'U_U');
+ } else if (singleUnderscore.test(name)) {
+ name = name.replace(singleUnderscore, 'u_u');
+ }
+ return name;
+ }
+};
+
+const dollarSign = /\$/;
+const doubleUnderscore = /__/;
+const singleUnderscore = /_/;
+
+const _systemEndianness = utils.getSystemEndianness();
+
+module.exports = {
+ utils
+};
+},{"./input":109,"./texture":112,"acorn":1}]},{},[106])(106)
+});
diff --git a/dist/gpu-browser-core.min.js b/dist/gpu-browser-core.min.js
new file mode 100644
index 00000000..2394e607
--- /dev/null
+++ b/dist/gpu-browser-core.min.js
@@ -0,0 +1,28 @@
+/**
+ * gpu.js
+ * http://gpu.rocks/
+ *
+ * GPU Accelerated JavaScript
+ *
+ * @version 2.16.0
+ * @date Thu Feb 13 2025 11:46:49 GMT-0800 (Pacific Standard Time)
+ *
+ * @license MIT
+ * The MIT License
+ *
+ * Copyright (c) 2025 gpu.js Team
+ *//**
+ * gpu.js
+ * http://gpu.rocks/
+ *
+ * GPU Accelerated JavaScript
+ *
+ * @version 2.16.0
+ * @date Thu Feb 13 2025 11:46:48 GMT-0800 (Pacific Standard Time)
+ *
+ * @license MIT
+ * The MIT License
+ *
+ * Copyright (c) 2025 gpu.js Team
+ */
+!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).GPU=e()}}((function(){return function e(t,n,r){function i(a,o){if(!n[a]){if(!t[a]){var u="function"==typeof require&&require;if(!o&&u)return u(a,!0);if(s)return s(a,!0);var l=new Error("Cannot find module '"+a+"'");throw l.code="MODULE_NOT_FOUND",l}var c=n[a]={exports:{}};t[a][0].call(c.exports,(function(e){return i(t[a][1][e]||e)}),c,c.exports,e,t,n,r)}return n[a].exports}for(var s="function"==typeof require&&require,a=0;a0;)l.pop()}function A(e,t){c[e]=t}function S(e){const t=g[e];return t?n+"."+t:e}function v(e){y=" ".repeat(e)}function _(e,t){const r=`${n}Variable${m.length}`;return l.push(`${y}const ${r} = ${t};`),m.push(e),r}function E(e){l.push(`${y}// ${e}`)}function w(){l.push(`${y}(() => {\n${y}const error = ${n}.getError();\n${y}if (error !== ${n}.NONE) {\n${y} const names = Object.getOwnPropertyNames(gl);\n${y} for (let i = 0; i < names.length; i++) {\n${y} const name = names[i];\n${y} if (${n}[name] === error) {\n${y} throw new Error('${n} threw ' + name);\n${y} }\n${y} }\n${y}}\n${y}})();`)}function D(e,t){return`${n}.${e}(${s(t,{contextName:n,contextVariables:m,getEntity:S,addVariable:_,variables:c,onUnrecognizedArgumentLookup:p})})`}function $(e){const t=m.indexOf(e);return-1!==t?`${n}Variable${t}`:null}}function i(e,t){const n=new Proxy(e,{get:function(t,n){if("function"==typeof t[n])return function(){if("drawBuffersWEBGL"===n)return c.push(`${p}${i}.drawBuffersWEBGL([${s(arguments[0],{contextName:i,contextVariables:o,getEntity:m,addVariable:f,variables:h,onUnrecognizedArgumentLookup:d})}]);`),e.drawBuffersWEBGL(arguments[0]);let t=e[n].apply(e,arguments);switch(typeof t){case"undefined":return void c.push(`${p}${g(n,arguments)};`);case"number":case"boolean":l&&-1===o.indexOf(a(t))?(c.push(`${p}const ${i}Variable${o.length} = ${g(n,arguments)};`),o.push(t=a(t))):(c.push(`${p}const ${i}Variable${o.length} = ${g(n,arguments)};`),o.push(t));break;default:null===t?c.push(`${g(n,arguments)};`):c.push(`${p}const ${i}Variable${o.length} = ${g(n,arguments)};`),o.push(t)}return t};return r[e[n]]=n,e[n]}}),r={},{contextName:i,contextVariables:o,getEntity:u,useTrackablePrimitives:l,recording:c,variables:h,indent:p,onUnrecognizedArgumentLookup:d}=t;return n;function m(e){return r.hasOwnProperty(e)?`${i}.${r[e]}`:u(e)}function g(e,t){return`${i}.${e}(${s(t,{contextName:i,contextVariables:o,getEntity:m,addVariable:f,variables:h,onUnrecognizedArgumentLookup:d})})`}function f(e,t){const n=`${i}Variable${o.length}`;return o.push(e),c.push(`${p}const ${n} = ${t};`),n}}function s(e,t){const{variables:n,onUnrecognizedArgumentLookup:r}=t;return Array.from(e).map((e=>{const i=function(e){if(n)for(const t in n)if(n.hasOwnProperty(t)&&n[t]===e)return t;if(r)return r(e);return null}(e);return i||function(e,t){const{contextName:n,contextVariables:r,getEntity:i,addVariable:s,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 i(e);case"Array":return s(e,`new ${e.constructor.name}([${Array.from(e).join(",")}])`);case"Float32Array":case"Uint8Array":case"Uint16Array":case"Int32Array":return s(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 a(e){return new e.constructor(e)}void 0!==t&&(t.exports={glWiretap:r,glExtensionWiretap:i}),"undefined"!=typeof window&&(r.glExtensionWiretap=i,window.glWiretap=r)},{}],3:[function(e,t,n){function r(e){const t=new Array(e.length);for(let n=0;n{e.output=c(t),e.graphical&&l(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&&l(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,i=4*t,s=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;r0&&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(s.join("")),t.push(`\n${i.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);return this.astGeneric(e.left,t),t.push(e.operator),this.astGeneric(e.right,t),t}astBlockStatement(e,t){if(this.isState("loop-body")){this.pushState("block-body");for(let n=0;n0&&t.push(",");const r=n[e],i=this.getDeclaration(r.id);i.valueType||(i.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:i,xProperty:s,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(i){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 c=`${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(`${c}`),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(s,t),t.push("]")):(t.push("["),this.astGeneric(o,t),t.push("]"),t.push("["),this.astGeneric(a,t),t.push("]"),t.push("["),this.astGeneric(s,t),t.push("]")):a?n?(t.push("[("),this.astGeneric(a,t),t.push(`*${this.dynamicArguments?"outputX":e[0]})+`),this.astGeneric(s,t),t.push("]")):(t.push("["),this.astGeneric(a,t),t.push("]"),t.push("["),this.astGeneric(s,t),t.push("]")):void 0!==s&&(t.push("["),this.astGeneric(s,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 i=0;i0&&t.push(", "),this.astGeneric(s,t)}return t.push(")"),t}astArrayExpression(e,t){const n=this.getType(e),r=e.elements.length,i=[];for(let t=0;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});i.push(" _imageData,"," _colorData,",` color: ${t},`),s.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"}}});s.push(t),i.push(" _mediaTo2DArray,"),i.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")}});s.push(t),i.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({ ${i.join("\n")} });\n ${s.join("\n")}\n return kernel;\n}`}}},{"../../utils":113}],7:[function(e,t,n){const{Kernel:r}=e("../kernel"),{FunctionBuilder:i}=e("../function-builder"),{CPUFunctionNode:s}=e("./function-node"),{utils:a}=e("../../utils"),{cpuKernelString:o}=e("./kernel-string");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"):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=a.getVariableType(e[0],this.strictIntegers);if("Array"===t)this.output=a.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=i.fromKernel(this,s);this.translatedSources=e.getPrototypes("kernel"),this.graphical||this.returnType||(this.returnType=e.getKernelResultType())}build(){if(this.built)return;if(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 i=this.output[0],s=this.output[1],a=this.thread.x+(s-this.thread.y-1)*i;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 o(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${i?` || ${i}`:""}`)}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=i.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}}}},{"../../utils":113,"../function-builder":8,"../kernel":35,"./function-node":5,"./kernel-string":6}],8:[function(e,t,n){class r{static fromKernel(e,t,n){const{kernelArguments:i,kernelConstants:s,argumentNames:a,argumentSizes:o,argumentBitRatios:u,constants:l,constantBitRatios:c,debug:h,loopMaxIterations:p,nativeFunctions:d,output:m,optimizeFloatMemory:g,precision:f,plugins:x,source:y,subKernels:T,functions:b,leadingReturnStatement:A,followingReturnStatement:S,dynamicArguments:v,dynamicOutput:_}=e,E=new Array(i.length),w={};for(let e=0;eU.needsArgumentType(e,t),$=(e,t,n)=>{U.assignArgumentType(e,t,n)},I=(e,t,n)=>U.lookupReturnType(e,t,n),F=e=>U.lookupFunctionArgumentTypes(e),k=(e,t)=>U.lookupFunctionArgumentName(e,t),R=(e,t)=>U.lookupFunctionArgumentBitRatio(e,t),L=(e,t,n,r)=>{U.assignArgumentType(e,t,n,r)},z=(e,t,n,r)=>{U.assignArgumentBitRatio(e,t,n,r)},C=(e,t,n)=>{U.trackFunctionCall(e,t,n)},M=(e,n)=>{const r=[];for(let t=0;tnew t(e.source,{returnType:e.returnType,argumentTypes:e.argumentTypes,output:m,plugins:x,constants:l,constantTypes:w,constantBitRatios:c,optimizeFloatMemory:g,precision:f,lookupReturnType:I,lookupFunctionArgumentTypes:F,lookupFunctionArgumentName:k,lookupFunctionArgumentBitRatio:R,needsArgumentType:D,assignArgumentType:$,triggerImplyArgumentType:L,triggerImplyArgumentBitRatio:z,onFunctionCall:C,onNestedFunction:M}))));let G=null;T&&(G=T.map((e=>{const{name:n,source:r}=e;return new t(r,Object.assign({},N,{name:n,isSubKernel:!0,isRootKernel:!1}))})));const U=new r({kernel:e,rootNode:V,functionNodes:K,nativeFunctions:d,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[i].source);continue}const s=this.functionMap[r];s&&t.push(s.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 i=t.arguments;for(let t=0;t0&&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})),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:i,functionCalls:a}=new s(e);this.contexts=t,this.identifiers=i,this.functionCalls=a,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 a[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;e-1}isAstMathFunction(e){return"CallExpression"===e.type&&e.callee&&"MemberExpression"===e.callee.type&&e.callee.object&&"Identifier"===e.callee.object.type&&"Math"===e.callee.object.name&&e.callee.property&&"Identifier"===e.callee.property.type&&["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"].indexOf(e.callee.property.name)>-1}isAstVariable(e){return"Identifier"===e.type||"MemberExpression"===e.type}isSafe(e){return this.isSafeDependencies(this.getDependencies(e))}isSafeDependencies(e){return!e||!e.every||e.every((e=>e.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 i=this.getMemberExpressionDetails(e);switch(i.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:i.name,origin:"output",isSafe:!1})}if(i)return i.property&&this.getDependencies(i.property,t,n),i.xProperty&&this.getDependencies(i.xProperty,t,n),i.yProperty&&this.getDependencies(i.yProperty,t,n),i.zProperty&&this.getDependencies(i.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("");if(t)return r;return["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()[][][]","[][]"].indexOf(r)>-1?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 ${s.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;n0?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 i(this.functionContexts)}get currentContext(){return i(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=i(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,i=t[e]||n[e]||null;if(!i&&t===n&&r.length>0){const t=r[r.length-2];if(t[e])return t[e]}return i}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,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}"`)}}}}},{"../utils":113}],11:[function(e,t,n){const{glWiretap:r}=e("gl-wiretap"),{utils:i}=e("../../utils");function s(e){return e.toString().replace("=>","").replace(/^function /,"").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,n){const r=e.toArray.toString(),s=!/^function/.test(r);return`() => {\n function framebuffer() { return ${n}; };\n ${i.flattenFunctionToString(`${s?"function ":""}${r}`,{findDependency:(t,n)=>{if("utils"===t)return`const ${n} = ${i[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,i){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 i=0;i{switch(typeof e){case"boolean":return new Boolean(e);case"number":return new Number(e);default:return e}})):null;const h=[],p=[],d=r(n.context,{useTrackablePrimitives:!0,onReadPixels:e=>{if(C.subKernels){if(m){const t=C.subKernels[g++].property;p.push(` result${isNaN(t)?"."+t:`[${t}]`} = ${a(e,C)};`)}else p.push(` const result = { result: ${a(e,C)} };`),m=!0;g===C.subKernels.length&&p.push(" return result;")}else e?p.push(` return ${a(e,C)};`):p.push(" return null;")},onUnrecognizedArgumentLookup:e=>{const t=u(e,C.kernelArguments,[],d,h);if(t)return t;const n=u(e,C.kernelConstants,S?Object.keys(S).map((e=>S[e])):[],d,h);return n||null}});let m=!1,g=0;const{source:f,canvas:x,output:y,pipeline:T,graphical:b,loopMaxIterations:A,constants:S,optimizeFloatMemory:v,precision:_,fixIntegerDivisionAccuracy:E,functions:w,nativeFunctions:D,subKernels:$,immutable:I,argumentTypes:F,constantTypes:k,kernelArguments:R,kernelConstants:L,tactic:z}=n,C=new e(f,{canvas:x,context:d,checkContext:!1,output:y,pipeline:T,graphical:b,loopMaxIterations:A,constants:S,optimizeFloatMemory:v,precision:_,fixIntegerDivisionAccuracy:E,functions:w,nativeFunctions:D,subKernels:$,immutable:I,argumentTypes:F,constantTypes:k,tactic:z});let M=[];if(d.setIndent(2),C.build.apply(C,t),M.push(d.toString()),d.reset(),C.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":d.insertVariable(`uploadValue_${e.name}`,e.uploadValue);break;case"HTMLImageArray":for(let r=0;re.varName)).join(", ")}) {`),d.setIndent(4),C.run.apply(C,t),C.renderKernels?C.renderKernels():C.renderOutput&&C.renderOutput(),M.push(" /** start setup uploads for kernel values **/"),C.kernelArguments.forEach((e=>{M.push(" "+e.getStringValueHandler().split("\n").join("\n "))})),M.push(" /** end setup uploads for kernel values **/"),M.push(d.toString()),C.renderOutput===C.renderTexture){d.reset();const e=d.getContextVariableName(C.framebuffer);if(C.renderKernels){const t=C.renderKernels(),n=d.getContextVariableName(C.texture.texture);M.push(` return {\n result: {\n texture: ${n},\n type: '${t.result.type}',\n toArray: ${o(t.result,n,e)}\n },`);const{subKernels:r,mappedTextures:i}=C;for(let n=0;n"utils"===e?`const ${t} = ${i[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}`)}})}(C)),M.push(" innerKernel.getPixels = getPixels;")),M.push(" return innerKernel;");let N=[];return L.forEach((e=>{N.push(`${e.getStringValueHandler()}`)})),`function kernel(settings) {\n const { context, constants } = settings;\n ${N.join("")}\n ${l||""}\n${M.join("\n")}\n}`}}},{"../../utils":113,"gl-wiretap":2}],12:[function(e,t,n){const{Kernel:r}=e("../kernel"),{utils:i}=e("../../utils"),{GLTextureArray2Float:s}=e("./texture/array-2-float"),{GLTextureArray2Float2D:a}=e("./texture/array-2-float-2d"),{GLTextureArray2Float3D:o}=e("./texture/array-2-float-3d"),{GLTextureArray3Float:u}=e("./texture/array-3-float"),{GLTextureArray3Float2D:l}=e("./texture/array-3-float-2d"),{GLTextureArray3Float3D:c}=e("./texture/array-3-float-3d"),{GLTextureArray4Float:h}=e("./texture/array-4-float"),{GLTextureArray4Float2D:p}=e("./texture/array-4-float-2d"),{GLTextureArray4Float3D:d}=e("./texture/array-4-float-3d"),{GLTextureFloat:m}=e("./texture/float"),{GLTextureFloat2D:g}=e("./texture/float-2d"),{GLTextureFloat3D:f}=e("./texture/float-3d"),{GLTextureMemoryOptimized:x}=e("./texture/memory-optimized"),{GLTextureMemoryOptimized2D:y}=e("./texture/memory-optimized-2d"),{GLTextureMemoryOptimized3D:T}=e("./texture/memory-optimized-3d"),{GLTextureUnsigned:b}=e("./texture/unsigned"),{GLTextureUnsigned2D:A}=e("./texture/unsigned-2d"),{GLTextureUnsigned3D:S}=e("./texture/unsigned-3d"),{GLTextureGraphical:v}=e("./texture/graphical");const _={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 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 i.warnDeprecated("method","setFloatTextures","setOptimizeFloatMemory"),this.floatTextures=e,this}static nativeFunctionArguments(e){const t=[],n=[],r=[],i=/^[a-zA-Z_]/,s=/[a-zA-Z_0-9]/;let a=0,o=null,u=null;for(;a0?r[r.length-1]:null;if("FUNCTION_ARGUMENTS"!==h||"/"!==l||"*"!==c)if("MULTI_LINE_COMMENT"!==h||"*"!==l||"/"!==c)if("FUNCTION_ARGUMENTS"!==h||"/"!==l||"/"!==c)if("COMMENT"!==h||"\n"!==l)if(null!==h||"("!==l){if("FUNCTION_ARGUMENTS"===h){if(")"===l){r.pop();break}if("f"===l&&"l"===c&&"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"===c&&"t"===e[a+2]&&" "===e[a+3]){r.push("DECLARE_VARIABLE"),u="int",o="",a+=4;continue}if("v"===l&&"e"===c&&"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"===c&&"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"===c&&"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"===h){if(""===o){if(" "===l){a++;continue}if(!i.test(l))throw new Error("variable name is not expected string")}o+=l,s.test(c)||(r.pop(),n.push(o),t.push(_[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 _[e.match(/int|float|vec[2-4]/)[0]]}static combineKernels(e,t){e.apply(null,arguments);const{texSize:n,context:r,threadDim:s}=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),r.readPixels(0,0,e,4*t,r.RGBA,r.FLOAT,a)}else{const e=new Uint8Array(n[0]*n[1]*4);r.readPixels(0,0,n[0],n[1],r.RGBA,r.UNSIGNED_BYTE,e),a=new Float32Array(e.buffer)}if(a=a.subarray(0,s[0]*s[1]*s[2]),1===t.output.length)return a;if(2===t.output.length)return i.splitArray(a,t.output[0]);if(3===t.output.length){return i.splitArray(a,t.output[0]*t.output[1]).map((function(e){return i.splitArray(e,t.output[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=v,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=S,null):this.output[1]>0?(this.TextureConstructor=A,null):(this.TextureConstructor=b,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=S,this.formatValues=i.erect3DPackedFloat,null):this.output[1]>0?(this.TextureConstructor=A,this.formatValues=i.erect2DPackedFloat,null):(this.TextureConstructor=b,this.formatValues=i.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=T,null):this.output[1]>0?(this.TextureConstructor=y,null):(this.TextureConstructor=x,null):this.output[2]>0?(this.TextureConstructor=f,null):this.output[1]>0?(this.TextureConstructor=g,null):(this.TextureConstructor=m,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=o,null):this.output[1]>0?(this.TextureConstructor=a,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=u,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=d,null):this.output[1]>0?(this.TextureConstructor=p,null):(this.TextureConstructor=h,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=T,this.formatValues=i.erectMemoryOptimized3DFloat,null):this.output[1]>0?(this.TextureConstructor=y,this.formatValues=i.erectMemoryOptimized2DFloat,null):(this.TextureConstructor=x,this.formatValues=i.erectMemoryOptimizedFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=o,this.formatValues=i.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=a,this.formatValues=i.erect2DArray2,null):(this.TextureConstructor=s,this.formatValues=i.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=c,this.formatValues=i.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=l,this.formatValues=i.erect2DArray3,null):(this.TextureConstructor=u,this.formatValues=i.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=d,this.formatValues=i.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=p,this.formatValues=i.erect2DArray4,null):(this.TextureConstructor=h,this.formatValues=i.erectArray4,null)}else switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=f,this.formatValues=i.erect3DFloat,null):this.output[1]>0?(this.TextureConstructor=g,this.formatValues=i.erect2DFloat,null):(this.TextureConstructor=m,this.formatValues=i.erectFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=o,this.formatValues=i.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=a,this.formatValues=i.erect2DArray2,null):(this.TextureConstructor=s,this.formatValues=i.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=c,this.formatValues=i.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=l,this.formatValues=i.erect2DArray3,null):(this.TextureConstructor=u,this.formatValues=i.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=d,this.formatValues=i.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=p,this.formatValues=i.erect2DArray4,null):(this.TextureConstructor=h,this.formatValues=i.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 i.linesToString(this.getMainResultKernelNumberTexture())+i.linesToString(this.getMainResultSubKernelNumberTexture())}getMainResultArray2Texture(){return i.linesToString(this.getMainResultKernelArray2Texture())+i.linesToString(this.getMainResultSubKernelArray2Texture())}getMainResultArray3Texture(){return i.linesToString(this.getMainResultKernelArray3Texture())+i.linesToString(this.getMainResultSubKernelArray3Texture())}getMainResultArray4Texture(){return i.linesToString(this.getMainResultKernelArray4Texture())+i.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],i=new Float32Array(n*r*4);return t.readPixels(0,0,n,r,t.RGBA,t.FLOAT,i),i}getPixels(e){const{context:t,output:n}=this,[r,s]=n,a=new Uint8Array(r*s*4);return t.readPixels(0,0,r,s,t.RGBA,t.UNSIGNED_BYTE,a),new Uint8ClampedArray((e?a:i.flipPixels(a,r,s)).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;r1&&(this.newTexture(),!0)}cloneTexture(){this.texture._refs--;const{context:e,size:t,texture:n,kernel:r}=this;r.debug&&console.warn("cloning internal texture"),e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),i(e,n),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,n,0);const s=e.createTexture();i(e,s),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]),s._refs=1,this.texture=s}newTexture(){this.texture._refs--;const e=this.context,t=this.size;this.kernel.debug&&console.warn("new internal texture");const n=e.createTexture();i(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();i(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),i(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.context.deleteTexture(this.texture))}framebuffer(){return this._framebuffer||(this._framebuffer=this.kernel.getRawValueFramebuffer(this.size[0],this.size[1])),this._framebuffer}}}},{"../../../texture":112}],27:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureMemoryOptimized2D:class extends i{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return r.erectMemoryOptimized2DFloat(this.renderValues(),this.output[0],this.output[1])}}}},{"../../../utils":113,"./float":24}],28:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureMemoryOptimized3D:class extends i{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return r.erectMemoryOptimized3DFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}},{"../../../utils":113,"./float":24}],29:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureMemoryOptimized:class extends i{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return r.erectMemoryOptimizedFloat(this.renderValues(),this.output[0])}}}},{"../../../utils":113,"./float":24}],30:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureUnsigned:i}=e("./unsigned");t.exports={GLTextureUnsigned2D:class extends i{constructor(e){super(e),this.type="NumberTexture"}toArray(){return r.erect2DPackedFloat(this.renderValues(),this.output[0],this.output[1])}}}},{"../../../utils":113,"./unsigned":32}],31:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureUnsigned:i}=e("./unsigned");t.exports={GLTextureUnsigned3D:class extends i{constructor(e){super(e),this.type="NumberTexture"}toArray(){return r.erect3DPackedFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}},{"../../../utils":113,"./unsigned":32}],32:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTexture:i}=e("./index");t.exports={GLTextureUnsigned:class extends i{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])}}}},{"../../../utils":113,"./index":26}],33:[function(e,t,n){const r=e("gl"),{WebGLKernel:i}=e("../web-gl/kernel"),{glKernelString:s}=e("../gl/kernel-string");let a=null,o=null,u=null,l=null,c=null;t.exports={HeadlessGLKernel:class extends i{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")},c=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 c}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}}}},{"../gl/kernel-string":11,"../web-gl/kernel":69,gl:1}],34:[function(e,t,n){t.exports={KernelValue:class{constructor(e,t){const{name:n,kernel:r,context:i,checkContext:s,onRequestContextHandle:a,onUpdateValueMismatch:o,origin:u,strictIntegers:l,type:c,tactic:h}=t;if(!n)throw new Error("name not set");if(!c)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=h,this.varName="constants"===u?`constants.${n}`:n,this.kernel=r,this.strictIntegers=l,this.type=e.type||c,this.size=e.size||null,this.index=null,this.context=i,this.checkContext=null==s||s,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}`)}}}},{}],35:[function(e,t,n){const{utils:r}=e("../utils"),{Input:i}=e("../input");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.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 i=0;it.argumentTypes[e]))||[]:t.argumentTypes||[],{name:r.getFunctionNameFromString(n)||null,source:n,argumentTypes:i,returnType:t.returnType||null}}onActivate(e){}}}},{"../input":109,"../utils":113}],36:[function(e,t,n){const r=`__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 (v1 == 0.0 || v2 == 0.0) return 0.0;\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 int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if (modi(a, 2) == 0) {\n result += n; \n }\n a = a / 2;\n n = n * 2;\n }\n return result;\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\nint bitwiseSignedRightShift(int num, int shifts) {\n return int(floor(float(num) / pow(2.0, 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__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\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 = exp2(_round(exponent));\n texel.b = texel.b - 128.0 * gte128.x;\n res = dot(texel, SCALE_FACTOR) * exp2(_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\n mantissa = value*pow(2.0, -exponent)-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}`;t.exports={fragmentShader:r}},{}],37:[function(e,t,n){const{utils:r}=e("../../utils"),{FunctionNode:i}=e("../function-node");const s={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"},a={"===":"==","!==":"!="};t.exports={WebGLFunctionNode:class extends i{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{if(!this.returnType){this.findLastReturn()&&(this.returnType=this.getType(e.body),"LiteralInteger"===this.returnType&&(this.returnType="Number"))}const{returnType:n}=this;if(n){const e=s[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 n=0;n0&&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("Unexpected expression",e);const u=r.sanitizeName(i);"sampler2D"===o||"sampler2DArray"===o?t.push(`${o} user_${u},ivec2 user_${u}Size,ivec3 user_${u}Dim`):t.push(`${o} user_${u}`)}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(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 n=[];this.astGeneric(e.right,n);if("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(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.astGeneric(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 ${i}`,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;t.push(n),t.push("(");switch(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)}t.push(",");switch(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 n=this.getType(e),i=r.sanitizeName(e.name);return"Infinity"===e.name?t.push("3.402823466e+38"):"Boolean"===n&&this.argumentNames.indexOf(i)>-1?t.push(`bool(user_${i})`):t.push(`user_${i}`),t}astForStatement(e,t){if("ForStatement"!==e.type)throw this.astErrorOutput("Invalid for statement",e);const n=[],r=[],i=[],s=[];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(s.join("")),t.push(`\n${i.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}0&&o.push(u.join(",")),i.push(o.join(";")),t.push(i.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}astSwitchStatement(e,t){if("SwitchStatement"!==e.type)throw this.astErrorOutput("Invalid switch statement",e);const{discriminant:n,cases:r}=e,i=this.getType(n),s=`switchDiscriminant${this.astKey(e,"_")}`;switch(i){case"Float":case"Number":t.push(`float ${s} = `),this.astGeneric(n,t),t.push(";\n");break;case"Integer":t.push(`int ${s} = `),this.astGeneric(n,t),t.push(";\n")}if(1===r.length&&!r[0].test)return this.astGeneric(r[0].consequent,t),t;let a=!1,o=[],u=!1,l=!1;for(let e=0;ee+1){u=!0,this.astGeneric(r[e].consequent,o);continue}t.push(" else {\n")}this.astGeneric(r[e].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:i,signature:s,origin:a,type:o,xProperty:u,yProperty:l,zProperty:c}=this.getMemberExpressionDetails(e);switch(s){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(`threadId.${i}`),t;case"this.output.value":if(this.dynamicOutput)switch(i){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(i){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[i]),t;const s=r.sanitizeName(i);switch(n){case"r":return t.push(`user_${s}.r`),t;case"g":return t.push(`user_${s}.g`),t;case"b":return t.push(`user_${s}.b`),t;case"a":return t.push(`user_${s}.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(i)}`),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()[][]":return this.astCallExpression(e.object.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(e.object.property)),t.push("]"),t.push("["),t.push(this.memberExpressionPropertyMarkup(e.property)),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(i)}`),t}const h=`${a}_${r.sanitizeName(i)}`;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(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(u,l,c,t),t.push(")");break;case"ArrayTexture(1)":t.push(`getFloatFromSampler2D(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(u,l,c,t),t.push(")");break;case"Array1D(2)":case"Array2D(2)":case"Array3D(2)":t.push(`getMemoryOptimizedVec2(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(u,l,c,t),t.push(")");break;case"ArrayTexture(2)":t.push(`getVec2FromSampler2D(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(u,l,c,t),t.push(")");break;case"Array1D(3)":case"Array2D(3)":case"Array3D(3)":t.push(`getMemoryOptimizedVec3(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(u,l,c,t),t.push(")");break;case"ArrayTexture(3)":t.push(`getVec3FromSampler2D(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(u,l,c,t),t.push(")");break;case"Array1D(4)":case"Array2D(4)":case"Array3D(4)":t.push(`getMemoryOptimizedVec4(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(u,l,c,t),t.push(")");break;case"ArrayTexture(4)":case"HTMLCanvas":case"OffscreenCanvas":case"HTMLImage":case"ImageBitmap":case"ImageData":case"HTMLVideo":t.push(`getVec4FromSampler2D(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(u,l,c,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(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(u,l,c,t),t.push(")");else{const e="user"===a?this.lookupFunctionArgumentBitRatio(this.name,i):this.constantBitRatios[i];switch(e){case 1:t.push(`get8(${h}, ${h}Size, ${h}Dim, `);break;case 2:t.push(`get16(${h}, ${h}Size, ${h}Dim, `);break;case 4:case 0:t.push(`get32(${h}, ${h}Size, ${h}Dim, `);break;default:throw new Error(`unhandled bit ratio of ${e}`)}this.memberExpressionXYZ(u,l,c,t),t.push(")")}break;case"MemoryOptimizedNumberTexture":t.push(`getMemoryOptimized32(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(u,l,c,t),t.push(")");break;case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":t.push(`${h}[${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 i=this.isAstMathFunction(e);if(n=i||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"===i)this.castValueToFloat(r,t);else this.astGeneric(r,t)}else{const i=this.lookupFunctionArgumentTypes(n)||[];for(let s=0;s0&&t.push(", ");const u=this.getType(a);switch(o||(this.triggerImplyArgumentType(n,s,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,s);const i=r.sanitizeName(a.name);t.push(`user_${i},user_${i}Size,user_${i}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)}return t.join("")}}}},{"../../utils":113,"../function-node":9}],38:[function(e,t,n){const{WebGLKernelValueBoolean:r}=e("./kernel-value/boolean"),{WebGLKernelValueFloat:i}=e("./kernel-value/float"),{WebGLKernelValueInteger:s}=e("./kernel-value/integer"),{WebGLKernelValueHTMLImage:a}=e("./kernel-value/html-image"),{WebGLKernelValueDynamicHTMLImage:o}=e("./kernel-value/dynamic-html-image"),{WebGLKernelValueHTMLVideo:u}=e("./kernel-value/html-video"),{WebGLKernelValueDynamicHTMLVideo:l}=e("./kernel-value/dynamic-html-video"),{WebGLKernelValueSingleInput:c}=e("./kernel-value/single-input"),{WebGLKernelValueDynamicSingleInput:h}=e("./kernel-value/dynamic-single-input"),{WebGLKernelValueUnsignedInput:p}=e("./kernel-value/unsigned-input"),{WebGLKernelValueDynamicUnsignedInput:d}=e("./kernel-value/dynamic-unsigned-input"),{WebGLKernelValueMemoryOptimizedNumberTexture:m}=e("./kernel-value/memory-optimized-number-texture"),{WebGLKernelValueDynamicMemoryOptimizedNumberTexture:g}=e("./kernel-value/dynamic-memory-optimized-number-texture"),{WebGLKernelValueNumberTexture:f}=e("./kernel-value/number-texture"),{WebGLKernelValueDynamicNumberTexture:x}=e("./kernel-value/dynamic-number-texture"),{WebGLKernelValueSingleArray:y}=e("./kernel-value/single-array"),{WebGLKernelValueDynamicSingleArray:T}=e("./kernel-value/dynamic-single-array"),{WebGLKernelValueSingleArray1DI:b}=e("./kernel-value/single-array1d-i"),{WebGLKernelValueDynamicSingleArray1DI:A}=e("./kernel-value/dynamic-single-array1d-i"),{WebGLKernelValueSingleArray2DI:S}=e("./kernel-value/single-array2d-i"),{WebGLKernelValueDynamicSingleArray2DI:v}=e("./kernel-value/dynamic-single-array2d-i"),{WebGLKernelValueSingleArray3DI:_}=e("./kernel-value/single-array3d-i"),{WebGLKernelValueDynamicSingleArray3DI:E}=e("./kernel-value/dynamic-single-array3d-i"),{WebGLKernelValueArray2:w}=e("./kernel-value/array2"),{WebGLKernelValueArray3:D}=e("./kernel-value/array3"),{WebGLKernelValueArray4:$}=e("./kernel-value/array4"),{WebGLKernelValueUnsignedArray:I}=e("./kernel-value/unsigned-array"),{WebGLKernelValueDynamicUnsignedArray:F}=e("./kernel-value/dynamic-unsigned-array"),k={unsigned:{dynamic:{Boolean:r,Integer:s,Float:i,Array:F,"Array(2)":w,"Array(3)":D,"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:x,"ArrayTexture(1)":x,"ArrayTexture(2)":x,"ArrayTexture(3)":x,"ArrayTexture(4)":x,MemoryOptimizedNumberTexture:g,HTMLCanvas:o,OffscreenCanvas:o,HTMLImage:o,ImageBitmap:o,ImageData:o,HTMLImageArray:!1,HTMLVideo:l},static:{Boolean:r,Float:i,Integer:s,Array:I,"Array(2)":w,"Array(3)":D,"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:p,NumberTexture:f,"ArrayTexture(1)":f,"ArrayTexture(2)":f,"ArrayTexture(3)":f,"ArrayTexture(4)":f,MemoryOptimizedNumberTexture:m,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:!1,HTMLVideo:u}},single:{dynamic:{Boolean:r,Integer:s,Float:i,Array:T,"Array(2)":w,"Array(3)":D,"Array(4)":$,"Array1D(2)":A,"Array1D(3)":A,"Array1D(4)":A,"Array2D(2)":v,"Array2D(3)":v,"Array2D(4)":v,"Array3D(2)":E,"Array3D(3)":E,"Array3D(4)":E,Input:h,NumberTexture:x,"ArrayTexture(1)":x,"ArrayTexture(2)":x,"ArrayTexture(3)":x,"ArrayTexture(4)":x,MemoryOptimizedNumberTexture:g,HTMLCanvas:o,OffscreenCanvas:o,HTMLImage:o,ImageBitmap:o,ImageData:o,HTMLImageArray:!1,HTMLVideo:l},static:{Boolean:r,Float:i,Integer:s,Array:y,"Array(2)":w,"Array(3)":D,"Array(4)":$,"Array1D(2)":b,"Array1D(3)":b,"Array1D(4)":b,"Array2D(2)":S,"Array2D(3)":S,"Array2D(4)":S,"Array3D(2)":_,"Array3D(3)":_,"Array3D(4)":_,Input:c,NumberTexture:f,"ArrayTexture(1)":f,"ArrayTexture(2)":f,"ArrayTexture(3)":f,"ArrayTexture(4)":f,MemoryOptimizedNumberTexture:m,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:!1,HTMLVideo:u}}};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 i=k[n][t];if(!1===i[e])return null;if(void 0===i[e])throw new Error(`Could not find a KernelValue for ${e}`);return i[e]},kernelValueMaps:k}},{"./kernel-value/array2":40,"./kernel-value/array3":41,"./kernel-value/array4":42,"./kernel-value/boolean":43,"./kernel-value/dynamic-html-image":44,"./kernel-value/dynamic-html-video":45,"./kernel-value/dynamic-memory-optimized-number-texture":46,"./kernel-value/dynamic-number-texture":47,"./kernel-value/dynamic-single-array":48,"./kernel-value/dynamic-single-array1d-i":49,"./kernel-value/dynamic-single-array2d-i":50,"./kernel-value/dynamic-single-array3d-i":51,"./kernel-value/dynamic-single-input":52,"./kernel-value/dynamic-unsigned-array":53,"./kernel-value/dynamic-unsigned-input":54,"./kernel-value/float":55,"./kernel-value/html-image":56,"./kernel-value/html-video":57,"./kernel-value/integer":59,"./kernel-value/memory-optimized-number-texture":60,"./kernel-value/number-texture":61,"./kernel-value/single-array":62,"./kernel-value/single-array1d-i":63,"./kernel-value/single-array2d-i":64,"./kernel-value/single-array3d-i":65,"./kernel-value/single-input":66,"./kernel-value/unsigned-array":67,"./kernel-value/unsigned-input":68}],39:[function(e,t,n){const{WebGLKernelValue:r}=e("./index"),{Input:i}=e("../../../input");t.exports={WebGLKernelArray:class extends r{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`):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&&t.isTextureFloat&&(this.precision=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=y.indexOf(t);-1===n&&(n=y.length,y.push(t),T[n]=[e[0],e[1]]),this.maxTexSize=T[n]}this.maxTexSize[0]this.argumentNames.length)throw new Error("too many arguments for kernel");const{context:n}=this;let r=0;const i=()=>this.createTexture(),s=()=>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[i]=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 i=this.threadDim=Array.from(this.output);for(;i.length<3;)i.push(1);const s=this.getVertexShader(arguments),a=n.createShader(n.VERTEX_SHADER);n.shaderSource(a,s),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 c=new Float32Array([-1,-1,1,-1,-1,1,1,1]),h=new Float32Array([0,0,1,0,0,1,1,1]),p=c.byteLength;let d=this.buffer;d?n.bindBuffer(n.ARRAY_BUFFER,d):(d=this.buffer=n.createBuffer(),n.bindBuffer(n.ARRAY_BUFFER,d),n.bufferData(n.ARRAY_BUFFER,c.byteLength+h.byteLength,n.STATIC_DRAW)),n.bufferSubData(n.ARRAY_BUFFER,0,c),n.bufferSubData(n.ARRAY_BUFFER,p,h);const m=n.getAttribLocation(this.program,"aPos");n.enableVertexAttribArray(m),n.vertexAttribPointer(m,2,n.FLOAT,!1,0,0);const g=n.getAttribLocation(this.program,"aTexCoord");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=i.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 && integerMod(x, y) == 0.0) {\n return float(int(x) / int(y));\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=y.indexOf(this.canvas);e>=0&&(y[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=i.fromKernel(this,s).toJSON(),e.settings.threadDim=this.threadDim,e}}}},{"../../plugins/math-random-uniformly-distributed":111,"../../utils":113,"../function-builder":8,"../gl/kernel":12,"../gl/kernel-string":11,"./fragment-shader":36,"./function-node":37,"./kernel-value-maps":38,"./vertex-shader":70}],70:[function(e,t,n){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}"}},{}],71:[function(e,t,n){const r=`#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 (v1 == 0.0 || v2 == 0.0) return 0.0;\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 int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if (modi(a, 2) == 0) {\n result += n; \n }\n a = a / 2;\n n = n * 2;\n }\n return result;\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\nint bitwiseSignedRightShift(int num, int shifts) {\n return int(floor(float(num) / pow(2.0, 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__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\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 = exp2(round(exponent));\n texel.b = texel.b - 128.0 * gte128.x;\n res = dot(texel, SCALE_FACTOR) * exp2(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\n mantissa = value*pow(2.0, -exponent)-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}`;t.exports={fragmentShader:r}},{}],72:[function(e,t,n){const{utils:r}=e("../../utils"),{WebGLFunctionNode:i}=e("../web-gl/function-node");t.exports={WebGL2FunctionNode:class extends i{astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const n=this.getType(e),i=r.sanitizeName(e.name);return"Infinity"===e.name?t.push("intBitsToFloat(2139095039)"):"Boolean"===n&&this.argumentNames.indexOf(i)>-1?t.push(`bool(user_${i})`):t.push(`user_${i}`),t}}}},{"../../utils":113,"../web-gl/function-node":37}],73:[function(e,t,n){const{WebGL2KernelValueBoolean:r}=e("./kernel-value/boolean"),{WebGL2KernelValueFloat:i}=e("./kernel-value/float"),{WebGL2KernelValueInteger:s}=e("./kernel-value/integer"),{WebGL2KernelValueHTMLImage:a}=e("./kernel-value/html-image"),{WebGL2KernelValueDynamicHTMLImage:o}=e("./kernel-value/dynamic-html-image"),{WebGL2KernelValueHTMLImageArray:u}=e("./kernel-value/html-image-array"),{WebGL2KernelValueDynamicHTMLImageArray:l}=e("./kernel-value/dynamic-html-image-array"),{WebGL2KernelValueHTMLVideo:c}=e("./kernel-value/html-video"),{WebGL2KernelValueDynamicHTMLVideo:h}=e("./kernel-value/dynamic-html-video"),{WebGL2KernelValueSingleInput:p}=e("./kernel-value/single-input"),{WebGL2KernelValueDynamicSingleInput:d}=e("./kernel-value/dynamic-single-input"),{WebGL2KernelValueUnsignedInput:m}=e("./kernel-value/unsigned-input"),{WebGL2KernelValueDynamicUnsignedInput:g}=e("./kernel-value/dynamic-unsigned-input"),{WebGL2KernelValueMemoryOptimizedNumberTexture:f}=e("./kernel-value/memory-optimized-number-texture"),{WebGL2KernelValueDynamicMemoryOptimizedNumberTexture:x}=e("./kernel-value/dynamic-memory-optimized-number-texture"),{WebGL2KernelValueNumberTexture:y}=e("./kernel-value/number-texture"),{WebGL2KernelValueDynamicNumberTexture:T}=e("./kernel-value/dynamic-number-texture"),{WebGL2KernelValueSingleArray:b}=e("./kernel-value/single-array"),{WebGL2KernelValueDynamicSingleArray:A}=e("./kernel-value/dynamic-single-array"),{WebGL2KernelValueSingleArray1DI:S}=e("./kernel-value/single-array1d-i"),{WebGL2KernelValueDynamicSingleArray1DI:v}=e("./kernel-value/dynamic-single-array1d-i"),{WebGL2KernelValueSingleArray2DI:_}=e("./kernel-value/single-array2d-i"),{WebGL2KernelValueDynamicSingleArray2DI:E}=e("./kernel-value/dynamic-single-array2d-i"),{WebGL2KernelValueSingleArray3DI:w}=e("./kernel-value/single-array3d-i"),{WebGL2KernelValueDynamicSingleArray3DI:D}=e("./kernel-value/dynamic-single-array3d-i"),{WebGL2KernelValueArray2:$}=e("./kernel-value/array2"),{WebGL2KernelValueArray3:I}=e("./kernel-value/array3"),{WebGL2KernelValueArray4:F}=e("./kernel-value/array4"),{WebGL2KernelValueUnsignedArray:k}=e("./kernel-value/unsigned-array"),{WebGL2KernelValueDynamicUnsignedArray:R}=e("./kernel-value/dynamic-unsigned-array"),L={unsigned:{dynamic:{Boolean:r,Integer:s,Float:i,Array:R,"Array(2)":$,"Array(3)":I,"Array(4)":F,"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:g,NumberTexture:T,"ArrayTexture(1)":T,"ArrayTexture(2)":T,"ArrayTexture(3)":T,"ArrayTexture(4)":T,MemoryOptimizedNumberTexture:x,HTMLCanvas:o,OffscreenCanvas:o,HTMLImage:o,ImageBitmap:o,ImageData:o,HTMLImageArray:l,HTMLVideo:h},static:{Boolean:r,Float:i,Integer:s,Array:k,"Array(2)":$,"Array(3)":I,"Array(4)":F,"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:x,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:u,HTMLVideo:c}},single:{dynamic:{Boolean:r,Integer:s,Float:i,Array:A,"Array(2)":$,"Array(3)":I,"Array(4)":F,"Array1D(2)":v,"Array1D(3)":v,"Array1D(4)":v,"Array2D(2)":E,"Array2D(3)":E,"Array2D(4)":E,"Array3D(2)":D,"Array3D(3)":D,"Array3D(4)":D,Input:d,NumberTexture:T,"ArrayTexture(1)":T,"ArrayTexture(2)":T,"ArrayTexture(3)":T,"ArrayTexture(4)":T,MemoryOptimizedNumberTexture:x,HTMLCanvas:o,OffscreenCanvas:o,HTMLImage:o,ImageBitmap:o,ImageData:o,HTMLImageArray:l,HTMLVideo:h},static:{Boolean:r,Float:i,Integer:s,Array:b,"Array(2)":$,"Array(3)":I,"Array(4)":F,"Array1D(2)":S,"Array1D(3)":S,"Array1D(4)":S,"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:c}}};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 i=L[n][t];if(!1===i[e])return null;if(void 0===i[e])throw new Error(`Could not find a KernelValue for ${e}`);return i[e]}}},{"./kernel-value/array2":74,"./kernel-value/array3":75,"./kernel-value/array4":76,"./kernel-value/boolean":77,"./kernel-value/dynamic-html-image":79,"./kernel-value/dynamic-html-image-array":78,"./kernel-value/dynamic-html-video":80,"./kernel-value/dynamic-memory-optimized-number-texture":81,"./kernel-value/dynamic-number-texture":82,"./kernel-value/dynamic-single-array":83,"./kernel-value/dynamic-single-array1d-i":84,"./kernel-value/dynamic-single-array2d-i":85,"./kernel-value/dynamic-single-array3d-i":86,"./kernel-value/dynamic-single-input":87,"./kernel-value/dynamic-unsigned-array":88,"./kernel-value/dynamic-unsigned-input":89,"./kernel-value/float":90,"./kernel-value/html-image":92,"./kernel-value/html-image-array":91,"./kernel-value/html-video":93,"./kernel-value/integer":94,"./kernel-value/memory-optimized-number-texture":95,"./kernel-value/number-texture":96,"./kernel-value/single-array":97,"./kernel-value/single-array1d-i":98,"./kernel-value/single-array2d-i":99,"./kernel-value/single-array3d-i":100,"./kernel-value/single-input":101,"./kernel-value/unsigned-array":102,"./kernel-value/unsigned-input":103}],74:[function(e,t,n){const{WebGLKernelValueArray2:r}=e("../../web-gl/kernel-value/array2");t.exports={WebGL2KernelValueArray2:class extends r{}}},{"../../web-gl/kernel-value/array2":40}],75:[function(e,t,n){const{WebGLKernelValueArray3:r}=e("../../web-gl/kernel-value/array3");t.exports={WebGL2KernelValueArray3:class extends r{}}},{"../../web-gl/kernel-value/array3":41}],76:[function(e,t,n){const{WebGLKernelValueArray4:r}=e("../../web-gl/kernel-value/array4");t.exports={WebGL2KernelValueArray4:class extends r{}}},{"../../web-gl/kernel-value/array4":42}],77:[function(e,t,n){const{WebGLKernelValueBoolean:r}=e("../../web-gl/kernel-value/boolean");t.exports={WebGL2KernelValueBoolean:class extends r{}}},{"../../web-gl/kernel-value/boolean":43}],78:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueHTMLImageArray:i}=e("./html-image-array");t.exports={WebGL2KernelValueDynamicHTMLImageArray:class extends i{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: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)}}}},{"../../../utils":113,"./html-image-array":91}],79:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueDynamicHTMLImage:i}=e("../../web-gl/kernel-value/dynamic-html-image");t.exports={WebGL2KernelValueDynamicHTMLImage:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":113,"../../web-gl/kernel-value/dynamic-html-image":44}],80:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueDynamicHTMLImage:i}=e("./dynamic-html-image");t.exports={WebGL2KernelValueDynamicHTMLVideo:class extends i{}}},{"../../../utils":113,"./dynamic-html-image":79}],81:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueDynamicMemoryOptimizedNumberTexture:i}=e("../../web-gl/kernel-value/dynamic-memory-optimized-number-texture");t.exports={WebGL2KernelValueDynamicMemoryOptimizedNumberTexture:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":113,"../../web-gl/kernel-value/dynamic-memory-optimized-number-texture":46}],82:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueDynamicNumberTexture:i}=e("../../web-gl/kernel-value/dynamic-number-texture");t.exports={WebGL2KernelValueDynamicNumberTexture:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":113,"../../web-gl/kernel-value/dynamic-number-texture":47}],83:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueSingleArray:i}=e("../../web-gl2/kernel-value/single-array");t.exports={WebGL2KernelValueDynamicSingleArray:class extends i{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)}}}},{"../../../utils":113,"../../web-gl2/kernel-value/single-array":97}],84:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueSingleArray1DI:i}=e("../../web-gl2/kernel-value/single-array1d-i");t.exports={WebGL2KernelValueDynamicSingleArray1DI:class extends i{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)}}}},{"../../../utils":113,"../../web-gl2/kernel-value/single-array1d-i":98}],85:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueSingleArray2DI:i}=e("../../web-gl2/kernel-value/single-array2d-i");t.exports={WebGL2KernelValueDynamicSingleArray2DI:class extends i{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)}}}},{"../../../utils":113,"../../web-gl2/kernel-value/single-array2d-i":99}],86:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueSingleArray3DI:i}=e("../../web-gl2/kernel-value/single-array3d-i");t.exports={WebGL2KernelValueDynamicSingleArray3DI:class extends i{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)}}}},{"../../../utils":113,"../../web-gl2/kernel-value/single-array3d-i":100}],87:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueSingleInput:i}=e("../../web-gl2/kernel-value/single-input");t.exports={WebGL2KernelValueDynamicSingleInput:class extends i{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,i]=e.size;this.dimensions=new Int32Array([t||1,n||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),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":113,"../../web-gl2/kernel-value/single-input":101}],88:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueDynamicUnsignedArray:i}=e("../../web-gl/kernel-value/dynamic-unsigned-array");t.exports={WebGL2KernelValueDynamicUnsignedArray:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":113,"../../web-gl/kernel-value/dynamic-unsigned-array":53}],89:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueDynamicUnsignedInput:i}=e("../../web-gl/kernel-value/dynamic-unsigned-input");t.exports={WebGL2KernelValueDynamicUnsignedInput:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":113,"../../web-gl/kernel-value/dynamic-unsigned-input":54}],90:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueFloat:i}=e("../../web-gl/kernel-value/float");t.exports={WebGL2KernelValueFloat:class extends i{}}},{"../../../utils":113,"../../web-gl/kernel-value/float":55}],91:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelArray:i}=e("../../web-gl/kernel-value/array");t.exports={WebGL2KernelValueHTMLImageArray:class extends i{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 n=0;ni})}"undefined"!=typeof window&&s(window),"undefined"!=typeof self&&s(self),t.exports=r},{"./index":108}],107:[function(e,t,n){const{gpuMock:r}=e("gpu-mock.js"),{utils:i}=e("./utils"),{Kernel:s}=e("./backend/kernel"),{CPUKernel:a}=e("./backend/cpu/kernel"),{HeadlessGLKernel:o}=e("./backend/headless-gl/kernel"),{WebGL2Kernel:u}=e("./backend/web-gl2/kernel"),{WebGLKernel:l}=e("./backend/web-gl/kernel"),{kernelRunShortcut:c}=e("./kernel-run-shortcut"),h=[o,u,l],p=["gpu","cpu"],d={headlessgl:o,webgl2:u,webgl:l};let m=!0;function g(e){if(!e)return{};const t=Object.assign({},e);return e.hasOwnProperty("floatOutput")&&(i.warnDeprecated("setting","floatOutput","precision"),t.precision=e.floatOutput?"single":"unsigned"),e.hasOwnProperty("outputToTexture")&&(i.warnDeprecated("setting","outputToTexture","pipeline"),t.pipeline=Boolean(e.outputToTexture)),e.hasOwnProperty("outputImmutable")&&(i.warnDeprecated("setting","outputImmutable","immutable"),t.immutable=Boolean(e.outputImmutable)),e.hasOwnProperty("floatTextures")&&(i.warnDeprecated("setting","floatTextures","optimizeFloatMemory"),t.optimizeFloatMemory=Boolean(e.floatTextures)),t}t.exports={GPU:class{static disableValidation(){m=!1}static enableValidation(){m=!0}static get isGPUSupported(){return h.some((e=>e.isSupported))}static get isKernelMapSupported(){return h.some((e=>e.isSupported&&e.features.kernelMap))}static get isOffscreenCanvasSupported(){return"undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas||"undefined"!=typeof importScripts}static get isWebGLSupported(){return l.isSupported}static get isWebGL2Supported(){return u.isSupported}static get isHeadlessGLSupported(){return o.isSupported}static get isCanvasSupported(){return"undefined"!=typeof HTMLCanvasElement}static get isGPUHTMLImageArraySupported(){return u.isSupported}static get isSinglePrecisionSupported(){return h.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:m,onRequestFallback:u,onRequestSwitchKernel:function t(r,i,a){a.debug&&console.warn("Switching kernels");let o=null;if(a.signature&&!s[a.signature]&&(s[a.signature]=a),a.dynamicOutput)for(let e=r.length-1;e>=0;e--){const t=r[e];"outputPrecisionMismatch"===t.type&&(o=t.needed)}const l=a.constructor,c=l.getArgumentTypes(a,i),h=l.getSignature(a,c),d=s[h];if(d)return d.onActivate(a),d;const g=s[h]=new l(e,{argumentTypes:c,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:o||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,debug:a.debug,gpu:a.gpu,validate:m,returnType:a.returnType,tactic:a.tactic,onRequestFallback:u,onRequestSwitchKernel:t,texture:a.texture,mappedTextures:a.mappedTextures,drawBuffersMap:a.drawBuffersMap});return g.build.apply(g,i),p.replaceKernel(g),n.push(g),g}},o),h=new this.Kernel(e,l),p=c(h);return this.canvas||(this.canvas=h.canvas),this.context||(this.context=h.context),n.push(h),p}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&&p.indexOf(this.mode)<0)throw new Error(`kernelMap not supported on ${this.Kernel.name}`);const r=g(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{for(let e=0;et.kernel[i])),t.__defineSetter__(i,(e=>{t.kernel[i]=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(),i=e.onRequestSwitchKernel(r,arguments,e);n.kernel=e=i,t=i.run.apply(i,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){i(e=t,n)},i(e,n),n}}},{"./utils":113}],111:[function(e,t,n){const r={name:"math-random-uniformly-distributed",onBeforeRun:e=>{e.setUniform1f("randomSeed1",Math.random()),e.setUniform1f("randomSeed2",Math.random())},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}"};t.exports=r},{}],112:[function(e,t,n){t.exports={Texture:class{constructor(e){const{texture:t,size:n,dimensions:r,output:i,context:s,type:a="NumberTexture",kernel:o,internalFormat:u,textureFormat:l}=e;if(!i)throw new Error('settings property "output" required.');if(!s)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=i,this.context=s,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}`)}}}},{}],113:[function(e,t,n){const r=e("acorn"),{Input:i}=e("./input"),{Texture:s}=e("./texture"),a=/function ([^(]*)/,o=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,u=/([^\s,]+)/g,l={systemEndianness:()=>d,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=a.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(o,"");let n=t.slice(t.indexOf("(")+1,t.indexOf(")")).match(u);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]=l.clone(e[n]),delete e.isActiveClone);return t},isArray:e=>!isNaN(e.length),getVariableType(e,t){if(l.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 s:return e.type;case i: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,i]=t,s=(n||1)*(r||1)*(i||1);return e.optimizeFloatMemory&&"single"===e.precision&&(n=s=Math.ceil(s/4)),r>1&&n*r===s?new Int32Array([n,r]):l.closestSquareDimensions(s)},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(l.isArray(e)){const t=[];let r=e;for(;l.isArray(r);)t.push(r.length),r=r[0];n=t.reverse()}else if(e instanceof s)n=e.output;else{if(!(e instanceof i))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,i=4*t,s=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 i=0;i{const i=new Array(r);for(let s=0;se.subarray(0,t),erectMemoryOptimized2DFloat:(e,t,n)=>{const r=new Array(n);for(let i=0;i{const i=new Array(r);for(let s=0;s{const n=new Float32Array(t);let r=0;for(let i=0;i{const r=new Array(n);let i=0;for(let s=0;s{const i=new Array(r);let s=0;for(let a=0;a{const n=new Array(t),r=4*t;let i=0;for(let t=0;t{const r=new Array(n),i=4*t;for(let s=0;s{const i=4*t,s=new Array(r);for(let a=0;a{const n=new Array(t),r=4*t;let i=0;for(let t=0;t{const r=4*t,i=new Array(n);for(let s=0;s{const i=4*t,s=new Array(r);for(let a=0;a{const n=new Array(e),r=4*t;let i=0;for(let t=0;t{const r=4*t,i=new Array(n);for(let s=0;s{const i=4*t,s=new Array(r);for(let a=0;a{const{findDependency:n,thisLookup:i,doNotDefine:s}=t;let a=t.flattened;a||(a=t.flattened={});const o=r.parse(e),u=[];let c=0;const h=function e(t){if(Array.isArray(t)){const n=[];for(let r=0;rnull!==e));return r.length<1?"":`${t.kind} ${r.join(",")}`;case"VariableDeclarator":if(t.init.object&&"ThisExpression"===t.init.object.type){return i(t.init.property.name,!0)?`${t.id.name} = ${e(t.init)}`:null}return`${t.id.name} = ${e(t.init)}`;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?i(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":return`if (${e(t.test)}) ${e(t.consequent)}`;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"}}),i=e.createKernel((function(e){return 255*e[this.thread.y][this.thread.x].b}),{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),s=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),i(t),s(t)];return a.rKernel=n,a.gKernel=r,a.bKernel=i,a.aKernel=s,a.gpu=e,a},splitRGBAToCanvases:(e,t,n,r)=>{const i=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)"}});i(t);const s=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)"}});s(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),[i.canvas,s.canvas,a.canvas,o.canvas]},getMinifySafeName:e=>{try{const t=r.parse(`const value = ${e.toString()}`),{init:n}=t.body[0].declarations[0];return n.body.name||n.body.body[0].argument.name}catch(e){throw new Error("Unrecognized function type. Please use `() => yourFunctionVariableHere` or function() { return yourFunctionVariableHere; }")}},sanitizeName:function(e){return c.test(e)&&(e=e.replace(c,"S_S")),h.test(e)?e=e.replace(h,"U_U"):p.test(e)&&(e=e.replace(p,"u_u")),e}},c=/\$/,h=/__/,p=/_/,d=l.getSystemEndianness();t.exports={utils:l}},{"./input":109,"./texture":112,acorn:1}]},{},[106])(106)}));
\ No newline at end of file
diff --git a/dist/gpu-browser.js b/dist/gpu-browser.js
new file mode 100644
index 00000000..ffb47946
--- /dev/null
+++ b/dist/gpu-browser.js
@@ -0,0 +1,20521 @@
+/**
+ * gpu.js
+ * http://gpu.rocks/
+ *
+ * GPU Accelerated JavaScript
+ *
+ * @version 2.16.0
+ * @date Thu Feb 13 2025 11:46:48 GMT-0800 (Pacific Standard Time)
+ *
+ * @license MIT
+ * The MIT License
+ *
+ * Copyright (c) 2025 gpu.js Team
+ */(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.GPU = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i code) { return false }
+ pos += set[i + 1];
+ if (pos >= code) { return true }
+ }
+ return false
+ }
+
+
+ function isIdentifierStart(code, astral) {
+ if (code < 65) { return code === 36 }
+ if (code < 91) { return true }
+ if (code < 97) { return code === 95 }
+ if (code < 123) { return true }
+ if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) }
+ if (astral === false) { return false }
+ return isInAstralSet(code, astralIdentifierStartCodes)
+ }
+
+
+ function isIdentifierChar(code, astral) {
+ if (code < 48) { return code === 36 }
+ if (code < 58) { return true }
+ if (code < 65) { return false }
+ if (code < 91) { return true }
+ if (code < 97) { return code === 95 }
+ if (code < 123) { return true }
+ if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) }
+ if (astral === false) { return false }
+ return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes)
+ }
+
+
+
+
+
+ var TokenType = function TokenType(label, conf) {
+ if ( conf === void 0 ) conf = {};
+
+ this.label = label;
+ this.keyword = conf.keyword;
+ this.beforeExpr = !!conf.beforeExpr;
+ this.startsExpr = !!conf.startsExpr;
+ this.isLoop = !!conf.isLoop;
+ this.isAssign = !!conf.isAssign;
+ this.prefix = !!conf.prefix;
+ this.postfix = !!conf.postfix;
+ this.binop = conf.binop || null;
+ this.updateContext = null;
+ };
+
+ function binop(name, prec) {
+ return new TokenType(name, {beforeExpr: true, binop: prec})
+ }
+ var beforeExpr = {beforeExpr: true}, startsExpr = {startsExpr: true};
+
+
+ var keywords = {};
+
+ function kw(name, options) {
+ if ( options === void 0 ) options = {};
+
+ options.keyword = name;
+ return keywords[name] = new TokenType(name, options)
+ }
+
+ var types$1 = {
+ num: new TokenType("num", startsExpr),
+ regexp: new TokenType("regexp", startsExpr),
+ string: new TokenType("string", startsExpr),
+ name: new TokenType("name", startsExpr),
+ privateId: new TokenType("privateId", startsExpr),
+ eof: new TokenType("eof"),
+
+ bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}),
+ bracketR: new TokenType("]"),
+ braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}),
+ braceR: new TokenType("}"),
+ parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}),
+ parenR: new TokenType(")"),
+ comma: new TokenType(",", beforeExpr),
+ semi: new TokenType(";", beforeExpr),
+ colon: new TokenType(":", beforeExpr),
+ dot: new TokenType("."),
+ question: new TokenType("?", beforeExpr),
+ questionDot: new TokenType("?."),
+ arrow: new TokenType("=>", beforeExpr),
+ template: new TokenType("template"),
+ invalidTemplate: new TokenType("invalidTemplate"),
+ ellipsis: new TokenType("...", beforeExpr),
+ backQuote: new TokenType("`", startsExpr),
+ dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}),
+
+
+ eq: new TokenType("=", {beforeExpr: true, isAssign: true}),
+ assign: new TokenType("_=", {beforeExpr: true, isAssign: true}),
+ incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}),
+ prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}),
+ logicalOR: binop("||", 1),
+ logicalAND: binop("&&", 2),
+ bitwiseOR: binop("|", 3),
+ bitwiseXOR: binop("^", 4),
+ bitwiseAND: binop("&", 5),
+ equality: binop("==/!=/===/!==", 6),
+ relational: binop(">/<=/>=", 7),
+ bitShift: binop("<>>/>>>", 8),
+ plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}),
+ modulo: binop("%", 10),
+ star: binop("*", 10),
+ slash: binop("/", 10),
+ starstar: new TokenType("**", {beforeExpr: true}),
+ coalesce: binop("??", 1),
+
+ _break: kw("break"),
+ _case: kw("case", beforeExpr),
+ _catch: kw("catch"),
+ _continue: kw("continue"),
+ _debugger: kw("debugger"),
+ _default: kw("default", beforeExpr),
+ _do: kw("do", {isLoop: true, beforeExpr: true}),
+ _else: kw("else", beforeExpr),
+ _finally: kw("finally"),
+ _for: kw("for", {isLoop: true}),
+ _function: kw("function", startsExpr),
+ _if: kw("if"),
+ _return: kw("return", beforeExpr),
+ _switch: kw("switch"),
+ _throw: kw("throw", beforeExpr),
+ _try: kw("try"),
+ _var: kw("var"),
+ _const: kw("const"),
+ _while: kw("while", {isLoop: true}),
+ _with: kw("with"),
+ _new: kw("new", {beforeExpr: true, startsExpr: true}),
+ _this: kw("this", startsExpr),
+ _super: kw("super", startsExpr),
+ _class: kw("class", startsExpr),
+ _extends: kw("extends", beforeExpr),
+ _export: kw("export"),
+ _import: kw("import", startsExpr),
+ _null: kw("null", startsExpr),
+ _true: kw("true", startsExpr),
+ _false: kw("false", startsExpr),
+ _in: kw("in", {beforeExpr: true, binop: 7}),
+ _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}),
+ _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}),
+ _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}),
+ _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true})
+ };
+
+
+ var lineBreak = /\r\n?|\n|\u2028|\u2029/;
+ var lineBreakG = new RegExp(lineBreak.source, "g");
+
+ function isNewLine(code) {
+ return code === 10 || code === 13 || code === 0x2028 || code === 0x2029
+ }
+
+ function nextLineBreak(code, from, end) {
+ if ( end === void 0 ) end = code.length;
+
+ for (var i = from; i < end; i++) {
+ var next = code.charCodeAt(i);
+ if (isNewLine(next))
+ { return i < end - 1 && next === 13 && code.charCodeAt(i + 1) === 10 ? i + 2 : i + 1 }
+ }
+ return -1
+ }
+
+ var nonASCIIwhitespace = /[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
+
+ var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g;
+
+ var ref = Object.prototype;
+ var hasOwnProperty = ref.hasOwnProperty;
+ var toString = ref.toString;
+
+ var hasOwn = Object.hasOwn || (function (obj, propName) { return (
+ hasOwnProperty.call(obj, propName)
+ ); });
+
+ var isArray = Array.isArray || (function (obj) { return (
+ toString.call(obj) === "[object Array]"
+ ); });
+
+ var regexpCache = Object.create(null);
+
+ function wordsRegexp(words) {
+ return regexpCache[words] || (regexpCache[words] = new RegExp("^(?:" + words.replace(/ /g, "|") + ")$"))
+ }
+
+ function codePointToString(code) {
+ if (code <= 0xFFFF) { return String.fromCharCode(code) }
+ code -= 0x10000;
+ return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00)
+ }
+
+ var loneSurrogate = /(?:[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/;
+
+
+ var Position = function Position(line, col) {
+ this.line = line;
+ this.column = col;
+ };
+
+ Position.prototype.offset = function offset (n) {
+ return new Position(this.line, this.column + n)
+ };
+
+ var SourceLocation = function SourceLocation(p, start, end) {
+ this.start = start;
+ this.end = end;
+ if (p.sourceFile !== null) { this.source = p.sourceFile; }
+ };
+
+
+ function getLineInfo(input, offset) {
+ for (var line = 1, cur = 0;;) {
+ var nextBreak = nextLineBreak(input, cur, offset);
+ if (nextBreak < 0) { return new Position(line, offset - cur) }
+ ++line;
+ cur = nextBreak;
+ }
+ }
+
+
+ var defaultOptions = {
+ ecmaVersion: null,
+ sourceType: "script",
+ onInsertedSemicolon: null,
+ onTrailingComma: null,
+ allowReserved: null,
+ allowReturnOutsideFunction: false,
+ allowImportExportEverywhere: false,
+ allowAwaitOutsideFunction: null,
+ allowSuperOutsideMethod: null,
+ allowHashBang: false,
+ checkPrivateFields: true,
+ locations: false,
+ onToken: null,
+ onComment: null,
+ ranges: false,
+ program: null,
+ sourceFile: null,
+ directSourceFile: null,
+ preserveParens: false
+ };
+
+
+ var warnedAboutEcmaVersion = false;
+
+ function getOptions(opts) {
+ var options = {};
+
+ for (var opt in defaultOptions)
+ { options[opt] = opts && hasOwn(opts, opt) ? opts[opt] : defaultOptions[opt]; }
+
+ if (options.ecmaVersion === "latest") {
+ options.ecmaVersion = 1e8;
+ } else if (options.ecmaVersion == null) {
+ if (!warnedAboutEcmaVersion && typeof console === "object" && console.warn) {
+ warnedAboutEcmaVersion = true;
+ console.warn("Since Acorn 8.0.0, options.ecmaVersion is required.\nDefaulting to 2020, but this will stop working in the future.");
+ }
+ options.ecmaVersion = 11;
+ } else if (options.ecmaVersion >= 2015) {
+ options.ecmaVersion -= 2009;
+ }
+
+ if (options.allowReserved == null)
+ { options.allowReserved = options.ecmaVersion < 5; }
+
+ if (!opts || opts.allowHashBang == null)
+ { options.allowHashBang = options.ecmaVersion >= 14; }
+
+ if (isArray(options.onToken)) {
+ var tokens = options.onToken;
+ options.onToken = function (token) { return tokens.push(token); };
+ }
+ if (isArray(options.onComment))
+ { options.onComment = pushComment(options, options.onComment); }
+
+ return options
+ }
+
+ function pushComment(options, array) {
+ return function(block, text, start, end, startLoc, endLoc) {
+ var comment = {
+ type: block ? "Block" : "Line",
+ value: text,
+ start: start,
+ end: end
+ };
+ if (options.locations)
+ { comment.loc = new SourceLocation(this, startLoc, endLoc); }
+ if (options.ranges)
+ { comment.range = [start, end]; }
+ array.push(comment);
+ }
+ }
+
+ var
+ SCOPE_TOP = 1,
+ SCOPE_FUNCTION = 2,
+ SCOPE_ASYNC = 4,
+ SCOPE_GENERATOR = 8,
+ SCOPE_ARROW = 16,
+ SCOPE_SIMPLE_CATCH = 32,
+ SCOPE_SUPER = 64,
+ SCOPE_DIRECT_SUPER = 128,
+ SCOPE_CLASS_STATIC_BLOCK = 256,
+ SCOPE_VAR = SCOPE_TOP | SCOPE_FUNCTION | SCOPE_CLASS_STATIC_BLOCK;
+
+ function functionFlags(async, generator) {
+ return SCOPE_FUNCTION | (async ? SCOPE_ASYNC : 0) | (generator ? SCOPE_GENERATOR : 0)
+ }
+
+ var
+ BIND_NONE = 0,
+ BIND_VAR = 1,
+ BIND_LEXICAL = 2,
+ BIND_FUNCTION = 3,
+ BIND_SIMPLE_CATCH = 4,
+ BIND_OUTSIDE = 5;
+
+ var Parser = function Parser(options, input, startPos) {
+ this.options = options = getOptions(options);
+ this.sourceFile = options.sourceFile;
+ this.keywords = wordsRegexp(keywords$1[options.ecmaVersion >= 6 ? 6 : options.sourceType === "module" ? "5module" : 5]);
+ var reserved = "";
+ if (options.allowReserved !== true) {
+ reserved = reservedWords[options.ecmaVersion >= 6 ? 6 : options.ecmaVersion === 5 ? 5 : 3];
+ if (options.sourceType === "module") { reserved += " await"; }
+ }
+ this.reservedWords = wordsRegexp(reserved);
+ var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict;
+ this.reservedWordsStrict = wordsRegexp(reservedStrict);
+ this.reservedWordsStrictBind = wordsRegexp(reservedStrict + " " + reservedWords.strictBind);
+ this.input = String(input);
+
+ this.containsEsc = false;
+
+
+ if (startPos) {
+ this.pos = startPos;
+ this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1;
+ this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length;
+ } else {
+ this.pos = this.lineStart = 0;
+ this.curLine = 1;
+ }
+
+ this.type = types$1.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 = true;
+
+ this.inModule = options.sourceType === "module";
+ this.strict = this.inModule || this.strictDirective(this.pos);
+
+ this.potentialArrowAt = -1;
+ this.potentialArrowInForAwait = false;
+
+ this.yieldPos = this.awaitPos = this.awaitIdentPos = 0;
+ this.labels = [];
+ this.undefinedExports = Object.create(null);
+
+ if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!")
+ { this.skipLineComment(2); }
+
+ this.scopeStack = [];
+ this.enterScope(SCOPE_TOP);
+
+ this.regexpState = null;
+
+ this.privateNameStack = [];
+ };
+
+ var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },canAwait: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true },allowNewDotTarget: { configurable: true },inClassStaticBlock: { configurable: true } };
+
+ Parser.prototype.parse = function parse () {
+ var node = this.options.program || this.startNode();
+ this.nextToken();
+ return this.parseTopLevel(node)
+ };
+
+ prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 };
+
+ prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 && !this.currentVarScope().inClassFieldInit };
+
+ prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 && !this.currentVarScope().inClassFieldInit };
+
+ prototypeAccessors.canAwait.get = function () {
+ for (var i = this.scopeStack.length - 1; i >= 0; i--) {
+ var scope = this.scopeStack[i];
+ if (scope.inClassFieldInit || scope.flags & SCOPE_CLASS_STATIC_BLOCK) { return false }
+ if (scope.flags & SCOPE_FUNCTION) { return (scope.flags & SCOPE_ASYNC) > 0 }
+ }
+ return (this.inModule && this.options.ecmaVersion >= 13) || this.options.allowAwaitOutsideFunction
+ };
+
+ prototypeAccessors.allowSuper.get = function () {
+ var ref = this.currentThisScope();
+ var flags = ref.flags;
+ var inClassFieldInit = ref.inClassFieldInit;
+ return (flags & SCOPE_SUPER) > 0 || inClassFieldInit || this.options.allowSuperOutsideMethod
+ };
+
+ prototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 };
+
+ prototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) };
+
+ prototypeAccessors.allowNewDotTarget.get = function () {
+ var ref = this.currentThisScope();
+ var flags = ref.flags;
+ var inClassFieldInit = ref.inClassFieldInit;
+ return (flags & (SCOPE_FUNCTION | SCOPE_CLASS_STATIC_BLOCK)) > 0 || inClassFieldInit
+ };
+
+ prototypeAccessors.inClassStaticBlock.get = function () {
+ return (this.currentVarScope().flags & SCOPE_CLASS_STATIC_BLOCK) > 0
+ };
+
+ Parser.extend = function extend () {
+ var plugins = [], len = arguments.length;
+ while ( len-- ) plugins[ len ] = arguments[ len ];
+
+ var cls = this;
+ for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); }
+ return cls
+ };
+
+ Parser.parse = function parse (input, options) {
+ return new this(options, input).parse()
+ };
+
+ Parser.parseExpressionAt = function parseExpressionAt (input, pos, options) {
+ var parser = new this(options, input, pos);
+ parser.nextToken();
+ return parser.parseExpression()
+ };
+
+ Parser.tokenizer = function tokenizer (input, options) {
+ return new this(options, input)
+ };
+
+ Object.defineProperties( Parser.prototype, prototypeAccessors );
+
+ var pp$9 = Parser.prototype;
+
+
+ var literal = /^(?:'((?:\\[^]|[^'\\])*?)'|"((?:\\[^]|[^"\\])*?)")/;
+ pp$9.strictDirective = function(start) {
+ if (this.options.ecmaVersion < 5) { return false }
+ for (;;) {
+ skipWhiteSpace.lastIndex = start;
+ start += skipWhiteSpace.exec(this.input)[0].length;
+ var match = literal.exec(this.input.slice(start));
+ if (!match) { return false }
+ if ((match[1] || match[2]) === "use strict") {
+ skipWhiteSpace.lastIndex = start + match[0].length;
+ var spaceAfter = skipWhiteSpace.exec(this.input), end = spaceAfter.index + spaceAfter[0].length;
+ var next = this.input.charAt(end);
+ return next === ";" || next === "}" ||
+ (lineBreak.test(spaceAfter[0]) &&
+ !(/[(`.[+\-/*%<>=,?^&]/.test(next) || next === "!" && this.input.charAt(end + 1) === "="))
+ }
+ start += match[0].length;
+
+ skipWhiteSpace.lastIndex = start;
+ start += skipWhiteSpace.exec(this.input)[0].length;
+ if (this.input[start] === ";")
+ { start++; }
+ }
+ };
+
+
+ pp$9.eat = function(type) {
+ if (this.type === type) {
+ this.next();
+ return true
+ } else {
+ return false
+ }
+ };
+
+
+ pp$9.isContextual = function(name) {
+ return this.type === types$1.name && this.value === name && !this.containsEsc
+ };
+
+
+ pp$9.eatContextual = function(name) {
+ if (!this.isContextual(name)) { return false }
+ this.next();
+ return true
+ };
+
+
+ pp$9.expectContextual = function(name) {
+ if (!this.eatContextual(name)) { this.unexpected(); }
+ };
+
+
+ pp$9.canInsertSemicolon = function() {
+ return this.type === types$1.eof ||
+ this.type === types$1.braceR ||
+ lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
+ };
+
+ pp$9.insertSemicolon = function() {
+ if (this.canInsertSemicolon()) {
+ if (this.options.onInsertedSemicolon)
+ { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); }
+ return true
+ }
+ };
+
+
+ pp$9.semicolon = function() {
+ if (!this.eat(types$1.semi) && !this.insertSemicolon()) { this.unexpected(); }
+ };
+
+ pp$9.afterTrailingComma = function(tokType, notNext) {
+ if (this.type === tokType) {
+ if (this.options.onTrailingComma)
+ { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); }
+ if (!notNext)
+ { this.next(); }
+ return true
+ }
+ };
+
+
+ pp$9.expect = function(type) {
+ this.eat(type) || this.unexpected();
+ };
+
+
+ pp$9.unexpected = function(pos) {
+ this.raise(pos != null ? pos : this.start, "Unexpected token");
+ };
+
+ var DestructuringErrors = function DestructuringErrors() {
+ this.shorthandAssign =
+ this.trailingComma =
+ this.parenthesizedAssign =
+ this.parenthesizedBind =
+ this.doubleProto =
+ -1;
+ };
+
+ pp$9.checkPatternErrors = function(refDestructuringErrors, isAssign) {
+ if (!refDestructuringErrors) { return }
+ if (refDestructuringErrors.trailingComma > -1)
+ { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); }
+ var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind;
+ if (parens > -1) { this.raiseRecoverable(parens, isAssign ? "Assigning to rvalue" : "Parenthesized pattern"); }
+ };
+
+ pp$9.checkExpressionErrors = function(refDestructuringErrors, andThrow) {
+ if (!refDestructuringErrors) { return false }
+ var shorthandAssign = refDestructuringErrors.shorthandAssign;
+ var doubleProto = refDestructuringErrors.doubleProto;
+ if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 }
+ if (shorthandAssign >= 0)
+ { this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); }
+ if (doubleProto >= 0)
+ { this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); }
+ };
+
+ pp$9.checkYieldAwaitInDefaultParams = function() {
+ if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos))
+ { this.raise(this.yieldPos, "Yield expression cannot be a default value"); }
+ if (this.awaitPos)
+ { this.raise(this.awaitPos, "Await expression cannot be a default value"); }
+ };
+
+ pp$9.isSimpleAssignTarget = function(expr) {
+ if (expr.type === "ParenthesizedExpression")
+ { return this.isSimpleAssignTarget(expr.expression) }
+ return expr.type === "Identifier" || expr.type === "MemberExpression"
+ };
+
+ var pp$8 = Parser.prototype;
+
+
+
+ pp$8.parseTopLevel = function(node) {
+ var exports = Object.create(null);
+ if (!node.body) { node.body = []; }
+ while (this.type !== types$1.eof) {
+ var stmt = this.parseStatement(null, true, exports);
+ node.body.push(stmt);
+ }
+ if (this.inModule)
+ { for (var i = 0, list = Object.keys(this.undefinedExports); i < list.length; i += 1)
+ {
+ var name = list[i];
+
+ this.raiseRecoverable(this.undefinedExports[name].start, ("Export '" + name + "' is not defined"));
+ } }
+ this.adaptDirectivePrologue(node.body);
+ this.next();
+ node.sourceType = this.options.sourceType;
+ return this.finishNode(node, "Program")
+ };
+
+ var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"};
+
+ pp$8.isLet = function(context) {
+ if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false }
+ skipWhiteSpace.lastIndex = this.pos;
+ var skip = skipWhiteSpace.exec(this.input);
+ var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);
+ if (nextCh === 91 || nextCh === 92) { return true }
+ if (context) { return false }
+
+ if (nextCh === 123 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true }
+ if (isIdentifierStart(nextCh, true)) {
+ var pos = next + 1;
+ while (isIdentifierChar(nextCh = this.input.charCodeAt(pos), true)) { ++pos; }
+ if (nextCh === 92 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true }
+ var ident = this.input.slice(next, pos);
+ if (!keywordRelationalOperator.test(ident)) { return true }
+ }
+ return false
+ };
+
+ pp$8.isAsyncFunction = function() {
+ if (this.options.ecmaVersion < 8 || !this.isContextual("async"))
+ { return false }
+
+ skipWhiteSpace.lastIndex = this.pos;
+ var skip = skipWhiteSpace.exec(this.input);
+ var next = this.pos + skip[0].length, after;
+ return !lineBreak.test(this.input.slice(this.pos, next)) &&
+ this.input.slice(next, next + 8) === "function" &&
+ (next + 8 === this.input.length ||
+ !(isIdentifierChar(after = this.input.charCodeAt(next + 8)) || after > 0xd7ff && after < 0xdc00))
+ };
+
+
+ pp$8.parseStatement = function(context, topLevel, exports) {
+ var starttype = this.type, node = this.startNode(), kind;
+
+ if (this.isLet(context)) {
+ starttype = types$1._var;
+ kind = "let";
+ }
+
+
+ switch (starttype) {
+ case types$1._break: case types$1._continue: return this.parseBreakContinueStatement(node, starttype.keyword)
+ case types$1._debugger: return this.parseDebuggerStatement(node)
+ case types$1._do: return this.parseDoStatement(node)
+ case types$1._for: return this.parseForStatement(node)
+ case types$1._function:
+ if ((context && (this.strict || context !== "if" && context !== "label")) && this.options.ecmaVersion >= 6) { this.unexpected(); }
+ return this.parseFunctionStatement(node, false, !context)
+ case types$1._class:
+ if (context) { this.unexpected(); }
+ return this.parseClass(node, true)
+ case types$1._if: return this.parseIfStatement(node)
+ case types$1._return: return this.parseReturnStatement(node)
+ case types$1._switch: return this.parseSwitchStatement(node)
+ case types$1._throw: return this.parseThrowStatement(node)
+ case types$1._try: return this.parseTryStatement(node)
+ case types$1._const: case types$1._var:
+ kind = kind || this.value;
+ if (context && kind !== "var") { this.unexpected(); }
+ return this.parseVarStatement(node, kind)
+ case types$1._while: return this.parseWhileStatement(node)
+ case types$1._with: return this.parseWithStatement(node)
+ case types$1.braceL: return this.parseBlock(true, node)
+ case types$1.semi: return this.parseEmptyStatement(node)
+ case types$1._export:
+ case types$1._import:
+ if (this.options.ecmaVersion > 10 && starttype === types$1._import) {
+ skipWhiteSpace.lastIndex = this.pos;
+ var skip = skipWhiteSpace.exec(this.input);
+ var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);
+ if (nextCh === 40 || nextCh === 46)
+ { return this.parseExpressionStatement(node, this.parseExpression()) }
+ }
+
+ if (!this.options.allowImportExportEverywhere) {
+ if (!topLevel)
+ { this.raise(this.start, "'import' and 'export' may only appear at the top level"); }
+ if (!this.inModule)
+ { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); }
+ }
+ return starttype === types$1._import ? this.parseImport(node) : this.parseExport(node, exports)
+
+ default:
+ if (this.isAsyncFunction()) {
+ if (context) { this.unexpected(); }
+ this.next();
+ return this.parseFunctionStatement(node, true, !context)
+ }
+
+ var maybeName = this.value, expr = this.parseExpression();
+ if (starttype === types$1.name && expr.type === "Identifier" && this.eat(types$1.colon))
+ { return this.parseLabeledStatement(node, maybeName, expr, context) }
+ else { return this.parseExpressionStatement(node, expr) }
+ }
+ };
+
+ pp$8.parseBreakContinueStatement = function(node, keyword) {
+ var isBreak = keyword === "break";
+ this.next();
+ if (this.eat(types$1.semi) || this.insertSemicolon()) { node.label = null; }
+ else if (this.type !== types$1.name) { this.unexpected(); }
+ else {
+ node.label = this.parseIdent();
+ this.semicolon();
+ }
+
+ var i = 0;
+ for (; i < this.labels.length; ++i) {
+ var lab = this.labels[i];
+ if (node.label == null || lab.name === node.label.name) {
+ if (lab.kind != null && (isBreak || lab.kind === "loop")) { break }
+ if (node.label && isBreak) { break }
+ }
+ }
+ if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); }
+ return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement")
+ };
+
+ pp$8.parseDebuggerStatement = function(node) {
+ this.next();
+ this.semicolon();
+ return this.finishNode(node, "DebuggerStatement")
+ };
+
+ pp$8.parseDoStatement = function(node) {
+ this.next();
+ this.labels.push(loopLabel);
+ node.body = this.parseStatement("do");
+ this.labels.pop();
+ this.expect(types$1._while);
+ node.test = this.parseParenExpression();
+ if (this.options.ecmaVersion >= 6)
+ { this.eat(types$1.semi); }
+ else
+ { this.semicolon(); }
+ return this.finishNode(node, "DoWhileStatement")
+ };
+
+
+ pp$8.parseForStatement = function(node) {
+ this.next();
+ var awaitAt = (this.options.ecmaVersion >= 9 && this.canAwait && this.eatContextual("await")) ? this.lastTokStart : -1;
+ this.labels.push(loopLabel);
+ this.enterScope(0);
+ this.expect(types$1.parenL);
+ if (this.type === types$1.semi) {
+ if (awaitAt > -1) { this.unexpected(awaitAt); }
+ return this.parseFor(node, null)
+ }
+ var isLet = this.isLet();
+ if (this.type === types$1._var || this.type === types$1._const || isLet) {
+ var init$1 = this.startNode(), kind = isLet ? "let" : this.value;
+ this.next();
+ this.parseVar(init$1, true, kind);
+ this.finishNode(init$1, "VariableDeclaration");
+ if ((this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1) {
+ if (this.options.ecmaVersion >= 9) {
+ if (this.type === types$1._in) {
+ if (awaitAt > -1) { this.unexpected(awaitAt); }
+ } else { node.await = awaitAt > -1; }
+ }
+ return this.parseForIn(node, init$1)
+ }
+ if (awaitAt > -1) { this.unexpected(awaitAt); }
+ return this.parseFor(node, init$1)
+ }
+ var startsWithLet = this.isContextual("let"), isForOf = false;
+ var containsEsc = this.containsEsc;
+ var refDestructuringErrors = new DestructuringErrors;
+ var initPos = this.start;
+ var init = awaitAt > -1
+ ? this.parseExprSubscripts(refDestructuringErrors, "await")
+ : this.parseExpression(true, refDestructuringErrors);
+ if (this.type === types$1._in || (isForOf = this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
+ if (awaitAt > -1) {
+ if (this.type === types$1._in) { this.unexpected(awaitAt); }
+ node.await = true;
+ } else if (isForOf && this.options.ecmaVersion >= 8) {
+ if (init.start === initPos && !containsEsc && init.type === "Identifier" && init.name === "async") { this.unexpected(); }
+ else if (this.options.ecmaVersion >= 9) { node.await = false; }
+ }
+ if (startsWithLet && isForOf) { this.raise(init.start, "The left-hand side of a for-of loop may not start with 'let'."); }
+ this.toAssignable(init, false, refDestructuringErrors);
+ this.checkLValPattern(init);
+ return this.parseForIn(node, init)
+ } else {
+ this.checkExpressionErrors(refDestructuringErrors, true);
+ }
+ if (awaitAt > -1) { this.unexpected(awaitAt); }
+ return this.parseFor(node, init)
+ };
+
+ pp$8.parseFunctionStatement = function(node, isAsync, declarationPosition) {
+ this.next();
+ return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync)
+ };
+
+ pp$8.parseIfStatement = function(node) {
+ this.next();
+ node.test = this.parseParenExpression();
+ node.consequent = this.parseStatement("if");
+ node.alternate = this.eat(types$1._else) ? this.parseStatement("if") : null;
+ return this.finishNode(node, "IfStatement")
+ };
+
+ pp$8.parseReturnStatement = function(node) {
+ if (!this.inFunction && !this.options.allowReturnOutsideFunction)
+ { this.raise(this.start, "'return' outside of function"); }
+ this.next();
+
+
+ if (this.eat(types$1.semi) || this.insertSemicolon()) { node.argument = null; }
+ else { node.argument = this.parseExpression(); this.semicolon(); }
+ return this.finishNode(node, "ReturnStatement")
+ };
+
+ pp$8.parseSwitchStatement = function(node) {
+ this.next();
+ node.discriminant = this.parseParenExpression();
+ node.cases = [];
+ this.expect(types$1.braceL);
+ this.labels.push(switchLabel);
+ this.enterScope(0);
+
+
+ var cur;
+ for (var sawDefault = false; this.type !== types$1.braceR;) {
+ if (this.type === types$1._case || this.type === types$1._default) {
+ var isCase = this.type === types$1._case;
+ if (cur) { this.finishNode(cur, "SwitchCase"); }
+ node.cases.push(cur = this.startNode());
+ cur.consequent = [];
+ this.next();
+ if (isCase) {
+ cur.test = this.parseExpression();
+ } else {
+ if (sawDefault) { this.raiseRecoverable(this.lastTokStart, "Multiple default clauses"); }
+ sawDefault = true;
+ cur.test = null;
+ }
+ this.expect(types$1.colon);
+ } else {
+ if (!cur) { this.unexpected(); }
+ cur.consequent.push(this.parseStatement(null));
+ }
+ }
+ this.exitScope();
+ if (cur) { this.finishNode(cur, "SwitchCase"); }
+ this.next();
+ this.labels.pop();
+ return this.finishNode(node, "SwitchStatement")
+ };
+
+ pp$8.parseThrowStatement = function(node) {
+ this.next();
+ if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start)))
+ { this.raise(this.lastTokEnd, "Illegal newline after throw"); }
+ node.argument = this.parseExpression();
+ this.semicolon();
+ return this.finishNode(node, "ThrowStatement")
+ };
+
+
+ var empty$1 = [];
+
+ pp$8.parseCatchClauseParam = function() {
+ var param = this.parseBindingAtom();
+ var simple = param.type === "Identifier";
+ this.enterScope(simple ? SCOPE_SIMPLE_CATCH : 0);
+ this.checkLValPattern(param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL);
+ this.expect(types$1.parenR);
+
+ return param
+ };
+
+ pp$8.parseTryStatement = function(node) {
+ this.next();
+ node.block = this.parseBlock();
+ node.handler = null;
+ if (this.type === types$1._catch) {
+ var clause = this.startNode();
+ this.next();
+ if (this.eat(types$1.parenL)) {
+ clause.param = this.parseCatchClauseParam();
+ } else {
+ if (this.options.ecmaVersion < 10) { this.unexpected(); }
+ clause.param = null;
+ this.enterScope(0);
+ }
+ clause.body = this.parseBlock(false);
+ this.exitScope();
+ node.handler = this.finishNode(clause, "CatchClause");
+ }
+ node.finalizer = this.eat(types$1._finally) ? this.parseBlock() : null;
+ if (!node.handler && !node.finalizer)
+ { this.raise(node.start, "Missing catch or finally clause"); }
+ return this.finishNode(node, "TryStatement")
+ };
+
+ pp$8.parseVarStatement = function(node, kind, allowMissingInitializer) {
+ this.next();
+ this.parseVar(node, false, kind, allowMissingInitializer);
+ this.semicolon();
+ return this.finishNode(node, "VariableDeclaration")
+ };
+
+ pp$8.parseWhileStatement = function(node) {
+ this.next();
+ node.test = this.parseParenExpression();
+ this.labels.push(loopLabel);
+ node.body = this.parseStatement("while");
+ this.labels.pop();
+ return this.finishNode(node, "WhileStatement")
+ };
+
+ pp$8.parseWithStatement = function(node) {
+ if (this.strict) { this.raise(this.start, "'with' in strict mode"); }
+ this.next();
+ node.object = this.parseParenExpression();
+ node.body = this.parseStatement("with");
+ return this.finishNode(node, "WithStatement")
+ };
+
+ pp$8.parseEmptyStatement = function(node) {
+ this.next();
+ return this.finishNode(node, "EmptyStatement")
+ };
+
+ pp$8.parseLabeledStatement = function(node, maybeName, expr, context) {
+ for (var i$1 = 0, list = this.labels; i$1 < list.length; i$1 += 1)
+ {
+ var label = list[i$1];
+
+ if (label.name === maybeName)
+ { this.raise(expr.start, "Label '" + maybeName + "' is already declared");
+ } }
+ var kind = this.type.isLoop ? "loop" : this.type === types$1._switch ? "switch" : null;
+ for (var i = this.labels.length - 1; i >= 0; i--) {
+ var label$1 = this.labels[i];
+ if (label$1.statementStart === node.start) {
+ label$1.statementStart = this.start;
+ label$1.kind = kind;
+ } else { break }
+ }
+ this.labels.push({name: maybeName, kind: kind, statementStart: this.start});
+ node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label");
+ this.labels.pop();
+ node.label = expr;
+ return this.finishNode(node, "LabeledStatement")
+ };
+
+ pp$8.parseExpressionStatement = function(node, expr) {
+ node.expression = expr;
+ this.semicolon();
+ return this.finishNode(node, "ExpressionStatement")
+ };
+
+
+ pp$8.parseBlock = function(createNewLexicalScope, node, exitStrict) {
+ if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true;
+ if ( node === void 0 ) node = this.startNode();
+
+ node.body = [];
+ this.expect(types$1.braceL);
+ if (createNewLexicalScope) { this.enterScope(0); }
+ while (this.type !== types$1.braceR) {
+ var stmt = this.parseStatement(null);
+ node.body.push(stmt);
+ }
+ if (exitStrict) { this.strict = false; }
+ this.next();
+ if (createNewLexicalScope) { this.exitScope(); }
+ return this.finishNode(node, "BlockStatement")
+ };
+
+
+ pp$8.parseFor = function(node, init) {
+ node.init = init;
+ this.expect(types$1.semi);
+ node.test = this.type === types$1.semi ? null : this.parseExpression();
+ this.expect(types$1.semi);
+ node.update = this.type === types$1.parenR ? null : this.parseExpression();
+ this.expect(types$1.parenR);
+ node.body = this.parseStatement("for");
+ this.exitScope();
+ this.labels.pop();
+ return this.finishNode(node, "ForStatement")
+ };
+
+
+ pp$8.parseForIn = function(node, init) {
+ var isForIn = this.type === types$1._in;
+ this.next();
+
+ if (
+ init.type === "VariableDeclaration" &&
+ init.declarations[0].init != null &&
+ (
+ !isForIn ||
+ this.options.ecmaVersion < 8 ||
+ this.strict ||
+ init.kind !== "var" ||
+ init.declarations[0].id.type !== "Identifier"
+ )
+ ) {
+ this.raise(
+ init.start,
+ ((isForIn ? "for-in" : "for-of") + " loop variable declaration may not have an initializer")
+ );
+ }
+ node.left = init;
+ node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign();
+ this.expect(types$1.parenR);
+ node.body = this.parseStatement("for");
+ this.exitScope();
+ this.labels.pop();
+ return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement")
+ };
+
+
+ pp$8.parseVar = function(node, isFor, kind, allowMissingInitializer) {
+ node.declarations = [];
+ node.kind = kind;
+ for (;;) {
+ var decl = this.startNode();
+ this.parseVarId(decl, kind);
+ if (this.eat(types$1.eq)) {
+ decl.init = this.parseMaybeAssign(isFor);
+ } else if (!allowMissingInitializer && kind === "const" && !(this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) {
+ this.unexpected();
+ } else if (!allowMissingInitializer && decl.id.type !== "Identifier" && !(isFor && (this.type === types$1._in || this.isContextual("of")))) {
+ this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value");
+ } else {
+ decl.init = null;
+ }
+ node.declarations.push(this.finishNode(decl, "VariableDeclarator"));
+ if (!this.eat(types$1.comma)) { break }
+ }
+ return node
+ };
+
+ pp$8.parseVarId = function(decl, kind) {
+ decl.id = this.parseBindingAtom();
+ this.checkLValPattern(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false);
+ };
+
+ var FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4;
+
+
+ pp$8.parseFunction = function(node, statement, allowExpressionBody, isAsync, forInit) {
+ this.initFunction(node);
+ if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) {
+ if (this.type === types$1.star && (statement & FUNC_HANGING_STATEMENT))
+ { this.unexpected(); }
+ node.generator = this.eat(types$1.star);
+ }
+ if (this.options.ecmaVersion >= 8)
+ { node.async = !!isAsync; }
+
+ if (statement & FUNC_STATEMENT) {
+ node.id = (statement & FUNC_NULLABLE_ID) && this.type !== types$1.name ? null : this.parseIdent();
+ if (node.id && !(statement & FUNC_HANGING_STATEMENT))
+ { this.checkLValSimple(node.id, (this.strict || node.generator || node.async) ? this.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION); }
+ }
+
+ var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
+ this.yieldPos = 0;
+ this.awaitPos = 0;
+ this.awaitIdentPos = 0;
+ this.enterScope(functionFlags(node.async, node.generator));
+
+ if (!(statement & FUNC_STATEMENT))
+ { node.id = this.type === types$1.name ? this.parseIdent() : null; }
+
+ this.parseFunctionParams(node);
+ this.parseFunctionBody(node, allowExpressionBody, false, forInit);
+
+ this.yieldPos = oldYieldPos;
+ this.awaitPos = oldAwaitPos;
+ this.awaitIdentPos = oldAwaitIdentPos;
+ return this.finishNode(node, (statement & FUNC_STATEMENT) ? "FunctionDeclaration" : "FunctionExpression")
+ };
+
+ pp$8.parseFunctionParams = function(node) {
+ this.expect(types$1.parenL);
+ node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8);
+ this.checkYieldAwaitInDefaultParams();
+ };
+
+
+ pp$8.parseClass = function(node, isStatement) {
+ this.next();
+
+ var oldStrict = this.strict;
+ this.strict = true;
+
+ this.parseClassId(node, isStatement);
+ this.parseClassSuper(node);
+ var privateNameMap = this.enterClassBody();
+ var classBody = this.startNode();
+ var hadConstructor = false;
+ classBody.body = [];
+ this.expect(types$1.braceL);
+ while (this.type !== types$1.braceR) {
+ var element = this.parseClassElement(node.superClass !== null);
+ if (element) {
+ classBody.body.push(element);
+ if (element.type === "MethodDefinition" && element.kind === "constructor") {
+ if (hadConstructor) { this.raiseRecoverable(element.start, "Duplicate constructor in the same class"); }
+ hadConstructor = true;
+ } else if (element.key && element.key.type === "PrivateIdentifier" && isPrivateNameConflicted(privateNameMap, element)) {
+ this.raiseRecoverable(element.key.start, ("Identifier '#" + (element.key.name) + "' has already been declared"));
+ }
+ }
+ }
+ this.strict = oldStrict;
+ this.next();
+ node.body = this.finishNode(classBody, "ClassBody");
+ this.exitClassBody();
+ return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression")
+ };
+
+ pp$8.parseClassElement = function(constructorAllowsSuper) {
+ if (this.eat(types$1.semi)) { return null }
+
+ var ecmaVersion = this.options.ecmaVersion;
+ var node = this.startNode();
+ var keyName = "";
+ var isGenerator = false;
+ var isAsync = false;
+ var kind = "method";
+ var isStatic = false;
+
+ if (this.eatContextual("static")) {
+ if (ecmaVersion >= 13 && this.eat(types$1.braceL)) {
+ this.parseClassStaticBlock(node);
+ return node
+ }
+ if (this.isClassElementNameStart() || this.type === types$1.star) {
+ isStatic = true;
+ } else {
+ keyName = "static";
+ }
+ }
+ node.static = isStatic;
+ if (!keyName && ecmaVersion >= 8 && this.eatContextual("async")) {
+ if ((this.isClassElementNameStart() || this.type === types$1.star) && !this.canInsertSemicolon()) {
+ isAsync = true;
+ } else {
+ keyName = "async";
+ }
+ }
+ if (!keyName && (ecmaVersion >= 9 || !isAsync) && this.eat(types$1.star)) {
+ isGenerator = true;
+ }
+ if (!keyName && !isAsync && !isGenerator) {
+ var lastValue = this.value;
+ if (this.eatContextual("get") || this.eatContextual("set")) {
+ if (this.isClassElementNameStart()) {
+ kind = lastValue;
+ } else {
+ keyName = lastValue;
+ }
+ }
+ }
+
+ if (keyName) {
+ node.computed = false;
+ node.key = this.startNodeAt(this.lastTokStart, this.lastTokStartLoc);
+ node.key.name = keyName;
+ this.finishNode(node.key, "Identifier");
+ } else {
+ this.parseClassElementName(node);
+ }
+
+ if (ecmaVersion < 13 || this.type === types$1.parenL || kind !== "method" || isGenerator || isAsync) {
+ var isConstructor = !node.static && checkKeyName(node, "constructor");
+ var allowsDirectSuper = isConstructor && constructorAllowsSuper;
+ if (isConstructor && kind !== "method") { this.raise(node.key.start, "Constructor can't have get/set modifier"); }
+ node.kind = isConstructor ? "constructor" : kind;
+ this.parseClassMethod(node, isGenerator, isAsync, allowsDirectSuper);
+ } else {
+ this.parseClassField(node);
+ }
+
+ return node
+ };
+
+ pp$8.isClassElementNameStart = function() {
+ return (
+ this.type === types$1.name ||
+ this.type === types$1.privateId ||
+ this.type === types$1.num ||
+ this.type === types$1.string ||
+ this.type === types$1.bracketL ||
+ this.type.keyword
+ )
+ };
+
+ pp$8.parseClassElementName = function(element) {
+ if (this.type === types$1.privateId) {
+ if (this.value === "constructor") {
+ this.raise(this.start, "Classes can't have an element named '#constructor'");
+ }
+ element.computed = false;
+ element.key = this.parsePrivateIdent();
+ } else {
+ this.parsePropertyName(element);
+ }
+ };
+
+ pp$8.parseClassMethod = function(method, isGenerator, isAsync, allowsDirectSuper) {
+ var key = method.key;
+ if (method.kind === "constructor") {
+ if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); }
+ if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); }
+ } else if (method.static && checkKeyName(method, "prototype")) {
+ this.raise(key.start, "Classes may not have a static property named prototype");
+ }
+
+ var value = method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper);
+
+ if (method.kind === "get" && value.params.length !== 0)
+ { this.raiseRecoverable(value.start, "getter should have no params"); }
+ if (method.kind === "set" && value.params.length !== 1)
+ { this.raiseRecoverable(value.start, "setter should have exactly one param"); }
+ if (method.kind === "set" && value.params[0].type === "RestElement")
+ { this.raiseRecoverable(value.params[0].start, "Setter cannot use rest params"); }
+
+ return this.finishNode(method, "MethodDefinition")
+ };
+
+ pp$8.parseClassField = function(field) {
+ if (checkKeyName(field, "constructor")) {
+ this.raise(field.key.start, "Classes can't have a field named 'constructor'");
+ } else if (field.static && checkKeyName(field, "prototype")) {
+ this.raise(field.key.start, "Classes can't have a static field named 'prototype'");
+ }
+
+ if (this.eat(types$1.eq)) {
+ var scope = this.currentThisScope();
+ var inClassFieldInit = scope.inClassFieldInit;
+ scope.inClassFieldInit = true;
+ field.value = this.parseMaybeAssign();
+ scope.inClassFieldInit = inClassFieldInit;
+ } else {
+ field.value = null;
+ }
+ this.semicolon();
+
+ return this.finishNode(field, "PropertyDefinition")
+ };
+
+ pp$8.parseClassStaticBlock = function(node) {
+ node.body = [];
+
+ var oldLabels = this.labels;
+ this.labels = [];
+ this.enterScope(SCOPE_CLASS_STATIC_BLOCK | SCOPE_SUPER);
+ while (this.type !== types$1.braceR) {
+ var stmt = this.parseStatement(null);
+ node.body.push(stmt);
+ }
+ this.next();
+ this.exitScope();
+ this.labels = oldLabels;
+
+ return this.finishNode(node, "StaticBlock")
+ };
+
+ pp$8.parseClassId = function(node, isStatement) {
+ if (this.type === types$1.name) {
+ node.id = this.parseIdent();
+ if (isStatement)
+ { this.checkLValSimple(node.id, BIND_LEXICAL, false); }
+ } else {
+ if (isStatement === true)
+ { this.unexpected(); }
+ node.id = null;
+ }
+ };
+
+ pp$8.parseClassSuper = function(node) {
+ node.superClass = this.eat(types$1._extends) ? this.parseExprSubscripts(null, false) : null;
+ };
+
+ pp$8.enterClassBody = function() {
+ var element = {declared: Object.create(null), used: []};
+ this.privateNameStack.push(element);
+ return element.declared
+ };
+
+ pp$8.exitClassBody = function() {
+ var ref = this.privateNameStack.pop();
+ var declared = ref.declared;
+ var used = ref.used;
+ if (!this.options.checkPrivateFields) { return }
+ var len = this.privateNameStack.length;
+ var parent = len === 0 ? null : this.privateNameStack[len - 1];
+ for (var i = 0; i < used.length; ++i) {
+ var id = used[i];
+ if (!hasOwn(declared, id.name)) {
+ if (parent) {
+ parent.used.push(id);
+ } else {
+ this.raiseRecoverable(id.start, ("Private field '#" + (id.name) + "' must be declared in an enclosing class"));
+ }
+ }
+ }
+ };
+
+ function isPrivateNameConflicted(privateNameMap, element) {
+ var name = element.key.name;
+ var curr = privateNameMap[name];
+
+ var next = "true";
+ if (element.type === "MethodDefinition" && (element.kind === "get" || element.kind === "set")) {
+ next = (element.static ? "s" : "i") + element.kind;
+ }
+
+ if (
+ curr === "iget" && next === "iset" ||
+ curr === "iset" && next === "iget" ||
+ curr === "sget" && next === "sset" ||
+ curr === "sset" && next === "sget"
+ ) {
+ privateNameMap[name] = "true";
+ return false
+ } else if (!curr) {
+ privateNameMap[name] = next;
+ return false
+ } else {
+ return true
+ }
+ }
+
+ function checkKeyName(node, name) {
+ var computed = node.computed;
+ var key = node.key;
+ return !computed && (
+ key.type === "Identifier" && key.name === name ||
+ key.type === "Literal" && key.value === name
+ )
+ }
+
+
+ pp$8.parseExportAllDeclaration = function(node, exports) {
+ if (this.options.ecmaVersion >= 11) {
+ if (this.eatContextual("as")) {
+ node.exported = this.parseModuleExportName();
+ this.checkExport(exports, node.exported, this.lastTokStart);
+ } else {
+ node.exported = null;
+ }
+ }
+ this.expectContextual("from");
+ if (this.type !== types$1.string) { this.unexpected(); }
+ node.source = this.parseExprAtom();
+ if (this.options.ecmaVersion >= 16)
+ { node.attributes = this.parseWithClause(); }
+ this.semicolon();
+ return this.finishNode(node, "ExportAllDeclaration")
+ };
+
+ pp$8.parseExport = function(node, exports) {
+ this.next();
+ if (this.eat(types$1.star)) {
+ return this.parseExportAllDeclaration(node, exports)
+ }
+ if (this.eat(types$1._default)) {
+ this.checkExport(exports, "default", this.lastTokStart);
+ node.declaration = this.parseExportDefaultDeclaration();
+ return this.finishNode(node, "ExportDefaultDeclaration")
+ }
+ if (this.shouldParseExportStatement()) {
+ node.declaration = this.parseExportDeclaration(node);
+ if (node.declaration.type === "VariableDeclaration")
+ { this.checkVariableExport(exports, node.declaration.declarations); }
+ else
+ { this.checkExport(exports, node.declaration.id, node.declaration.id.start); }
+ node.specifiers = [];
+ node.source = null;
+ } else {
+ node.declaration = null;
+ node.specifiers = this.parseExportSpecifiers(exports);
+ if (this.eatContextual("from")) {
+ if (this.type !== types$1.string) { this.unexpected(); }
+ node.source = this.parseExprAtom();
+ if (this.options.ecmaVersion >= 16)
+ { node.attributes = this.parseWithClause(); }
+ } else {
+ for (var i = 0, list = node.specifiers; i < list.length; i += 1) {
+ var spec = list[i];
+
+ this.checkUnreserved(spec.local);
+ this.checkLocalExport(spec.local);
+
+ if (spec.local.type === "Literal") {
+ this.raise(spec.local.start, "A string literal cannot be used as an exported binding without `from`.");
+ }
+ }
+
+ node.source = null;
+ }
+ this.semicolon();
+ }
+ return this.finishNode(node, "ExportNamedDeclaration")
+ };
+
+ pp$8.parseExportDeclaration = function(node) {
+ return this.parseStatement(null)
+ };
+
+ pp$8.parseExportDefaultDeclaration = function() {
+ var isAsync;
+ if (this.type === types$1._function || (isAsync = this.isAsyncFunction())) {
+ var fNode = this.startNode();
+ this.next();
+ if (isAsync) { this.next(); }
+ return this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync)
+ } else if (this.type === types$1._class) {
+ var cNode = this.startNode();
+ return this.parseClass(cNode, "nullableID")
+ } else {
+ var declaration = this.parseMaybeAssign();
+ this.semicolon();
+ return declaration
+ }
+ };
+
+ pp$8.checkExport = function(exports, name, pos) {
+ if (!exports) { return }
+ if (typeof name !== "string")
+ { name = name.type === "Identifier" ? name.name : name.value; }
+ if (hasOwn(exports, name))
+ { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); }
+ exports[name] = true;
+ };
+
+ pp$8.checkPatternExport = function(exports, pat) {
+ var type = pat.type;
+ if (type === "Identifier")
+ { this.checkExport(exports, pat, pat.start); }
+ else if (type === "ObjectPattern")
+ { for (var i = 0, list = pat.properties; i < list.length; i += 1)
+ {
+ var prop = list[i];
+
+ this.checkPatternExport(exports, prop);
+ } }
+ else if (type === "ArrayPattern")
+ { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) {
+ var elt = list$1[i$1];
+
+ if (elt) { this.checkPatternExport(exports, elt); }
+ } }
+ else if (type === "Property")
+ { this.checkPatternExport(exports, pat.value); }
+ else if (type === "AssignmentPattern")
+ { this.checkPatternExport(exports, pat.left); }
+ else if (type === "RestElement")
+ { this.checkPatternExport(exports, pat.argument); }
+ };
+
+ pp$8.checkVariableExport = function(exports, decls) {
+ if (!exports) { return }
+ for (var i = 0, list = decls; i < list.length; i += 1)
+ {
+ var decl = list[i];
+
+ this.checkPatternExport(exports, decl.id);
+ }
+ };
+
+ pp$8.shouldParseExportStatement = function() {
+ return this.type.keyword === "var" ||
+ this.type.keyword === "const" ||
+ this.type.keyword === "class" ||
+ this.type.keyword === "function" ||
+ this.isLet() ||
+ this.isAsyncFunction()
+ };
+
+
+ pp$8.parseExportSpecifier = function(exports) {
+ var node = this.startNode();
+ node.local = this.parseModuleExportName();
+
+ node.exported = this.eatContextual("as") ? this.parseModuleExportName() : node.local;
+ this.checkExport(
+ exports,
+ node.exported,
+ node.exported.start
+ );
+
+ return this.finishNode(node, "ExportSpecifier")
+ };
+
+ pp$8.parseExportSpecifiers = function(exports) {
+ var nodes = [], first = true;
+ this.expect(types$1.braceL);
+ while (!this.eat(types$1.braceR)) {
+ if (!first) {
+ this.expect(types$1.comma);
+ if (this.afterTrailingComma(types$1.braceR)) { break }
+ } else { first = false; }
+
+ nodes.push(this.parseExportSpecifier(exports));
+ }
+ return nodes
+ };
+
+
+ pp$8.parseImport = function(node) {
+ this.next();
+
+ if (this.type === types$1.string) {
+ node.specifiers = empty$1;
+ node.source = this.parseExprAtom();
+ } else {
+ node.specifiers = this.parseImportSpecifiers();
+ this.expectContextual("from");
+ node.source = this.type === types$1.string ? this.parseExprAtom() : this.unexpected();
+ }
+ if (this.options.ecmaVersion >= 16)
+ { node.attributes = this.parseWithClause(); }
+ this.semicolon();
+ return this.finishNode(node, "ImportDeclaration")
+ };
+
+
+ pp$8.parseImportSpecifier = function() {
+ var node = this.startNode();
+ node.imported = this.parseModuleExportName();
+
+ if (this.eatContextual("as")) {
+ node.local = this.parseIdent();
+ } else {
+ this.checkUnreserved(node.imported);
+ node.local = node.imported;
+ }
+ this.checkLValSimple(node.local, BIND_LEXICAL);
+
+ return this.finishNode(node, "ImportSpecifier")
+ };
+
+ pp$8.parseImportDefaultSpecifier = function() {
+ var node = this.startNode();
+ node.local = this.parseIdent();
+ this.checkLValSimple(node.local, BIND_LEXICAL);
+ return this.finishNode(node, "ImportDefaultSpecifier")
+ };
+
+ pp$8.parseImportNamespaceSpecifier = function() {
+ var node = this.startNode();
+ this.next();
+ this.expectContextual("as");
+ node.local = this.parseIdent();
+ this.checkLValSimple(node.local, BIND_LEXICAL);
+ return this.finishNode(node, "ImportNamespaceSpecifier")
+ };
+
+ pp$8.parseImportSpecifiers = function() {
+ var nodes = [], first = true;
+ if (this.type === types$1.name) {
+ nodes.push(this.parseImportDefaultSpecifier());
+ if (!this.eat(types$1.comma)) { return nodes }
+ }
+ if (this.type === types$1.star) {
+ nodes.push(this.parseImportNamespaceSpecifier());
+ return nodes
+ }
+ this.expect(types$1.braceL);
+ while (!this.eat(types$1.braceR)) {
+ if (!first) {
+ this.expect(types$1.comma);
+ if (this.afterTrailingComma(types$1.braceR)) { break }
+ } else { first = false; }
+
+ nodes.push(this.parseImportSpecifier());
+ }
+ return nodes
+ };
+
+ pp$8.parseWithClause = function() {
+ var nodes = [];
+ if (!this.eat(types$1._with)) {
+ return nodes
+ }
+ this.expect(types$1.braceL);
+ var attributeKeys = {};
+ var first = true;
+ while (!this.eat(types$1.braceR)) {
+ if (!first) {
+ this.expect(types$1.comma);
+ if (this.afterTrailingComma(types$1.braceR)) { break }
+ } else { first = false; }
+
+ var attr = this.parseImportAttribute();
+ var keyName = attr.key.type === "Identifier" ? attr.key.name : attr.key.value;
+ if (hasOwn(attributeKeys, keyName))
+ { this.raiseRecoverable(attr.key.start, "Duplicate attribute key '" + keyName + "'"); }
+ attributeKeys[keyName] = true;
+ nodes.push(attr);
+ }
+ return nodes
+ };
+
+ pp$8.parseImportAttribute = function() {
+ var node = this.startNode();
+ node.key = this.type === types$1.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never");
+ this.expect(types$1.colon);
+ if (this.type !== types$1.string) {
+ this.unexpected();
+ }
+ node.value = this.parseExprAtom();
+ return this.finishNode(node, "ImportAttribute")
+ };
+
+ pp$8.parseModuleExportName = function() {
+ if (this.options.ecmaVersion >= 13 && this.type === types$1.string) {
+ var stringLiteral = this.parseLiteral(this.value);
+ if (loneSurrogate.test(stringLiteral.value)) {
+ this.raise(stringLiteral.start, "An export name cannot include a lone surrogate.");
+ }
+ return stringLiteral
+ }
+ return this.parseIdent(true)
+ };
+
+ pp$8.adaptDirectivePrologue = function(statements) {
+ for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) {
+ statements[i].directive = statements[i].expression.raw.slice(1, -1);
+ }
+ };
+ pp$8.isDirectiveCandidate = function(statement) {
+ return (
+ this.options.ecmaVersion >= 5 &&
+ statement.type === "ExpressionStatement" &&
+ statement.expression.type === "Literal" &&
+ typeof statement.expression.value === "string" &&
+ (this.input[statement.start] === "\"" || this.input[statement.start] === "'")
+ )
+ };
+
+ var pp$7 = Parser.prototype;
+
+
+ pp$7.toAssignable = function(node, isBinding, refDestructuringErrors) {
+ if (this.options.ecmaVersion >= 6 && node) {
+ switch (node.type) {
+ case "Identifier":
+ if (this.inAsync && node.name === "await")
+ { this.raise(node.start, "Cannot use 'await' as identifier inside an async function"); }
+ break
+
+ case "ObjectPattern":
+ case "ArrayPattern":
+ case "AssignmentPattern":
+ case "RestElement":
+ break
+
+ case "ObjectExpression":
+ node.type = "ObjectPattern";
+ if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
+ for (var i = 0, list = node.properties; i < list.length; i += 1) {
+ var prop = list[i];
+
+ this.toAssignable(prop, isBinding);
+ if (
+ prop.type === "RestElement" &&
+ (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern")
+ ) {
+ this.raise(prop.argument.start, "Unexpected token");
+ }
+ }
+ break
+
+ case "Property":
+ if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); }
+ this.toAssignable(node.value, isBinding);
+ break
+
+ case "ArrayExpression":
+ node.type = "ArrayPattern";
+ if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
+ this.toAssignableList(node.elements, isBinding);
+ break
+
+ case "SpreadElement":
+ node.type = "RestElement";
+ this.toAssignable(node.argument, isBinding);
+ if (node.argument.type === "AssignmentPattern")
+ { this.raise(node.argument.start, "Rest elements cannot have a default value"); }
+ break
+
+ case "AssignmentExpression":
+ if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); }
+ node.type = "AssignmentPattern";
+ delete node.operator;
+ this.toAssignable(node.left, isBinding);
+ break
+
+ case "ParenthesizedExpression":
+ this.toAssignable(node.expression, isBinding, refDestructuringErrors);
+ break
+
+ case "ChainExpression":
+ this.raiseRecoverable(node.start, "Optional chaining cannot appear in left-hand side");
+ break
+
+ case "MemberExpression":
+ if (!isBinding) { break }
+
+ default:
+ this.raise(node.start, "Assigning to rvalue");
+ }
+ } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
+ return node
+ };
+
+
+ pp$7.toAssignableList = function(exprList, isBinding) {
+ var end = exprList.length;
+ for (var i = 0; i < end; i++) {
+ var elt = exprList[i];
+ if (elt) { this.toAssignable(elt, isBinding); }
+ }
+ if (end) {
+ var last = exprList[end - 1];
+ if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier")
+ { this.unexpected(last.argument.start); }
+ }
+ return exprList
+ };
+
+
+ pp$7.parseSpread = function(refDestructuringErrors) {
+ var node = this.startNode();
+ this.next();
+ node.argument = this.parseMaybeAssign(false, refDestructuringErrors);
+ return this.finishNode(node, "SpreadElement")
+ };
+
+ pp$7.parseRestBinding = function() {
+ var node = this.startNode();
+ this.next();
+
+ if (this.options.ecmaVersion === 6 && this.type !== types$1.name)
+ { this.unexpected(); }
+
+ node.argument = this.parseBindingAtom();
+
+ return this.finishNode(node, "RestElement")
+ };
+
+
+ pp$7.parseBindingAtom = function() {
+ if (this.options.ecmaVersion >= 6) {
+ switch (this.type) {
+ case types$1.bracketL:
+ var node = this.startNode();
+ this.next();
+ node.elements = this.parseBindingList(types$1.bracketR, true, true);
+ return this.finishNode(node, "ArrayPattern")
+
+ case types$1.braceL:
+ return this.parseObj(true)
+ }
+ }
+ return this.parseIdent()
+ };
+
+ pp$7.parseBindingList = function(close, allowEmpty, allowTrailingComma, allowModifiers) {
+ var elts = [], first = true;
+ while (!this.eat(close)) {
+ if (first) { first = false; }
+ else { this.expect(types$1.comma); }
+ if (allowEmpty && this.type === types$1.comma) {
+ elts.push(null);
+ } else if (allowTrailingComma && this.afterTrailingComma(close)) {
+ break
+ } else if (this.type === types$1.ellipsis) {
+ var rest = this.parseRestBinding();
+ this.parseBindingListItem(rest);
+ elts.push(rest);
+ if (this.type === types$1.comma) { this.raiseRecoverable(this.start, "Comma is not permitted after the rest element"); }
+ this.expect(close);
+ break
+ } else {
+ elts.push(this.parseAssignableListItem(allowModifiers));
+ }
+ }
+ return elts
+ };
+
+ pp$7.parseAssignableListItem = function(allowModifiers) {
+ var elem = this.parseMaybeDefault(this.start, this.startLoc);
+ this.parseBindingListItem(elem);
+ return elem
+ };
+
+ pp$7.parseBindingListItem = function(param) {
+ return param
+ };
+
+
+ pp$7.parseMaybeDefault = function(startPos, startLoc, left) {
+ left = left || this.parseBindingAtom();
+ if (this.options.ecmaVersion < 6 || !this.eat(types$1.eq)) { return left }
+ var node = this.startNodeAt(startPos, startLoc);
+ node.left = left;
+ node.right = this.parseMaybeAssign();
+ return this.finishNode(node, "AssignmentPattern")
+ };
+
+
+ pp$7.checkLValSimple = function(expr, bindingType, checkClashes) {
+ if ( bindingType === void 0 ) bindingType = BIND_NONE;
+
+ var isBind = bindingType !== BIND_NONE;
+
+ switch (expr.type) {
+ case "Identifier":
+ if (this.strict && this.reservedWordsStrictBind.test(expr.name))
+ { this.raiseRecoverable(expr.start, (isBind ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); }
+ if (isBind) {
+ if (bindingType === BIND_LEXICAL && expr.name === "let")
+ { this.raiseRecoverable(expr.start, "let is disallowed as a lexically bound name"); }
+ if (checkClashes) {
+ if (hasOwn(checkClashes, expr.name))
+ { this.raiseRecoverable(expr.start, "Argument name clash"); }
+ checkClashes[expr.name] = true;
+ }
+ if (bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); }
+ }
+ break
+
+ case "ChainExpression":
+ this.raiseRecoverable(expr.start, "Optional chaining cannot appear in left-hand side");
+ break
+
+ case "MemberExpression":
+ if (isBind) { this.raiseRecoverable(expr.start, "Binding member expression"); }
+ break
+
+ case "ParenthesizedExpression":
+ if (isBind) { this.raiseRecoverable(expr.start, "Binding parenthesized expression"); }
+ return this.checkLValSimple(expr.expression, bindingType, checkClashes)
+
+ default:
+ this.raise(expr.start, (isBind ? "Binding" : "Assigning to") + " rvalue");
+ }
+ };
+
+ pp$7.checkLValPattern = function(expr, bindingType, checkClashes) {
+ if ( bindingType === void 0 ) bindingType = BIND_NONE;
+
+ switch (expr.type) {
+ case "ObjectPattern":
+ for (var i = 0, list = expr.properties; i < list.length; i += 1) {
+ var prop = list[i];
+
+ this.checkLValInnerPattern(prop, bindingType, checkClashes);
+ }
+ break
+
+ case "ArrayPattern":
+ for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) {
+ var elem = list$1[i$1];
+
+ if (elem) { this.checkLValInnerPattern(elem, bindingType, checkClashes); }
+ }
+ break
+
+ default:
+ this.checkLValSimple(expr, bindingType, checkClashes);
+ }
+ };
+
+ pp$7.checkLValInnerPattern = function(expr, bindingType, checkClashes) {
+ if ( bindingType === void 0 ) bindingType = BIND_NONE;
+
+ switch (expr.type) {
+ case "Property":
+ this.checkLValInnerPattern(expr.value, bindingType, checkClashes);
+ break
+
+ case "AssignmentPattern":
+ this.checkLValPattern(expr.left, bindingType, checkClashes);
+ break
+
+ case "RestElement":
+ this.checkLValPattern(expr.argument, bindingType, checkClashes);
+ break
+
+ default:
+ this.checkLValPattern(expr, bindingType, checkClashes);
+ }
+ };
+
+
+
+ var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) {
+ this.token = token;
+ this.isExpr = !!isExpr;
+ this.preserveSpace = !!preserveSpace;
+ this.override = override;
+ this.generator = !!generator;
+ };
+
+ var types = {
+ b_stat: new TokContext("{", false),
+ b_expr: new TokContext("{", true),
+ b_tmpl: new TokContext("${", false),
+ p_stat: new TokContext("(", false),
+ p_expr: new TokContext("(", true),
+ q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }),
+ f_stat: new TokContext("function", false),
+ f_expr: new TokContext("function", true),
+ f_expr_gen: new TokContext("function", true, false, null, true),
+ f_gen: new TokContext("function", false, false, null, true)
+ };
+
+ var pp$6 = Parser.prototype;
+
+ pp$6.initialContext = function() {
+ return [types.b_stat]
+ };
+
+ pp$6.curContext = function() {
+ return this.context[this.context.length - 1]
+ };
+
+ pp$6.braceIsBlock = function(prevType) {
+ var parent = this.curContext();
+ if (parent === types.f_expr || parent === types.f_stat)
+ { return true }
+ if (prevType === types$1.colon && (parent === types.b_stat || parent === types.b_expr))
+ { return !parent.isExpr }
+
+ if (prevType === types$1._return || prevType === types$1.name && this.exprAllowed)
+ { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) }
+ if (prevType === types$1._else || prevType === types$1.semi || prevType === types$1.eof || prevType === types$1.parenR || prevType === types$1.arrow)
+ { return true }
+ if (prevType === types$1.braceL)
+ { return parent === types.b_stat }
+ if (prevType === types$1._var || prevType === types$1._const || prevType === types$1.name)
+ { return false }
+ return !this.exprAllowed
+ };
+
+ pp$6.inGeneratorContext = function() {
+ for (var i = this.context.length - 1; i >= 1; i--) {
+ var context = this.context[i];
+ if (context.token === "function")
+ { return context.generator }
+ }
+ return false
+ };
+
+ pp$6.updateContext = function(prevType) {
+ var update, type = this.type;
+ if (type.keyword && prevType === types$1.dot)
+ { this.exprAllowed = false; }
+ else if (update = type.updateContext)
+ { update.call(this, prevType); }
+ else
+ { this.exprAllowed = type.beforeExpr; }
+ };
+
+
+ pp$6.overrideContext = function(tokenCtx) {
+ if (this.curContext() !== tokenCtx) {
+ this.context[this.context.length - 1] = tokenCtx;
+ }
+ };
+
+
+ types$1.parenR.updateContext = types$1.braceR.updateContext = function() {
+ if (this.context.length === 1) {
+ this.exprAllowed = true;
+ return
+ }
+ var out = this.context.pop();
+ if (out === types.b_stat && this.curContext().token === "function") {
+ out = this.context.pop();
+ }
+ this.exprAllowed = !out.isExpr;
+ };
+
+ types$1.braceL.updateContext = function(prevType) {
+ this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr);
+ this.exprAllowed = true;
+ };
+
+ types$1.dollarBraceL.updateContext = function() {
+ this.context.push(types.b_tmpl);
+ this.exprAllowed = true;
+ };
+
+ types$1.parenL.updateContext = function(prevType) {
+ var statementParens = prevType === types$1._if || prevType === types$1._for || prevType === types$1._with || prevType === types$1._while;
+ this.context.push(statementParens ? types.p_stat : types.p_expr);
+ this.exprAllowed = true;
+ };
+
+ types$1.incDec.updateContext = function() {
+ };
+
+ types$1._function.updateContext = types$1._class.updateContext = function(prevType) {
+ if (prevType.beforeExpr && prevType !== types$1._else &&
+ !(prevType === types$1.semi && this.curContext() !== types.p_stat) &&
+ !(prevType === types$1._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) &&
+ !((prevType === types$1.colon || prevType === types$1.braceL) && this.curContext() === types.b_stat))
+ { this.context.push(types.f_expr); }
+ else
+ { this.context.push(types.f_stat); }
+ this.exprAllowed = false;
+ };
+
+ types$1.colon.updateContext = function() {
+ if (this.curContext().token === "function") { this.context.pop(); }
+ this.exprAllowed = true;
+ };
+
+ types$1.backQuote.updateContext = function() {
+ if (this.curContext() === types.q_tmpl)
+ { this.context.pop(); }
+ else
+ { this.context.push(types.q_tmpl); }
+ this.exprAllowed = false;
+ };
+
+ types$1.star.updateContext = function(prevType) {
+ if (prevType === types$1._function) {
+ var index = this.context.length - 1;
+ if (this.context[index] === types.f_expr)
+ { this.context[index] = types.f_expr_gen; }
+ else
+ { this.context[index] = types.f_gen; }
+ }
+ this.exprAllowed = true;
+ };
+
+ types$1.name.updateContext = function(prevType) {
+ var allowed = false;
+ if (this.options.ecmaVersion >= 6 && prevType !== types$1.dot) {
+ if (this.value === "of" && !this.exprAllowed ||
+ this.value === "yield" && this.inGeneratorContext())
+ { allowed = true; }
+ }
+ this.exprAllowed = allowed;
+ };
+
+
+
+ var pp$5 = Parser.prototype;
+
+
+ pp$5.checkPropClash = function(prop, propHash, refDestructuringErrors) {
+ if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement")
+ { return }
+ if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand))
+ { return }
+ var key = prop.key;
+ var name;
+ switch (key.type) {
+ case "Identifier": name = key.name; break
+ case "Literal": name = String(key.value); break
+ default: return
+ }
+ var kind = prop.kind;
+ if (this.options.ecmaVersion >= 6) {
+ if (name === "__proto__" && kind === "init") {
+ if (propHash.proto) {
+ if (refDestructuringErrors) {
+ if (refDestructuringErrors.doubleProto < 0) {
+ refDestructuringErrors.doubleProto = key.start;
+ }
+ } else {
+ this.raiseRecoverable(key.start, "Redefinition of __proto__ property");
+ }
+ }
+ propHash.proto = true;
+ }
+ return
+ }
+ name = "$" + name;
+ var other = propHash[name];
+ if (other) {
+ var redefinition;
+ if (kind === "init") {
+ redefinition = this.strict && other.init || other.get || other.set;
+ } else {
+ redefinition = other.init || other[kind];
+ }
+ if (redefinition)
+ { this.raiseRecoverable(key.start, "Redefinition of property"); }
+ } else {
+ other = propHash[name] = {
+ init: false,
+ get: false,
+ set: false
+ };
+ }
+ other[kind] = true;
+ };
+
+
+
+
+ pp$5.parseExpression = function(forInit, refDestructuringErrors) {
+ var startPos = this.start, startLoc = this.startLoc;
+ var expr = this.parseMaybeAssign(forInit, refDestructuringErrors);
+ if (this.type === types$1.comma) {
+ var node = this.startNodeAt(startPos, startLoc);
+ node.expressions = [expr];
+ while (this.eat(types$1.comma)) { node.expressions.push(this.parseMaybeAssign(forInit, refDestructuringErrors)); }
+ return this.finishNode(node, "SequenceExpression")
+ }
+ return expr
+ };
+
+
+ pp$5.parseMaybeAssign = function(forInit, refDestructuringErrors, afterLeftParse) {
+ if (this.isContextual("yield")) {
+ if (this.inGenerator) { return this.parseYield(forInit) }
+ else { this.exprAllowed = false; }
+ }
+
+ var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1, oldDoubleProto = -1;
+ if (refDestructuringErrors) {
+ oldParenAssign = refDestructuringErrors.parenthesizedAssign;
+ oldTrailingComma = refDestructuringErrors.trailingComma;
+ oldDoubleProto = refDestructuringErrors.doubleProto;
+ refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1;
+ } else {
+ refDestructuringErrors = new DestructuringErrors;
+ ownDestructuringErrors = true;
+ }
+
+ var startPos = this.start, startLoc = this.startLoc;
+ if (this.type === types$1.parenL || this.type === types$1.name) {
+ this.potentialArrowAt = this.start;
+ this.potentialArrowInForAwait = forInit === "await";
+ }
+ var left = this.parseMaybeConditional(forInit, refDestructuringErrors);
+ if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); }
+ if (this.type.isAssign) {
+ var node = this.startNodeAt(startPos, startLoc);
+ node.operator = this.value;
+ if (this.type === types$1.eq)
+ { left = this.toAssignable(left, false, refDestructuringErrors); }
+ if (!ownDestructuringErrors) {
+ refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1;
+ }
+ if (refDestructuringErrors.shorthandAssign >= left.start)
+ { refDestructuringErrors.shorthandAssign = -1; }
+ if (this.type === types$1.eq)
+ { this.checkLValPattern(left); }
+ else
+ { this.checkLValSimple(left); }
+ node.left = left;
+ this.next();
+ node.right = this.parseMaybeAssign(forInit);
+ if (oldDoubleProto > -1) { refDestructuringErrors.doubleProto = oldDoubleProto; }
+ return this.finishNode(node, "AssignmentExpression")
+ } else {
+ if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); }
+ }
+ if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; }
+ if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; }
+ return left
+ };
+
+
+ pp$5.parseMaybeConditional = function(forInit, refDestructuringErrors) {
+ var startPos = this.start, startLoc = this.startLoc;
+ var expr = this.parseExprOps(forInit, refDestructuringErrors);
+ if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
+ if (this.eat(types$1.question)) {
+ var node = this.startNodeAt(startPos, startLoc);
+ node.test = expr;
+ node.consequent = this.parseMaybeAssign();
+ this.expect(types$1.colon);
+ node.alternate = this.parseMaybeAssign(forInit);
+ return this.finishNode(node, "ConditionalExpression")
+ }
+ return expr
+ };
+
+
+ pp$5.parseExprOps = function(forInit, refDestructuringErrors) {
+ var startPos = this.start, startLoc = this.startLoc;
+ var expr = this.parseMaybeUnary(refDestructuringErrors, false, false, forInit);
+ if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
+ return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, forInit)
+ };
+
+
+ pp$5.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, forInit) {
+ var prec = this.type.binop;
+ if (prec != null && (!forInit || this.type !== types$1._in)) {
+ if (prec > minPrec) {
+ var logical = this.type === types$1.logicalOR || this.type === types$1.logicalAND;
+ var coalesce = this.type === types$1.coalesce;
+ if (coalesce) {
+ prec = types$1.logicalAND.binop;
+ }
+ var op = this.value;
+ this.next();
+ var startPos = this.start, startLoc = this.startLoc;
+ var right = this.parseExprOp(this.parseMaybeUnary(null, false, false, forInit), startPos, startLoc, prec, forInit);
+ var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical || coalesce);
+ if ((logical && this.type === types$1.coalesce) || (coalesce && (this.type === types$1.logicalOR || this.type === types$1.logicalAND))) {
+ this.raiseRecoverable(this.start, "Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses");
+ }
+ return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, forInit)
+ }
+ }
+ return left
+ };
+
+ pp$5.buildBinary = function(startPos, startLoc, left, right, op, logical) {
+ if (right.type === "PrivateIdentifier") { this.raise(right.start, "Private identifier can only be left side of binary expression"); }
+ var node = this.startNodeAt(startPos, startLoc);
+ node.left = left;
+ node.operator = op;
+ node.right = right;
+ return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression")
+ };
+
+
+ pp$5.parseMaybeUnary = function(refDestructuringErrors, sawUnary, incDec, forInit) {
+ var startPos = this.start, startLoc = this.startLoc, expr;
+ if (this.isContextual("await") && this.canAwait) {
+ expr = this.parseAwait(forInit);
+ sawUnary = true;
+ } else if (this.type.prefix) {
+ var node = this.startNode(), update = this.type === types$1.incDec;
+ node.operator = this.value;
+ node.prefix = true;
+ this.next();
+ node.argument = this.parseMaybeUnary(null, true, update, forInit);
+ this.checkExpressionErrors(refDestructuringErrors, true);
+ if (update) { this.checkLValSimple(node.argument); }
+ else if (this.strict && node.operator === "delete" && isLocalVariableAccess(node.argument))
+ { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); }
+ else if (node.operator === "delete" && isPrivateFieldAccess(node.argument))
+ { this.raiseRecoverable(node.start, "Private fields can not be deleted"); }
+ else { sawUnary = true; }
+ expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
+ } else if (!sawUnary && this.type === types$1.privateId) {
+ if ((forInit || this.privateNameStack.length === 0) && this.options.checkPrivateFields) { this.unexpected(); }
+ expr = this.parsePrivateIdent();
+ if (this.type !== types$1._in) { this.unexpected(); }
+ } else {
+ expr = this.parseExprSubscripts(refDestructuringErrors, forInit);
+ if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
+ while (this.type.postfix && !this.canInsertSemicolon()) {
+ var node$1 = this.startNodeAt(startPos, startLoc);
+ node$1.operator = this.value;
+ node$1.prefix = false;
+ node$1.argument = expr;
+ this.checkLValSimple(expr);
+ this.next();
+ expr = this.finishNode(node$1, "UpdateExpression");
+ }
+ }
+
+ if (!incDec && this.eat(types$1.starstar)) {
+ if (sawUnary)
+ { this.unexpected(this.lastTokStart); }
+ else
+ { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false, false, forInit), "**", false) }
+ } else {
+ return expr
+ }
+ };
+
+ function isLocalVariableAccess(node) {
+ return (
+ node.type === "Identifier" ||
+ node.type === "ParenthesizedExpression" && isLocalVariableAccess(node.expression)
+ )
+ }
+
+ function isPrivateFieldAccess(node) {
+ return (
+ node.type === "MemberExpression" && node.property.type === "PrivateIdentifier" ||
+ node.type === "ChainExpression" && isPrivateFieldAccess(node.expression) ||
+ node.type === "ParenthesizedExpression" && isPrivateFieldAccess(node.expression)
+ )
+ }
+
+
+ pp$5.parseExprSubscripts = function(refDestructuringErrors, forInit) {
+ var startPos = this.start, startLoc = this.startLoc;
+ var expr = this.parseExprAtom(refDestructuringErrors, forInit);
+ if (expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")")
+ { return expr }
+ var result = this.parseSubscripts(expr, startPos, startLoc, false, forInit);
+ if (refDestructuringErrors && result.type === "MemberExpression") {
+ if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; }
+ if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; }
+ if (refDestructuringErrors.trailingComma >= result.start) { refDestructuringErrors.trailingComma = -1; }
+ }
+ return result
+ };
+
+ pp$5.parseSubscripts = function(base, startPos, startLoc, noCalls, forInit) {
+ var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" &&
+ this.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 &&
+ this.potentialArrowAt === base.start;
+ var optionalChained = false;
+
+ while (true) {
+ var element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit);
+
+ if (element.optional) { optionalChained = true; }
+ if (element === base || element.type === "ArrowFunctionExpression") {
+ if (optionalChained) {
+ var chainNode = this.startNodeAt(startPos, startLoc);
+ chainNode.expression = element;
+ element = this.finishNode(chainNode, "ChainExpression");
+ }
+ return element
+ }
+
+ base = element;
+ }
+ };
+
+ pp$5.shouldParseAsyncArrow = function() {
+ return !this.canInsertSemicolon() && this.eat(types$1.arrow)
+ };
+
+ pp$5.parseSubscriptAsyncArrow = function(startPos, startLoc, exprList, forInit) {
+ return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true, forInit)
+ };
+
+ pp$5.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit) {
+ var optionalSupported = this.options.ecmaVersion >= 11;
+ var optional = optionalSupported && this.eat(types$1.questionDot);
+ if (noCalls && optional) { this.raise(this.lastTokStart, "Optional chaining cannot appear in the callee of new expressions"); }
+
+ var computed = this.eat(types$1.bracketL);
+ if (computed || (optional && this.type !== types$1.parenL && this.type !== types$1.backQuote) || this.eat(types$1.dot)) {
+ var node = this.startNodeAt(startPos, startLoc);
+ node.object = base;
+ if (computed) {
+ node.property = this.parseExpression();
+ this.expect(types$1.bracketR);
+ } else if (this.type === types$1.privateId && base.type !== "Super") {
+ node.property = this.parsePrivateIdent();
+ } else {
+ node.property = this.parseIdent(this.options.allowReserved !== "never");
+ }
+ node.computed = !!computed;
+ if (optionalSupported) {
+ node.optional = optional;
+ }
+ base = this.finishNode(node, "MemberExpression");
+ } else if (!noCalls && this.eat(types$1.parenL)) {
+ var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
+ this.yieldPos = 0;
+ this.awaitPos = 0;
+ this.awaitIdentPos = 0;
+ var exprList = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors);
+ if (maybeAsyncArrow && !optional && this.shouldParseAsyncArrow()) {
+ this.checkPatternErrors(refDestructuringErrors, false);
+ this.checkYieldAwaitInDefaultParams();
+ if (this.awaitIdentPos > 0)
+ { this.raise(this.awaitIdentPos, "Cannot use 'await' as identifier inside an async function"); }
+ this.yieldPos = oldYieldPos;
+ this.awaitPos = oldAwaitPos;
+ this.awaitIdentPos = oldAwaitIdentPos;
+ return this.parseSubscriptAsyncArrow(startPos, startLoc, exprList, forInit)
+ }
+ this.checkExpressionErrors(refDestructuringErrors, true);
+ this.yieldPos = oldYieldPos || this.yieldPos;
+ this.awaitPos = oldAwaitPos || this.awaitPos;
+ this.awaitIdentPos = oldAwaitIdentPos || this.awaitIdentPos;
+ var node$1 = this.startNodeAt(startPos, startLoc);
+ node$1.callee = base;
+ node$1.arguments = exprList;
+ if (optionalSupported) {
+ node$1.optional = optional;
+ }
+ base = this.finishNode(node$1, "CallExpression");
+ } else if (this.type === types$1.backQuote) {
+ if (optional || optionalChained) {
+ this.raise(this.start, "Optional chaining cannot appear in the tag of tagged template expressions");
+ }
+ var node$2 = this.startNodeAt(startPos, startLoc);
+ node$2.tag = base;
+ node$2.quasi = this.parseTemplate({isTagged: true});
+ base = this.finishNode(node$2, "TaggedTemplateExpression");
+ }
+ return base
+ };
+
+
+ pp$5.parseExprAtom = function(refDestructuringErrors, forInit, forNew) {
+ if (this.type === types$1.slash) { this.readRegexp(); }
+
+ var node, canBeArrow = this.potentialArrowAt === this.start;
+ switch (this.type) {
+ case types$1._super:
+ if (!this.allowSuper)
+ { this.raise(this.start, "'super' keyword outside a method"); }
+ node = this.startNode();
+ this.next();
+ if (this.type === types$1.parenL && !this.allowDirectSuper)
+ { this.raise(node.start, "super() call outside constructor of a subclass"); }
+ if (this.type !== types$1.dot && this.type !== types$1.bracketL && this.type !== types$1.parenL)
+ { this.unexpected(); }
+ return this.finishNode(node, "Super")
+
+ case types$1._this:
+ node = this.startNode();
+ this.next();
+ return this.finishNode(node, "ThisExpression")
+
+ case types$1.name:
+ var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc;
+ var id = this.parseIdent(false);
+ if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types$1._function)) {
+ this.overrideContext(types.f_expr);
+ return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, false, true, forInit)
+ }
+ if (canBeArrow && !this.canInsertSemicolon()) {
+ if (this.eat(types$1.arrow))
+ { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false, forInit) }
+ if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types$1.name && !containsEsc &&
+ (!this.potentialArrowInForAwait || this.value !== "of" || this.containsEsc)) {
+ id = this.parseIdent(false);
+ if (this.canInsertSemicolon() || !this.eat(types$1.arrow))
+ { this.unexpected(); }
+ return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true, forInit)
+ }
+ }
+ return id
+
+ case types$1.regexp:
+ var value = this.value;
+ node = this.parseLiteral(value.value);
+ node.regex = {pattern: value.pattern, flags: value.flags};
+ return node
+
+ case types$1.num: case types$1.string:
+ return this.parseLiteral(this.value)
+
+ case types$1._null: case types$1._true: case types$1._false:
+ node = this.startNode();
+ node.value = this.type === types$1._null ? null : this.type === types$1._true;
+ node.raw = this.type.keyword;
+ this.next();
+ return this.finishNode(node, "Literal")
+
+ case types$1.parenL:
+ var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow, forInit);
+ if (refDestructuringErrors) {
+ if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr))
+ { refDestructuringErrors.parenthesizedAssign = start; }
+ if (refDestructuringErrors.parenthesizedBind < 0)
+ { refDestructuringErrors.parenthesizedBind = start; }
+ }
+ return expr
+
+ case types$1.bracketL:
+ node = this.startNode();
+ this.next();
+ node.elements = this.parseExprList(types$1.bracketR, true, true, refDestructuringErrors);
+ return this.finishNode(node, "ArrayExpression")
+
+ case types$1.braceL:
+ this.overrideContext(types.b_expr);
+ return this.parseObj(false, refDestructuringErrors)
+
+ case types$1._function:
+ node = this.startNode();
+ this.next();
+ return this.parseFunction(node, 0)
+
+ case types$1._class:
+ return this.parseClass(this.startNode(), false)
+
+ case types$1._new:
+ return this.parseNew()
+
+ case types$1.backQuote:
+ return this.parseTemplate()
+
+ case types$1._import:
+ if (this.options.ecmaVersion >= 11) {
+ return this.parseExprImport(forNew)
+ } else {
+ return this.unexpected()
+ }
+
+ default:
+ return this.parseExprAtomDefault()
+ }
+ };
+
+ pp$5.parseExprAtomDefault = function() {
+ this.unexpected();
+ };
+
+ pp$5.parseExprImport = function(forNew) {
+ var node = this.startNode();
+
+ if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword import"); }
+ this.next();
+
+ if (this.type === types$1.parenL && !forNew) {
+ return this.parseDynamicImport(node)
+ } else if (this.type === types$1.dot) {
+ var meta = this.startNodeAt(node.start, node.loc && node.loc.start);
+ meta.name = "import";
+ node.meta = this.finishNode(meta, "Identifier");
+ return this.parseImportMeta(node)
+ } else {
+ this.unexpected();
+ }
+ };
+
+ pp$5.parseDynamicImport = function(node) {
+ this.next();
+
+ node.source = this.parseMaybeAssign();
+
+ if (this.options.ecmaVersion >= 16) {
+ if (!this.eat(types$1.parenR)) {
+ this.expect(types$1.comma);
+ if (!this.afterTrailingComma(types$1.parenR)) {
+ node.options = this.parseMaybeAssign();
+ if (!this.eat(types$1.parenR)) {
+ this.expect(types$1.comma);
+ if (!this.afterTrailingComma(types$1.parenR)) {
+ this.unexpected();
+ }
+ }
+ } else {
+ node.options = null;
+ }
+ } else {
+ node.options = null;
+ }
+ } else {
+ if (!this.eat(types$1.parenR)) {
+ var errorPos = this.start;
+ if (this.eat(types$1.comma) && this.eat(types$1.parenR)) {
+ this.raiseRecoverable(errorPos, "Trailing comma is not allowed in import()");
+ } else {
+ this.unexpected(errorPos);
+ }
+ }
+ }
+
+ return this.finishNode(node, "ImportExpression")
+ };
+
+ pp$5.parseImportMeta = function(node) {
+ this.next();
+
+ var containsEsc = this.containsEsc;
+ node.property = this.parseIdent(true);
+
+ if (node.property.name !== "meta")
+ { this.raiseRecoverable(node.property.start, "The only valid meta property for import is 'import.meta'"); }
+ if (containsEsc)
+ { this.raiseRecoverable(node.start, "'import.meta' must not contain escaped characters"); }
+ if (this.options.sourceType !== "module" && !this.options.allowImportExportEverywhere)
+ { this.raiseRecoverable(node.start, "Cannot use 'import.meta' outside a module"); }
+
+ return this.finishNode(node, "MetaProperty")
+ };
+
+ pp$5.parseLiteral = function(value) {
+ var node = this.startNode();
+ node.value = value;
+ node.raw = this.input.slice(this.start, this.end);
+ if (node.raw.charCodeAt(node.raw.length - 1) === 110) { node.bigint = node.raw.slice(0, -1).replace(/_/g, ""); }
+ this.next();
+ return this.finishNode(node, "Literal")
+ };
+
+ pp$5.parseParenExpression = function() {
+ this.expect(types$1.parenL);
+ var val = this.parseExpression();
+ this.expect(types$1.parenR);
+ return val
+ };
+
+ pp$5.shouldParseArrow = function(exprList) {
+ return !this.canInsertSemicolon()
+ };
+
+ pp$5.parseParenAndDistinguishExpression = function(canBeArrow, forInit) {
+ var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8;
+ if (this.options.ecmaVersion >= 6) {
+ this.next();
+
+ var innerStartPos = this.start, innerStartLoc = this.startLoc;
+ var exprList = [], first = true, lastIsComma = false;
+ var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart;
+ this.yieldPos = 0;
+ this.awaitPos = 0;
+ while (this.type !== types$1.parenR) {
+ first ? first = false : this.expect(types$1.comma);
+ if (allowTrailingComma && this.afterTrailingComma(types$1.parenR, true)) {
+ lastIsComma = true;
+ break
+ } else if (this.type === types$1.ellipsis) {
+ spreadStart = this.start;
+ exprList.push(this.parseParenItem(this.parseRestBinding()));
+ if (this.type === types$1.comma) {
+ this.raiseRecoverable(
+ this.start,
+ "Comma is not permitted after the rest element"
+ );
+ }
+ break
+ } else {
+ exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem));
+ }
+ }
+ var innerEndPos = this.lastTokEnd, innerEndLoc = this.lastTokEndLoc;
+ this.expect(types$1.parenR);
+
+ if (canBeArrow && this.shouldParseArrow(exprList) && this.eat(types$1.arrow)) {
+ this.checkPatternErrors(refDestructuringErrors, false);
+ this.checkYieldAwaitInDefaultParams();
+ this.yieldPos = oldYieldPos;
+ this.awaitPos = oldAwaitPos;
+ return this.parseParenArrowList(startPos, startLoc, exprList, forInit)
+ }
+
+ if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); }
+ if (spreadStart) { this.unexpected(spreadStart); }
+ this.checkExpressionErrors(refDestructuringErrors, true);
+ this.yieldPos = oldYieldPos || this.yieldPos;
+ this.awaitPos = oldAwaitPos || this.awaitPos;
+
+ if (exprList.length > 1) {
+ val = this.startNodeAt(innerStartPos, innerStartLoc);
+ val.expressions = exprList;
+ this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc);
+ } else {
+ val = exprList[0];
+ }
+ } else {
+ val = this.parseParenExpression();
+ }
+
+ if (this.options.preserveParens) {
+ var par = this.startNodeAt(startPos, startLoc);
+ par.expression = val;
+ return this.finishNode(par, "ParenthesizedExpression")
+ } else {
+ return val
+ }
+ };
+
+ pp$5.parseParenItem = function(item) {
+ return item
+ };
+
+ pp$5.parseParenArrowList = function(startPos, startLoc, exprList, forInit) {
+ return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, false, forInit)
+ };
+
+
+ var empty = [];
+
+ pp$5.parseNew = function() {
+ if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword new"); }
+ var node = this.startNode();
+ this.next();
+ if (this.options.ecmaVersion >= 6 && this.type === types$1.dot) {
+ var meta = this.startNodeAt(node.start, node.loc && node.loc.start);
+ meta.name = "new";
+ node.meta = this.finishNode(meta, "Identifier");
+ this.next();
+ var containsEsc = this.containsEsc;
+ node.property = this.parseIdent(true);
+ if (node.property.name !== "target")
+ { this.raiseRecoverable(node.property.start, "The only valid meta property for new is 'new.target'"); }
+ if (containsEsc)
+ { this.raiseRecoverable(node.start, "'new.target' must not contain escaped characters"); }
+ if (!this.allowNewDotTarget)
+ { this.raiseRecoverable(node.start, "'new.target' can only be used in functions and class static block"); }
+ return this.finishNode(node, "MetaProperty")
+ }
+ var startPos = this.start, startLoc = this.startLoc;
+ node.callee = this.parseSubscripts(this.parseExprAtom(null, false, true), startPos, startLoc, true, false);
+ if (this.eat(types$1.parenL)) { node.arguments = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false); }
+ else { node.arguments = empty; }
+ return this.finishNode(node, "NewExpression")
+ };
+
+
+ pp$5.parseTemplateElement = function(ref) {
+ var isTagged = ref.isTagged;
+
+ var elem = this.startNode();
+ if (this.type === types$1.invalidTemplate) {
+ if (!isTagged) {
+ this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal");
+ }
+ elem.value = {
+ raw: this.value.replace(/\r\n?/g, "\n"),
+ cooked: null
+ };
+ } else {
+ elem.value = {
+ raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"),
+ cooked: this.value
+ };
+ }
+ this.next();
+ elem.tail = this.type === types$1.backQuote;
+ return this.finishNode(elem, "TemplateElement")
+ };
+
+ pp$5.parseTemplate = function(ref) {
+ if ( ref === void 0 ) ref = {};
+ var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false;
+
+ var node = this.startNode();
+ this.next();
+ node.expressions = [];
+ var curElt = this.parseTemplateElement({isTagged: isTagged});
+ node.quasis = [curElt];
+ while (!curElt.tail) {
+ if (this.type === types$1.eof) { this.raise(this.pos, "Unterminated template literal"); }
+ this.expect(types$1.dollarBraceL);
+ node.expressions.push(this.parseExpression());
+ this.expect(types$1.braceR);
+ node.quasis.push(curElt = this.parseTemplateElement({isTagged: isTagged}));
+ }
+ this.next();
+ return this.finishNode(node, "TemplateLiteral")
+ };
+
+ pp$5.isAsyncProp = function(prop) {
+ return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" &&
+ (this.type === types$1.name || this.type === types$1.num || this.type === types$1.string || this.type === types$1.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types$1.star)) &&
+ !lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
+ };
+
+
+ pp$5.parseObj = function(isPattern, refDestructuringErrors) {
+ var node = this.startNode(), first = true, propHash = {};
+ node.properties = [];
+ this.next();
+ while (!this.eat(types$1.braceR)) {
+ if (!first) {
+ this.expect(types$1.comma);
+ if (this.options.ecmaVersion >= 5 && this.afterTrailingComma(types$1.braceR)) { break }
+ } else { first = false; }
+
+ var prop = this.parseProperty(isPattern, refDestructuringErrors);
+ if (!isPattern) { this.checkPropClash(prop, propHash, refDestructuringErrors); }
+ node.properties.push(prop);
+ }
+ return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression")
+ };
+
+ pp$5.parseProperty = function(isPattern, refDestructuringErrors) {
+ var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc;
+ if (this.options.ecmaVersion >= 9 && this.eat(types$1.ellipsis)) {
+ if (isPattern) {
+ prop.argument = this.parseIdent(false);
+ if (this.type === types$1.comma) {
+ this.raiseRecoverable(this.start, "Comma is not permitted after the rest element");
+ }
+ return this.finishNode(prop, "RestElement")
+ }
+ prop.argument = this.parseMaybeAssign(false, refDestructuringErrors);
+ if (this.type === types$1.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) {
+ refDestructuringErrors.trailingComma = this.start;
+ }
+ return this.finishNode(prop, "SpreadElement")
+ }
+ if (this.options.ecmaVersion >= 6) {
+ prop.method = false;
+ prop.shorthand = false;
+ if (isPattern || refDestructuringErrors) {
+ startPos = this.start;
+ startLoc = this.startLoc;
+ }
+ if (!isPattern)
+ { isGenerator = this.eat(types$1.star); }
+ }
+ var containsEsc = this.containsEsc;
+ this.parsePropertyName(prop);
+ if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) {
+ isAsync = true;
+ isGenerator = this.options.ecmaVersion >= 9 && this.eat(types$1.star);
+ this.parsePropertyName(prop);
+ } else {
+ isAsync = false;
+ }
+ this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc);
+ return this.finishNode(prop, "Property")
+ };
+
+ pp$5.parseGetterSetter = function(prop) {
+ prop.kind = prop.key.name;
+ this.parsePropertyName(prop);
+ prop.value = this.parseMethod(false);
+ var paramCount = prop.kind === "get" ? 0 : 1;
+ if (prop.value.params.length !== paramCount) {
+ var start = prop.value.start;
+ if (prop.kind === "get")
+ { this.raiseRecoverable(start, "getter should have no params"); }
+ else
+ { this.raiseRecoverable(start, "setter should have exactly one param"); }
+ } else {
+ if (prop.kind === "set" && prop.value.params[0].type === "RestElement")
+ { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); }
+ }
+ };
+
+ pp$5.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) {
+ if ((isGenerator || isAsync) && this.type === types$1.colon)
+ { this.unexpected(); }
+
+ if (this.eat(types$1.colon)) {
+ prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors);
+ prop.kind = "init";
+ } else if (this.options.ecmaVersion >= 6 && this.type === types$1.parenL) {
+ if (isPattern) { this.unexpected(); }
+ prop.kind = "init";
+ prop.method = true;
+ prop.value = this.parseMethod(isGenerator, isAsync);
+ } else if (!isPattern && !containsEsc &&
+ this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
+ (prop.key.name === "get" || prop.key.name === "set") &&
+ (this.type !== types$1.comma && this.type !== types$1.braceR && this.type !== types$1.eq)) {
+ if (isGenerator || isAsync) { this.unexpected(); }
+ this.parseGetterSetter(prop);
+ } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
+ if (isGenerator || isAsync) { this.unexpected(); }
+ this.checkUnreserved(prop.key);
+ if (prop.key.name === "await" && !this.awaitIdentPos)
+ { this.awaitIdentPos = startPos; }
+ prop.kind = "init";
+ if (isPattern) {
+ prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key));
+ } else if (this.type === types$1.eq && refDestructuringErrors) {
+ if (refDestructuringErrors.shorthandAssign < 0)
+ { refDestructuringErrors.shorthandAssign = this.start; }
+ prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key));
+ } else {
+ prop.value = this.copyNode(prop.key);
+ }
+ prop.shorthand = true;
+ } else { this.unexpected(); }
+ };
+
+ pp$5.parsePropertyName = function(prop) {
+ if (this.options.ecmaVersion >= 6) {
+ if (this.eat(types$1.bracketL)) {
+ prop.computed = true;
+ prop.key = this.parseMaybeAssign();
+ this.expect(types$1.bracketR);
+ return prop.key
+ } else {
+ prop.computed = false;
+ }
+ }
+ return prop.key = this.type === types$1.num || this.type === types$1.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never")
+ };
+
+
+ pp$5.initFunction = function(node) {
+ node.id = null;
+ if (this.options.ecmaVersion >= 6) { node.generator = node.expression = false; }
+ if (this.options.ecmaVersion >= 8) { node.async = false; }
+ };
+
+
+ pp$5.parseMethod = function(isGenerator, isAsync, allowDirectSuper) {
+ var node = this.startNode(), oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
+
+ this.initFunction(node);
+ if (this.options.ecmaVersion >= 6)
+ { node.generator = isGenerator; }
+ if (this.options.ecmaVersion >= 8)
+ { node.async = !!isAsync; }
+
+ this.yieldPos = 0;
+ this.awaitPos = 0;
+ this.awaitIdentPos = 0;
+ this.enterScope(functionFlags(isAsync, node.generator) | SCOPE_SUPER | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0));
+
+ this.expect(types$1.parenL);
+ node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8);
+ this.checkYieldAwaitInDefaultParams();
+ this.parseFunctionBody(node, false, true, false);
+
+ this.yieldPos = oldYieldPos;
+ this.awaitPos = oldAwaitPos;
+ this.awaitIdentPos = oldAwaitIdentPos;
+ return this.finishNode(node, "FunctionExpression")
+ };
+
+
+ pp$5.parseArrowExpression = function(node, params, isAsync, forInit) {
+ var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
+
+ this.enterScope(functionFlags(isAsync, false) | SCOPE_ARROW);
+ this.initFunction(node);
+ if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; }
+
+ this.yieldPos = 0;
+ this.awaitPos = 0;
+ this.awaitIdentPos = 0;
+
+ node.params = this.toAssignableList(params, true);
+ this.parseFunctionBody(node, true, false, forInit);
+
+ this.yieldPos = oldYieldPos;
+ this.awaitPos = oldAwaitPos;
+ this.awaitIdentPos = oldAwaitIdentPos;
+ return this.finishNode(node, "ArrowFunctionExpression")
+ };
+
+
+ pp$5.parseFunctionBody = function(node, isArrowFunction, isMethod, forInit) {
+ var isExpression = isArrowFunction && this.type !== types$1.braceL;
+ var oldStrict = this.strict, useStrict = false;
+
+ if (isExpression) {
+ node.body = this.parseMaybeAssign(forInit);
+ node.expression = true;
+ this.checkParams(node, false);
+ } else {
+ var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params);
+ if (!oldStrict || nonSimple) {
+ useStrict = this.strictDirective(this.end);
+ if (useStrict && nonSimple)
+ { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); }
+ }
+ var oldLabels = this.labels;
+ this.labels = [];
+ if (useStrict) { this.strict = true; }
+
+ this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params));
+ if (this.strict && node.id) { this.checkLValSimple(node.id, BIND_OUTSIDE); }
+ node.body = this.parseBlock(false, undefined, useStrict && !oldStrict);
+ node.expression = false;
+ this.adaptDirectivePrologue(node.body.body);
+ this.labels = oldLabels;
+ }
+ this.exitScope();
+ };
+
+ pp$5.isSimpleParamList = function(params) {
+ for (var i = 0, list = params; i < list.length; i += 1)
+ {
+ var param = list[i];
+
+ if (param.type !== "Identifier") { return false
+ } }
+ return true
+ };
+
+
+ pp$5.checkParams = function(node, allowDuplicates) {
+ var nameHash = Object.create(null);
+ for (var i = 0, list = node.params; i < list.length; i += 1)
+ {
+ var param = list[i];
+
+ this.checkLValInnerPattern(param, BIND_VAR, allowDuplicates ? null : nameHash);
+ }
+ };
+
+
+ pp$5.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) {
+ var elts = [], first = true;
+ while (!this.eat(close)) {
+ if (!first) {
+ this.expect(types$1.comma);
+ if (allowTrailingComma && this.afterTrailingComma(close)) { break }
+ } else { first = false; }
+
+ var elt = (void 0);
+ if (allowEmpty && this.type === types$1.comma)
+ { elt = null; }
+ else if (this.type === types$1.ellipsis) {
+ elt = this.parseSpread(refDestructuringErrors);
+ if (refDestructuringErrors && this.type === types$1.comma && refDestructuringErrors.trailingComma < 0)
+ { refDestructuringErrors.trailingComma = this.start; }
+ } else {
+ elt = this.parseMaybeAssign(false, refDestructuringErrors);
+ }
+ elts.push(elt);
+ }
+ return elts
+ };
+
+ pp$5.checkUnreserved = function(ref) {
+ var start = ref.start;
+ var end = ref.end;
+ var name = ref.name;
+
+ if (this.inGenerator && name === "yield")
+ { this.raiseRecoverable(start, "Cannot use 'yield' as identifier inside a generator"); }
+ if (this.inAsync && name === "await")
+ { this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function"); }
+ if (this.currentThisScope().inClassFieldInit && name === "arguments")
+ { this.raiseRecoverable(start, "Cannot use 'arguments' in class field initializer"); }
+ if (this.inClassStaticBlock && (name === "arguments" || name === "await"))
+ { this.raise(start, ("Cannot use " + name + " in class static initialization block")); }
+ if (this.keywords.test(name))
+ { this.raise(start, ("Unexpected keyword '" + name + "'")); }
+ if (this.options.ecmaVersion < 6 &&
+ this.input.slice(start, end).indexOf("\\") !== -1) { return }
+ var re = this.strict ? this.reservedWordsStrict : this.reservedWords;
+ if (re.test(name)) {
+ if (!this.inAsync && name === "await")
+ { this.raiseRecoverable(start, "Cannot use keyword 'await' outside an async function"); }
+ this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved"));
+ }
+ };
+
+
+ pp$5.parseIdent = function(liberal) {
+ var node = this.parseIdentNode();
+ this.next(!!liberal);
+ this.finishNode(node, "Identifier");
+ if (!liberal) {
+ this.checkUnreserved(node);
+ if (node.name === "await" && !this.awaitIdentPos)
+ { this.awaitIdentPos = node.start; }
+ }
+ return node
+ };
+
+ pp$5.parseIdentNode = function() {
+ var node = this.startNode();
+ if (this.type === types$1.name) {
+ node.name = this.value;
+ } else if (this.type.keyword) {
+ node.name = this.type.keyword;
+
+ if ((node.name === "class" || node.name === "function") &&
+ (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) {
+ this.context.pop();
+ }
+ this.type = types$1.name;
+ } else {
+ this.unexpected();
+ }
+ return node
+ };
+
+ pp$5.parsePrivateIdent = function() {
+ var node = this.startNode();
+ if (this.type === types$1.privateId) {
+ node.name = this.value;
+ } else {
+ this.unexpected();
+ }
+ this.next();
+ this.finishNode(node, "PrivateIdentifier");
+
+ if (this.options.checkPrivateFields) {
+ if (this.privateNameStack.length === 0) {
+ this.raise(node.start, ("Private field '#" + (node.name) + "' must be declared in an enclosing class"));
+ } else {
+ this.privateNameStack[this.privateNameStack.length - 1].used.push(node);
+ }
+ }
+
+ return node
+ };
+
+
+ pp$5.parseYield = function(forInit) {
+ if (!this.yieldPos) { this.yieldPos = this.start; }
+
+ var node = this.startNode();
+ this.next();
+ if (this.type === types$1.semi || this.canInsertSemicolon() || (this.type !== types$1.star && !this.type.startsExpr)) {
+ node.delegate = false;
+ node.argument = null;
+ } else {
+ node.delegate = this.eat(types$1.star);
+ node.argument = this.parseMaybeAssign(forInit);
+ }
+ return this.finishNode(node, "YieldExpression")
+ };
+
+ pp$5.parseAwait = function(forInit) {
+ if (!this.awaitPos) { this.awaitPos = this.start; }
+
+ var node = this.startNode();
+ this.next();
+ node.argument = this.parseMaybeUnary(null, true, false, forInit);
+ return this.finishNode(node, "AwaitExpression")
+ };
+
+ var pp$4 = Parser.prototype;
+
+
+ pp$4.raise = function(pos, message) {
+ var loc = getLineInfo(this.input, pos);
+ message += " (" + loc.line + ":" + loc.column + ")";
+ var err = new SyntaxError(message);
+ err.pos = pos; err.loc = loc; err.raisedAt = this.pos;
+ throw err
+ };
+
+ pp$4.raiseRecoverable = pp$4.raise;
+
+ pp$4.curPosition = function() {
+ if (this.options.locations) {
+ return new Position(this.curLine, this.pos - this.lineStart)
+ }
+ };
+
+ var pp$3 = Parser.prototype;
+
+ var Scope = function Scope(flags) {
+ this.flags = flags;
+ this.var = [];
+ this.lexical = [];
+ this.functions = [];
+ this.inClassFieldInit = false;
+ };
+
+
+ pp$3.enterScope = function(flags) {
+ this.scopeStack.push(new Scope(flags));
+ };
+
+ pp$3.exitScope = function() {
+ this.scopeStack.pop();
+ };
+
+ pp$3.treatFunctionsAsVarInScope = function(scope) {
+ return (scope.flags & SCOPE_FUNCTION) || !this.inModule && (scope.flags & SCOPE_TOP)
+ };
+
+ pp$3.declareName = function(name, bindingType, pos) {
+ var redeclared = false;
+ if (bindingType === BIND_LEXICAL) {
+ var scope = this.currentScope();
+ redeclared = scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1;
+ scope.lexical.push(name);
+ if (this.inModule && (scope.flags & SCOPE_TOP))
+ { delete this.undefinedExports[name]; }
+ } else if (bindingType === BIND_SIMPLE_CATCH) {
+ var scope$1 = this.currentScope();
+ scope$1.lexical.push(name);
+ } else if (bindingType === BIND_FUNCTION) {
+ var scope$2 = this.currentScope();
+ if (this.treatFunctionsAsVar)
+ { redeclared = scope$2.lexical.indexOf(name) > -1; }
+ else
+ { redeclared = scope$2.lexical.indexOf(name) > -1 || scope$2.var.indexOf(name) > -1; }
+ scope$2.functions.push(name);
+ } else {
+ for (var i = this.scopeStack.length - 1; i >= 0; --i) {
+ var scope$3 = this.scopeStack[i];
+ if (scope$3.lexical.indexOf(name) > -1 && !((scope$3.flags & SCOPE_SIMPLE_CATCH) && scope$3.lexical[0] === name) ||
+ !this.treatFunctionsAsVarInScope(scope$3) && scope$3.functions.indexOf(name) > -1) {
+ redeclared = true;
+ break
+ }
+ scope$3.var.push(name);
+ if (this.inModule && (scope$3.flags & SCOPE_TOP))
+ { delete this.undefinedExports[name]; }
+ if (scope$3.flags & SCOPE_VAR) { break }
+ }
+ }
+ if (redeclared) { this.raiseRecoverable(pos, ("Identifier '" + name + "' has already been declared")); }
+ };
+
+ pp$3.checkLocalExport = function(id) {
+ if (this.scopeStack[0].lexical.indexOf(id.name) === -1 &&
+ this.scopeStack[0].var.indexOf(id.name) === -1) {
+ this.undefinedExports[id.name] = id;
+ }
+ };
+
+ pp$3.currentScope = function() {
+ return this.scopeStack[this.scopeStack.length - 1]
+ };
+
+ pp$3.currentVarScope = function() {
+ for (var i = this.scopeStack.length - 1;; i--) {
+ var scope = this.scopeStack[i];
+ if (scope.flags & SCOPE_VAR) { return scope }
+ }
+ };
+
+ pp$3.currentThisScope = function() {
+ for (var i = this.scopeStack.length - 1;; i--) {
+ var scope = this.scopeStack[i];
+ if (scope.flags & SCOPE_VAR && !(scope.flags & SCOPE_ARROW)) { return scope }
+ }
+ };
+
+ var Node = function Node(parser, pos, loc) {
+ this.type = "";
+ this.start = pos;
+ this.end = 0;
+ if (parser.options.locations)
+ { this.loc = new SourceLocation(parser, loc); }
+ if (parser.options.directSourceFile)
+ { this.sourceFile = parser.options.directSourceFile; }
+ if (parser.options.ranges)
+ { this.range = [pos, 0]; }
+ };
+
+
+ var pp$2 = Parser.prototype;
+
+ pp$2.startNode = function() {
+ return new Node(this, this.start, this.startLoc)
+ };
+
+ pp$2.startNodeAt = function(pos, loc) {
+ return new Node(this, pos, loc)
+ };
+
+
+ function finishNodeAt(node, type, pos, loc) {
+ node.type = type;
+ node.end = pos;
+ if (this.options.locations)
+ { node.loc.end = loc; }
+ if (this.options.ranges)
+ { node.range[1] = pos; }
+ return node
+ }
+
+ pp$2.finishNode = function(node, type) {
+ return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc)
+ };
+
+
+ pp$2.finishNodeAt = function(node, type, pos, loc) {
+ return finishNodeAt.call(this, node, type, pos, loc)
+ };
+
+ pp$2.copyNode = function(node) {
+ var newNode = new Node(this, node.start, this.startLoc);
+ for (var prop in node) { newNode[prop] = node[prop]; }
+ return newNode
+ };
+
+ var scriptValuesAddedInUnicode = "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";
+
+
+ var ecma9BinaryProperties = "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";
+ var ecma10BinaryProperties = ecma9BinaryProperties + " Extended_Pictographic";
+ var ecma11BinaryProperties = ecma10BinaryProperties;
+ var ecma12BinaryProperties = ecma11BinaryProperties + " EBase EComp EMod EPres ExtPict";
+ var ecma13BinaryProperties = ecma12BinaryProperties;
+ var ecma14BinaryProperties = ecma13BinaryProperties;
+
+ var unicodeBinaryProperties = {
+ 9: ecma9BinaryProperties,
+ 10: ecma10BinaryProperties,
+ 11: ecma11BinaryProperties,
+ 12: ecma12BinaryProperties,
+ 13: ecma13BinaryProperties,
+ 14: ecma14BinaryProperties
+ };
+
+ var ecma14BinaryPropertiesOfStrings = "Basic_Emoji Emoji_Keycap_Sequence RGI_Emoji_Modifier_Sequence RGI_Emoji_Flag_Sequence RGI_Emoji_Tag_Sequence RGI_Emoji_ZWJ_Sequence RGI_Emoji";
+
+ var unicodeBinaryPropertiesOfStrings = {
+ 9: "",
+ 10: "",
+ 11: "",
+ 12: "",
+ 13: "",
+ 14: ecma14BinaryPropertiesOfStrings
+ };
+
+ var unicodeGeneralCategoryValues = "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";
+
+ var ecma9ScriptValues = "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";
+ var ecma10ScriptValues = ecma9ScriptValues + " Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd";
+ var ecma11ScriptValues = ecma10ScriptValues + " Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho";
+ var ecma12ScriptValues = ecma11ScriptValues + " Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi";
+ var ecma13ScriptValues = ecma12ScriptValues + " Cypro_Minoan Cpmn Old_Uyghur Ougr Tangsa Tnsa Toto Vithkuqi Vith";
+ var ecma14ScriptValues = ecma13ScriptValues + " " + scriptValuesAddedInUnicode;
+
+ var unicodeScriptValues = {
+ 9: ecma9ScriptValues,
+ 10: ecma10ScriptValues,
+ 11: ecma11ScriptValues,
+ 12: ecma12ScriptValues,
+ 13: ecma13ScriptValues,
+ 14: ecma14ScriptValues
+ };
+
+ var data = {};
+ function buildUnicodeData(ecmaVersion) {
+ var d = data[ecmaVersion] = {
+ binary: wordsRegexp(unicodeBinaryProperties[ecmaVersion] + " " + unicodeGeneralCategoryValues),
+ binaryOfStrings: wordsRegexp(unicodeBinaryPropertiesOfStrings[ecmaVersion]),
+ nonBinary: {
+ General_Category: wordsRegexp(unicodeGeneralCategoryValues),
+ Script: wordsRegexp(unicodeScriptValues[ecmaVersion])
+ }
+ };
+ d.nonBinary.Script_Extensions = d.nonBinary.Script;
+
+ d.nonBinary.gc = d.nonBinary.General_Category;
+ d.nonBinary.sc = d.nonBinary.Script;
+ d.nonBinary.scx = d.nonBinary.Script_Extensions;
+ }
+
+ for (var i = 0, list = [9, 10, 11, 12, 13, 14]; i < list.length; i += 1) {
+ var ecmaVersion = list[i];
+
+ buildUnicodeData(ecmaVersion);
+ }
+
+ var pp$1 = Parser.prototype;
+
+ var BranchID = function BranchID(parent, base) {
+ this.parent = parent;
+ this.base = base || this;
+ };
+
+ BranchID.prototype.separatedFrom = function separatedFrom (alt) {
+ for (var self = this; self; self = self.parent) {
+ for (var other = alt; other; other = other.parent) {
+ if (self.base === other.base && self !== other) { return true }
+ }
+ }
+ return false
+ };
+
+ BranchID.prototype.sibling = function sibling () {
+ return new BranchID(this.parent, this.base)
+ };
+
+ var RegExpValidationState = function RegExpValidationState(parser) {
+ this.parser = parser;
+ this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "") + (parser.options.ecmaVersion >= 13 ? "d" : "") + (parser.options.ecmaVersion >= 15 ? "v" : "");
+ this.unicodeProperties = data[parser.options.ecmaVersion >= 14 ? 14 : parser.options.ecmaVersion];
+ this.source = "";
+ this.flags = "";
+ this.start = 0;
+ this.switchU = false;
+ this.switchV = false;
+ this.switchN = false;
+ this.pos = 0;
+ this.lastIntValue = 0;
+ this.lastStringValue = "";
+ this.lastAssertionIsQuantifiable = false;
+ this.numCapturingParens = 0;
+ this.maxBackReference = 0;
+ this.groupNames = Object.create(null);
+ this.backReferenceNames = [];
+ this.branchID = null;
+ };
+
+ RegExpValidationState.prototype.reset = function reset (start, pattern, flags) {
+ var unicodeSets = flags.indexOf("v") !== -1;
+ var unicode = flags.indexOf("u") !== -1;
+ this.start = start | 0;
+ this.source = pattern + "";
+ this.flags = flags;
+ if (unicodeSets && this.parser.options.ecmaVersion >= 15) {
+ this.switchU = true;
+ this.switchV = true;
+ this.switchN = true;
+ } else {
+ this.switchU = unicode && this.parser.options.ecmaVersion >= 6;
+ this.switchV = false;
+ this.switchN = unicode && this.parser.options.ecmaVersion >= 9;
+ }
+ };
+
+ RegExpValidationState.prototype.raise = function raise (message) {
+ this.parser.raiseRecoverable(this.start, ("Invalid regular expression: /" + (this.source) + "/: " + message));
+ };
+
+ RegExpValidationState.prototype.at = function at (i, forceU) {
+ if ( forceU === void 0 ) forceU = false;
+
+ var s = this.source;
+ var l = s.length;
+ if (i >= l) {
+ return -1
+ }
+ var c = s.charCodeAt(i);
+ if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {
+ return c
+ }
+ var next = s.charCodeAt(i + 1);
+ return next >= 0xDC00 && next <= 0xDFFF ? (c << 10) + next - 0x35FDC00 : c
+ };
+
+ RegExpValidationState.prototype.nextIndex = function nextIndex (i, forceU) {
+ if ( forceU === void 0 ) forceU = false;
+
+ var s = this.source;
+ var l = s.length;
+ if (i >= l) {
+ return l
+ }
+ var c = s.charCodeAt(i), next;
+ if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l ||
+ (next = s.charCodeAt(i + 1)) < 0xDC00 || next > 0xDFFF) {
+ return i + 1
+ }
+ return i + 2
+ };
+
+ RegExpValidationState.prototype.current = function current (forceU) {
+ if ( forceU === void 0 ) forceU = false;
+
+ return this.at(this.pos, forceU)
+ };
+
+ RegExpValidationState.prototype.lookahead = function lookahead (forceU) {
+ if ( forceU === void 0 ) forceU = false;
+
+ return this.at(this.nextIndex(this.pos, forceU), forceU)
+ };
+
+ RegExpValidationState.prototype.advance = function advance (forceU) {
+ if ( forceU === void 0 ) forceU = false;
+
+ this.pos = this.nextIndex(this.pos, forceU);
+ };
+
+ RegExpValidationState.prototype.eat = function eat (ch, forceU) {
+ if ( forceU === void 0 ) forceU = false;
+
+ if (this.current(forceU) === ch) {
+ this.advance(forceU);
+ return true
+ }
+ return false
+ };
+
+ RegExpValidationState.prototype.eatChars = function eatChars (chs, forceU) {
+ if ( forceU === void 0 ) forceU = false;
+
+ var pos = this.pos;
+ for (var i = 0, list = chs; i < list.length; i += 1) {
+ var ch = list[i];
+
+ var current = this.at(pos, forceU);
+ if (current === -1 || current !== ch) {
+ return false
+ }
+ pos = this.nextIndex(pos, forceU);
+ }
+ this.pos = pos;
+ return true
+ };
+
+ pp$1.validateRegExpFlags = function(state) {
+ var validFlags = state.validFlags;
+ var flags = state.flags;
+
+ var u = false;
+ var v = false;
+
+ for (var i = 0; i < flags.length; i++) {
+ var flag = flags.charAt(i);
+ if (validFlags.indexOf(flag) === -1) {
+ this.raise(state.start, "Invalid regular expression flag");
+ }
+ if (flags.indexOf(flag, i + 1) > -1) {
+ this.raise(state.start, "Duplicate regular expression flag");
+ }
+ if (flag === "u") { u = true; }
+ if (flag === "v") { v = true; }
+ }
+ if (this.options.ecmaVersion >= 15 && u && v) {
+ this.raise(state.start, "Invalid regular expression flag");
+ }
+ };
+
+ function hasProp(obj) {
+ for (var _ in obj) { return true }
+ return false
+ }
+
+ pp$1.validateRegExpPattern = function(state) {
+ this.regexp_pattern(state);
+
+ if (!state.switchN && this.options.ecmaVersion >= 9 && hasProp(state.groupNames)) {
+ state.switchN = true;
+ this.regexp_pattern(state);
+ }
+ };
+
+ pp$1.regexp_pattern = function(state) {
+ state.pos = 0;
+ state.lastIntValue = 0;
+ state.lastStringValue = "";
+ state.lastAssertionIsQuantifiable = false;
+ state.numCapturingParens = 0;
+ state.maxBackReference = 0;
+ state.groupNames = Object.create(null);
+ state.backReferenceNames.length = 0;
+ state.branchID = null;
+
+ this.regexp_disjunction(state);
+
+ if (state.pos !== state.source.length) {
+ if (state.eat(0x29 )) {
+ state.raise("Unmatched ')'");
+ }
+ if (state.eat(0x5D ) || state.eat(0x7D )) {
+ state.raise("Lone quantifier brackets");
+ }
+ }
+ if (state.maxBackReference > state.numCapturingParens) {
+ state.raise("Invalid escape");
+ }
+ for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) {
+ var name = list[i];
+
+ if (!state.groupNames[name]) {
+ state.raise("Invalid named capture referenced");
+ }
+ }
+ };
+
+ pp$1.regexp_disjunction = function(state) {
+ var trackDisjunction = this.options.ecmaVersion >= 16;
+ if (trackDisjunction) { state.branchID = new BranchID(state.branchID, null); }
+ this.regexp_alternative(state);
+ while (state.eat(0x7C )) {
+ if (trackDisjunction) { state.branchID = state.branchID.sibling(); }
+ this.regexp_alternative(state);
+ }
+ if (trackDisjunction) { state.branchID = state.branchID.parent; }
+
+ if (this.regexp_eatQuantifier(state, true)) {
+ state.raise("Nothing to repeat");
+ }
+ if (state.eat(0x7B )) {
+ state.raise("Lone quantifier brackets");
+ }
+ };
+
+ pp$1.regexp_alternative = function(state) {
+ while (state.pos < state.source.length && this.regexp_eatTerm(state)) {}
+ };
+
+ pp$1.regexp_eatTerm = function(state) {
+ if (this.regexp_eatAssertion(state)) {
+ if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) {
+ if (state.switchU) {
+ state.raise("Invalid quantifier");
+ }
+ }
+ return true
+ }
+
+ if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) {
+ this.regexp_eatQuantifier(state);
+ return true
+ }
+
+ return false
+ };
+
+ pp$1.regexp_eatAssertion = function(state) {
+ var start = state.pos;
+ state.lastAssertionIsQuantifiable = false;
+
+ if (state.eat(0x5E ) || state.eat(0x24 )) {
+ return true
+ }
+
+ if (state.eat(0x5C )) {
+ if (state.eat(0x42 ) || state.eat(0x62 )) {
+ return true
+ }
+ state.pos = start;
+ }
+
+ if (state.eat(0x28 ) && state.eat(0x3F )) {
+ var lookbehind = false;
+ if (this.options.ecmaVersion >= 9) {
+ lookbehind = state.eat(0x3C );
+ }
+ if (state.eat(0x3D ) || state.eat(0x21 )) {
+ this.regexp_disjunction(state);
+ if (!state.eat(0x29 )) {
+ state.raise("Unterminated group");
+ }
+ state.lastAssertionIsQuantifiable = !lookbehind;
+ return true
+ }
+ }
+
+ state.pos = start;
+ return false
+ };
+
+ pp$1.regexp_eatQuantifier = function(state, noError) {
+ if ( noError === void 0 ) noError = false;
+
+ if (this.regexp_eatQuantifierPrefix(state, noError)) {
+ state.eat(0x3F );
+ return true
+ }
+ return false
+ };
+
+ pp$1.regexp_eatQuantifierPrefix = function(state, noError) {
+ return (
+ state.eat(0x2A ) ||
+ state.eat(0x2B ) ||
+ state.eat(0x3F ) ||
+ this.regexp_eatBracedQuantifier(state, noError)
+ )
+ };
+ pp$1.regexp_eatBracedQuantifier = function(state, noError) {
+ var start = state.pos;
+ if (state.eat(0x7B )) {
+ var min = 0, max = -1;
+ if (this.regexp_eatDecimalDigits(state)) {
+ min = state.lastIntValue;
+ if (state.eat(0x2C ) && this.regexp_eatDecimalDigits(state)) {
+ max = state.lastIntValue;
+ }
+ if (state.eat(0x7D )) {
+ if (max !== -1 && max < min && !noError) {
+ state.raise("numbers out of order in {} quantifier");
+ }
+ return true
+ }
+ }
+ if (state.switchU && !noError) {
+ state.raise("Incomplete quantifier");
+ }
+ state.pos = start;
+ }
+ return false
+ };
+
+ pp$1.regexp_eatAtom = function(state) {
+ return (
+ this.regexp_eatPatternCharacters(state) ||
+ state.eat(0x2E ) ||
+ this.regexp_eatReverseSolidusAtomEscape(state) ||
+ this.regexp_eatCharacterClass(state) ||
+ this.regexp_eatUncapturingGroup(state) ||
+ this.regexp_eatCapturingGroup(state)
+ )
+ };
+ pp$1.regexp_eatReverseSolidusAtomEscape = function(state) {
+ var start = state.pos;
+ if (state.eat(0x5C )) {
+ if (this.regexp_eatAtomEscape(state)) {
+ return true
+ }
+ state.pos = start;
+ }
+ return false
+ };
+ pp$1.regexp_eatUncapturingGroup = function(state) {
+ var start = state.pos;
+ if (state.eat(0x28 )) {
+ if (state.eat(0x3F )) {
+ if (this.options.ecmaVersion >= 16) {
+ var addModifiers = this.regexp_eatModifiers(state);
+ var hasHyphen = state.eat(0x2D );
+ if (addModifiers || hasHyphen) {
+ for (var i = 0; i < addModifiers.length; i++) {
+ var modifier = addModifiers.charAt(i);
+ if (addModifiers.indexOf(modifier, i + 1) > -1) {
+ state.raise("Duplicate regular expression modifiers");
+ }
+ }
+ if (hasHyphen) {
+ var removeModifiers = this.regexp_eatModifiers(state);
+ if (!addModifiers && !removeModifiers && state.current() === 0x3A ) {
+ state.raise("Invalid regular expression modifiers");
+ }
+ for (var i$1 = 0; i$1 < removeModifiers.length; i$1++) {
+ var modifier$1 = removeModifiers.charAt(i$1);
+ if (
+ removeModifiers.indexOf(modifier$1, i$1 + 1) > -1 ||
+ addModifiers.indexOf(modifier$1) > -1
+ ) {
+ state.raise("Duplicate regular expression modifiers");
+ }
+ }
+ }
+ }
+ }
+ if (state.eat(0x3A )) {
+ this.regexp_disjunction(state);
+ if (state.eat(0x29 )) {
+ return true
+ }
+ state.raise("Unterminated group");
+ }
+ }
+ state.pos = start;
+ }
+ return false
+ };
+ pp$1.regexp_eatCapturingGroup = function(state) {
+ if (state.eat(0x28 )) {
+ if (this.options.ecmaVersion >= 9) {
+ this.regexp_groupSpecifier(state);
+ } else if (state.current() === 0x3F ) {
+ state.raise("Invalid group");
+ }
+ this.regexp_disjunction(state);
+ if (state.eat(0x29 )) {
+ state.numCapturingParens += 1;
+ return true
+ }
+ state.raise("Unterminated group");
+ }
+ return false
+ };
+ pp$1.regexp_eatModifiers = function(state) {
+ var modifiers = "";
+ var ch = 0;
+ while ((ch = state.current()) !== -1 && isRegularExpressionModifier(ch)) {
+ modifiers += codePointToString(ch);
+ state.advance();
+ }
+ return modifiers
+ };
+ function isRegularExpressionModifier(ch) {
+ return ch === 0x69 || ch === 0x6d || ch === 0x73
+ }
+
+ pp$1.regexp_eatExtendedAtom = function(state) {
+ return (
+ state.eat(0x2E ) ||
+ this.regexp_eatReverseSolidusAtomEscape(state) ||
+ this.regexp_eatCharacterClass(state) ||
+ this.regexp_eatUncapturingGroup(state) ||
+ this.regexp_eatCapturingGroup(state) ||
+ this.regexp_eatInvalidBracedQuantifier(state) ||
+ this.regexp_eatExtendedPatternCharacter(state)
+ )
+ };
+
+ pp$1.regexp_eatInvalidBracedQuantifier = function(state) {
+ if (this.regexp_eatBracedQuantifier(state, true)) {
+ state.raise("Nothing to repeat");
+ }
+ return false
+ };
+
+ pp$1.regexp_eatSyntaxCharacter = function(state) {
+ var ch = state.current();
+ if (isSyntaxCharacter(ch)) {
+ state.lastIntValue = ch;
+ state.advance();
+ return true
+ }
+ return false
+ };
+ function isSyntaxCharacter(ch) {
+ return (
+ ch === 0x24 ||
+ ch >= 0x28 && ch <= 0x2B ||
+ ch === 0x2E ||
+ ch === 0x3F ||
+ ch >= 0x5B && ch <= 0x5E ||
+ ch >= 0x7B && ch <= 0x7D
+ )
+ }
+
+ pp$1.regexp_eatPatternCharacters = function(state) {
+ var start = state.pos;
+ var ch = 0;
+ while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) {
+ state.advance();
+ }
+ return state.pos !== start
+ };
+
+ pp$1.regexp_eatExtendedPatternCharacter = function(state) {
+ var ch = state.current();
+ if (
+ ch !== -1 &&
+ ch !== 0x24 &&
+ !(ch >= 0x28 && ch <= 0x2B ) &&
+ ch !== 0x2E &&
+ ch !== 0x3F &&
+ ch !== 0x5B &&
+ ch !== 0x5E &&
+ ch !== 0x7C
+ ) {
+ state.advance();
+ return true
+ }
+ return false
+ };
+
+ pp$1.regexp_groupSpecifier = function(state) {
+ if (state.eat(0x3F )) {
+ if (!this.regexp_eatGroupName(state)) { state.raise("Invalid group"); }
+ var trackDisjunction = this.options.ecmaVersion >= 16;
+ var known = state.groupNames[state.lastStringValue];
+ if (known) {
+ if (trackDisjunction) {
+ for (var i = 0, list = known; i < list.length; i += 1) {
+ var altID = list[i];
+
+ if (!altID.separatedFrom(state.branchID))
+ { state.raise("Duplicate capture group name"); }
+ }
+ } else {
+ state.raise("Duplicate capture group name");
+ }
+ }
+ if (trackDisjunction) {
+ (known || (state.groupNames[state.lastStringValue] = [])).push(state.branchID);
+ } else {
+ state.groupNames[state.lastStringValue] = true;
+ }
+ }
+ };
+
+ pp$1.regexp_eatGroupName = function(state) {
+ state.lastStringValue = "";
+ if (state.eat(0x3C )) {
+ if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E )) {
+ return true
+ }
+ state.raise("Invalid capture group name");
+ }
+ return false
+ };
+
+ pp$1.regexp_eatRegExpIdentifierName = function(state) {
+ state.lastStringValue = "";
+ if (this.regexp_eatRegExpIdentifierStart(state)) {
+ state.lastStringValue += codePointToString(state.lastIntValue);
+ while (this.regexp_eatRegExpIdentifierPart(state)) {
+ state.lastStringValue += codePointToString(state.lastIntValue);
+ }
+ return true
+ }
+ return false
+ };
+
+ pp$1.regexp_eatRegExpIdentifierStart = function(state) {
+ var start = state.pos;
+ var forceU = this.options.ecmaVersion >= 11;
+ var ch = state.current(forceU);
+ state.advance(forceU);
+
+ if (ch === 0x5C && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) {
+ ch = state.lastIntValue;
+ }
+ if (isRegExpIdentifierStart(ch)) {
+ state.lastIntValue = ch;
+ return true
+ }
+
+ state.pos = start;
+ return false
+ };
+ function isRegExpIdentifierStart(ch) {
+ return isIdentifierStart(ch, true) || ch === 0x24 || ch === 0x5F
+ }
+
+ pp$1.regexp_eatRegExpIdentifierPart = function(state) {
+ var start = state.pos;
+ var forceU = this.options.ecmaVersion >= 11;
+ var ch = state.current(forceU);
+ state.advance(forceU);
+
+ if (ch === 0x5C && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) {
+ ch = state.lastIntValue;
+ }
+ if (isRegExpIdentifierPart(ch)) {
+ state.lastIntValue = ch;
+ return true
+ }
+
+ state.pos = start;
+ return false
+ };
+ function isRegExpIdentifierPart(ch) {
+ return isIdentifierChar(ch, true) || ch === 0x24 || ch === 0x5F || ch === 0x200C || ch === 0x200D
+ }
+
+ pp$1.regexp_eatAtomEscape = function(state) {
+ if (
+ this.regexp_eatBackReference(state) ||
+ this.regexp_eatCharacterClassEscape(state) ||
+ this.regexp_eatCharacterEscape(state) ||
+ (state.switchN && this.regexp_eatKGroupName(state))
+ ) {
+ return true
+ }
+ if (state.switchU) {
+ if (state.current() === 0x63 ) {
+ state.raise("Invalid unicode escape");
+ }
+ state.raise("Invalid escape");
+ }
+ return false
+ };
+ pp$1.regexp_eatBackReference = function(state) {
+ var start = state.pos;
+ if (this.regexp_eatDecimalEscape(state)) {
+ var n = state.lastIntValue;
+ if (state.switchU) {
+ if (n > state.maxBackReference) {
+ state.maxBackReference = n;
+ }
+ return true
+ }
+ if (n <= state.numCapturingParens) {
+ return true
+ }
+ state.pos = start;
+ }
+ return false
+ };
+ pp$1.regexp_eatKGroupName = function(state) {
+ if (state.eat(0x6B )) {
+ if (this.regexp_eatGroupName(state)) {
+ state.backReferenceNames.push(state.lastStringValue);
+ return true
+ }
+ state.raise("Invalid named reference");
+ }
+ return false
+ };
+
+ pp$1.regexp_eatCharacterEscape = function(state) {
+ return (
+ this.regexp_eatControlEscape(state) ||
+ this.regexp_eatCControlLetter(state) ||
+ this.regexp_eatZero(state) ||
+ this.regexp_eatHexEscapeSequence(state) ||
+ this.regexp_eatRegExpUnicodeEscapeSequence(state, false) ||
+ (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) ||
+ this.regexp_eatIdentityEscape(state)
+ )
+ };
+ pp$1.regexp_eatCControlLetter = function(state) {
+ var start = state.pos;
+ if (state.eat(0x63 )) {
+ if (this.regexp_eatControlLetter(state)) {
+ return true
+ }
+ state.pos = start;
+ }
+ return false
+ };
+ pp$1.regexp_eatZero = function(state) {
+ if (state.current() === 0x30 && !isDecimalDigit(state.lookahead())) {
+ state.lastIntValue = 0;
+ state.advance();
+ return true
+ }
+ return false
+ };
+
+ pp$1.regexp_eatControlEscape = function(state) {
+ var ch = state.current();
+ if (ch === 0x74 ) {
+ state.lastIntValue = 0x09;
+ state.advance();
+ return true
+ }
+ if (ch === 0x6E ) {
+ state.lastIntValue = 0x0A;
+ state.advance();
+ return true
+ }
+ if (ch === 0x76 ) {
+ state.lastIntValue = 0x0B;
+ state.advance();
+ return true
+ }
+ if (ch === 0x66 ) {
+ state.lastIntValue = 0x0C;
+ state.advance();
+ return true
+ }
+ if (ch === 0x72 ) {
+ state.lastIntValue = 0x0D;
+ state.advance();
+ return true
+ }
+ return false
+ };
+
+ pp$1.regexp_eatControlLetter = function(state) {
+ var ch = state.current();
+ if (isControlLetter(ch)) {
+ state.lastIntValue = ch % 0x20;
+ state.advance();
+ return true
+ }
+ return false
+ };
+ function isControlLetter(ch) {
+ return (
+ (ch >= 0x41 && ch <= 0x5A ) ||
+ (ch >= 0x61 && ch <= 0x7A )
+ )
+ }
+
+ pp$1.regexp_eatRegExpUnicodeEscapeSequence = function(state, forceU) {
+ if ( forceU === void 0 ) forceU = false;
+
+ var start = state.pos;
+ var switchU = forceU || state.switchU;
+
+ if (state.eat(0x75 )) {
+ if (this.regexp_eatFixedHexDigits(state, 4)) {
+ var lead = state.lastIntValue;
+ if (switchU && lead >= 0xD800 && lead <= 0xDBFF) {
+ var leadSurrogateEnd = state.pos;
+ if (state.eat(0x5C ) && state.eat(0x75 ) && this.regexp_eatFixedHexDigits(state, 4)) {
+ var trail = state.lastIntValue;
+ if (trail >= 0xDC00 && trail <= 0xDFFF) {
+ state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;
+ return true
+ }
+ }
+ state.pos = leadSurrogateEnd;
+ state.lastIntValue = lead;
+ }
+ return true
+ }
+ if (
+ switchU &&
+ state.eat(0x7B ) &&
+ this.regexp_eatHexDigits(state) &&
+ state.eat(0x7D ) &&
+ isValidUnicode(state.lastIntValue)
+ ) {
+ return true
+ }
+ if (switchU) {
+ state.raise("Invalid unicode escape");
+ }
+ state.pos = start;
+ }
+
+ return false
+ };
+ function isValidUnicode(ch) {
+ return ch >= 0 && ch <= 0x10FFFF
+ }
+
+ pp$1.regexp_eatIdentityEscape = function(state) {
+ if (state.switchU) {
+ if (this.regexp_eatSyntaxCharacter(state)) {
+ return true
+ }
+ if (state.eat(0x2F )) {
+ state.lastIntValue = 0x2F;
+ return true
+ }
+ return false
+ }
+
+ var ch = state.current();
+ if (ch !== 0x63 && (!state.switchN || ch !== 0x6B )) {
+ state.lastIntValue = ch;
+ state.advance();
+ return true
+ }
+
+ return false
+ };
+
+ pp$1.regexp_eatDecimalEscape = function(state) {
+ state.lastIntValue = 0;
+ var ch = state.current();
+ if (ch >= 0x31 && ch <= 0x39 ) {
+ do {
+ state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 );
+ state.advance();
+ } while ((ch = state.current()) >= 0x30 && ch <= 0x39 )
+ return true
+ }
+ return false
+ };
+
+ var CharSetNone = 0;
+ var CharSetOk = 1;
+ var CharSetString = 2;
+
+ pp$1.regexp_eatCharacterClassEscape = function(state) {
+ var ch = state.current();
+
+ if (isCharacterClassEscape(ch)) {
+ state.lastIntValue = -1;
+ state.advance();
+ return CharSetOk
+ }
+
+ var negate = false;
+ if (
+ state.switchU &&
+ this.options.ecmaVersion >= 9 &&
+ ((negate = ch === 0x50 ) || ch === 0x70 )
+ ) {
+ state.lastIntValue = -1;
+ state.advance();
+ var result;
+ if (
+ state.eat(0x7B ) &&
+ (result = this.regexp_eatUnicodePropertyValueExpression(state)) &&
+ state.eat(0x7D )
+ ) {
+ if (negate && result === CharSetString) { state.raise("Invalid property name"); }
+ return result
+ }
+ state.raise("Invalid property name");
+ }
+
+ return CharSetNone
+ };
+
+ function isCharacterClassEscape(ch) {
+ return (
+ ch === 0x64 ||
+ ch === 0x44 ||
+ ch === 0x73 ||
+ ch === 0x53 ||
+ ch === 0x77 ||
+ ch === 0x57
+ )
+ }
+
+ pp$1.regexp_eatUnicodePropertyValueExpression = function(state) {
+ var start = state.pos;
+
+ if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D )) {
+ var name = state.lastStringValue;
+ if (this.regexp_eatUnicodePropertyValue(state)) {
+ var value = state.lastStringValue;
+ this.regexp_validateUnicodePropertyNameAndValue(state, name, value);
+ return CharSetOk
+ }
+ }
+ state.pos = start;
+
+ if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) {
+ var nameOrValue = state.lastStringValue;
+ return this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue)
+ }
+ return CharSetNone
+ };
+
+ pp$1.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) {
+ if (!hasOwn(state.unicodeProperties.nonBinary, name))
+ { state.raise("Invalid property name"); }
+ if (!state.unicodeProperties.nonBinary[name].test(value))
+ { state.raise("Invalid property value"); }
+ };
+
+ pp$1.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) {
+ if (state.unicodeProperties.binary.test(nameOrValue)) { return CharSetOk }
+ if (state.switchV && state.unicodeProperties.binaryOfStrings.test(nameOrValue)) { return CharSetString }
+ state.raise("Invalid property name");
+ };
+
+ pp$1.regexp_eatUnicodePropertyName = function(state) {
+ var ch = 0;
+ state.lastStringValue = "";
+ while (isUnicodePropertyNameCharacter(ch = state.current())) {
+ state.lastStringValue += codePointToString(ch);
+ state.advance();
+ }
+ return state.lastStringValue !== ""
+ };
+
+ function isUnicodePropertyNameCharacter(ch) {
+ return isControlLetter(ch) || ch === 0x5F
+ }
+
+ pp$1.regexp_eatUnicodePropertyValue = function(state) {
+ var ch = 0;
+ state.lastStringValue = "";
+ while (isUnicodePropertyValueCharacter(ch = state.current())) {
+ state.lastStringValue += codePointToString(ch);
+ state.advance();
+ }
+ return state.lastStringValue !== ""
+ };
+ function isUnicodePropertyValueCharacter(ch) {
+ return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch)
+ }
+
+ pp$1.regexp_eatLoneUnicodePropertyNameOrValue = function(state) {
+ return this.regexp_eatUnicodePropertyValue(state)
+ };
+
+ pp$1.regexp_eatCharacterClass = function(state) {
+ if (state.eat(0x5B )) {
+ var negate = state.eat(0x5E );
+ var result = this.regexp_classContents(state);
+ if (!state.eat(0x5D ))
+ { state.raise("Unterminated character class"); }
+ if (negate && result === CharSetString)
+ { state.raise("Negated character class may contain strings"); }
+ return true
+ }
+ return false
+ };
+
+ pp$1.regexp_classContents = function(state) {
+ if (state.current() === 0x5D ) { return CharSetOk }
+ if (state.switchV) { return this.regexp_classSetExpression(state) }
+ this.regexp_nonEmptyClassRanges(state);
+ return CharSetOk
+ };
+
+ pp$1.regexp_nonEmptyClassRanges = function(state) {
+ while (this.regexp_eatClassAtom(state)) {
+ var left = state.lastIntValue;
+ if (state.eat(0x2D ) && this.regexp_eatClassAtom(state)) {
+ var right = state.lastIntValue;
+ if (state.switchU && (left === -1 || right === -1)) {
+ state.raise("Invalid character class");
+ }
+ if (left !== -1 && right !== -1 && left > right) {
+ state.raise("Range out of order in character class");
+ }
+ }
+ }
+ };
+
+ pp$1.regexp_eatClassAtom = function(state) {
+ var start = state.pos;
+
+ if (state.eat(0x5C )) {
+ if (this.regexp_eatClassEscape(state)) {
+ return true
+ }
+ if (state.switchU) {
+ var ch$1 = state.current();
+ if (ch$1 === 0x63 || isOctalDigit(ch$1)) {
+ state.raise("Invalid class escape");
+ }
+ state.raise("Invalid escape");
+ }
+ state.pos = start;
+ }
+
+ var ch = state.current();
+ if (ch !== 0x5D ) {
+ state.lastIntValue = ch;
+ state.advance();
+ return true
+ }
+
+ return false
+ };
+
+ pp$1.regexp_eatClassEscape = function(state) {
+ var start = state.pos;
+
+ if (state.eat(0x62 )) {
+ state.lastIntValue = 0x08;
+ return true
+ }
+
+ if (state.switchU && state.eat(0x2D )) {
+ state.lastIntValue = 0x2D;
+ return true
+ }
+
+ if (!state.switchU && state.eat(0x63 )) {
+ if (this.regexp_eatClassControlLetter(state)) {
+ return true
+ }
+ state.pos = start;
+ }
+
+ return (
+ this.regexp_eatCharacterClassEscape(state) ||
+ this.regexp_eatCharacterEscape(state)
+ )
+ };
+
+ pp$1.regexp_classSetExpression = function(state) {
+ var result = CharSetOk, subResult;
+ if (this.regexp_eatClassSetRange(state)) ; else if (subResult = this.regexp_eatClassSetOperand(state)) {
+ if (subResult === CharSetString) { result = CharSetString; }
+ var start = state.pos;
+ while (state.eatChars([0x26, 0x26] )) {
+ if (
+ state.current() !== 0x26 &&
+ (subResult = this.regexp_eatClassSetOperand(state))
+ ) {
+ if (subResult !== CharSetString) { result = CharSetOk; }
+ continue
+ }
+ state.raise("Invalid character in character class");
+ }
+ if (start !== state.pos) { return result }
+ while (state.eatChars([0x2D, 0x2D] )) {
+ if (this.regexp_eatClassSetOperand(state)) { continue }
+ state.raise("Invalid character in character class");
+ }
+ if (start !== state.pos) { return result }
+ } else {
+ state.raise("Invalid character in character class");
+ }
+ for (;;) {
+ if (this.regexp_eatClassSetRange(state)) { continue }
+ subResult = this.regexp_eatClassSetOperand(state);
+ if (!subResult) { return result }
+ if (subResult === CharSetString) { result = CharSetString; }
+ }
+ };
+
+ pp$1.regexp_eatClassSetRange = function(state) {
+ var start = state.pos;
+ if (this.regexp_eatClassSetCharacter(state)) {
+ var left = state.lastIntValue;
+ if (state.eat(0x2D ) && this.regexp_eatClassSetCharacter(state)) {
+ var right = state.lastIntValue;
+ if (left !== -1 && right !== -1 && left > right) {
+ state.raise("Range out of order in character class");
+ }
+ return true
+ }
+ state.pos = start;
+ }
+ return false
+ };
+
+ pp$1.regexp_eatClassSetOperand = function(state) {
+ if (this.regexp_eatClassSetCharacter(state)) { return CharSetOk }
+ return this.regexp_eatClassStringDisjunction(state) || this.regexp_eatNestedClass(state)
+ };
+
+ pp$1.regexp_eatNestedClass = function(state) {
+ var start = state.pos;
+ if (state.eat(0x5B )) {
+ var negate = state.eat(0x5E );
+ var result = this.regexp_classContents(state);
+ if (state.eat(0x5D )) {
+ if (negate && result === CharSetString) {
+ state.raise("Negated character class may contain strings");
+ }
+ return result
+ }
+ state.pos = start;
+ }
+ if (state.eat(0x5C )) {
+ var result$1 = this.regexp_eatCharacterClassEscape(state);
+ if (result$1) {
+ return result$1
+ }
+ state.pos = start;
+ }
+ return null
+ };
+
+ pp$1.regexp_eatClassStringDisjunction = function(state) {
+ var start = state.pos;
+ if (state.eatChars([0x5C, 0x71] )) {
+ if (state.eat(0x7B )) {
+ var result = this.regexp_classStringDisjunctionContents(state);
+ if (state.eat(0x7D )) {
+ return result
+ }
+ } else {
+ state.raise("Invalid escape");
+ }
+ state.pos = start;
+ }
+ return null
+ };
+
+ pp$1.regexp_classStringDisjunctionContents = function(state) {
+ var result = this.regexp_classString(state);
+ while (state.eat(0x7C )) {
+ if (this.regexp_classString(state) === CharSetString) { result = CharSetString; }
+ }
+ return result
+ };
+
+ pp$1.regexp_classString = function(state) {
+ var count = 0;
+ while (this.regexp_eatClassSetCharacter(state)) { count++; }
+ return count === 1 ? CharSetOk : CharSetString
+ };
+
+ pp$1.regexp_eatClassSetCharacter = function(state) {
+ var start = state.pos;
+ if (state.eat(0x5C )) {
+ if (
+ this.regexp_eatCharacterEscape(state) ||
+ this.regexp_eatClassSetReservedPunctuator(state)
+ ) {
+ return true
+ }
+ if (state.eat(0x62 )) {
+ state.lastIntValue = 0x08;
+ return true
+ }
+ state.pos = start;
+ return false
+ }
+ var ch = state.current();
+ if (ch < 0 || ch === state.lookahead() && isClassSetReservedDoublePunctuatorCharacter(ch)) { return false }
+ if (isClassSetSyntaxCharacter(ch)) { return false }
+ state.advance();
+ state.lastIntValue = ch;
+ return true
+ };
+
+ function isClassSetReservedDoublePunctuatorCharacter(ch) {
+ return (
+ ch === 0x21 ||
+ ch >= 0x23 && ch <= 0x26 ||
+ ch >= 0x2A && ch <= 0x2C ||
+ ch === 0x2E ||
+ ch >= 0x3A && ch <= 0x40 ||
+ ch === 0x5E ||
+ ch === 0x60 ||
+ ch === 0x7E
+ )
+ }
+
+ function isClassSetSyntaxCharacter(ch) {
+ return (
+ ch === 0x28 ||
+ ch === 0x29 ||
+ ch === 0x2D ||
+ ch === 0x2F ||
+ ch >= 0x5B && ch <= 0x5D ||
+ ch >= 0x7B && ch <= 0x7D
+ )
+ }
+
+ pp$1.regexp_eatClassSetReservedPunctuator = function(state) {
+ var ch = state.current();
+ if (isClassSetReservedPunctuator(ch)) {
+ state.lastIntValue = ch;
+ state.advance();
+ return true
+ }
+ return false
+ };
+
+ function isClassSetReservedPunctuator(ch) {
+ return (
+ ch === 0x21 ||
+ ch === 0x23 ||
+ ch === 0x25 ||
+ ch === 0x26 ||
+ ch === 0x2C ||
+ ch === 0x2D ||
+ ch >= 0x3A && ch <= 0x3E ||
+ ch === 0x40 ||
+ ch === 0x60 ||
+ ch === 0x7E
+ )
+ }
+
+ pp$1.regexp_eatClassControlLetter = function(state) {
+ var ch = state.current();
+ if (isDecimalDigit(ch) || ch === 0x5F ) {
+ state.lastIntValue = ch % 0x20;
+ state.advance();
+ return true
+ }
+ return false
+ };
+
+ pp$1.regexp_eatHexEscapeSequence = function(state) {
+ var start = state.pos;
+ if (state.eat(0x78 )) {
+ if (this.regexp_eatFixedHexDigits(state, 2)) {
+ return true
+ }
+ if (state.switchU) {
+ state.raise("Invalid escape");
+ }
+ state.pos = start;
+ }
+ return false
+ };
+
+ pp$1.regexp_eatDecimalDigits = function(state) {
+ var start = state.pos;
+ var ch = 0;
+ state.lastIntValue = 0;
+ while (isDecimalDigit(ch = state.current())) {
+ state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 );
+ state.advance();
+ }
+ return state.pos !== start
+ };
+ function isDecimalDigit(ch) {
+ return ch >= 0x30 && ch <= 0x39
+ }
+
+ pp$1.regexp_eatHexDigits = function(state) {
+ var start = state.pos;
+ var ch = 0;
+ state.lastIntValue = 0;
+ while (isHexDigit(ch = state.current())) {
+ state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);
+ state.advance();
+ }
+ return state.pos !== start
+ };
+ function isHexDigit(ch) {
+ return (
+ (ch >= 0x30 && ch <= 0x39 ) ||
+ (ch >= 0x41 && ch <= 0x46 ) ||
+ (ch >= 0x61 && ch <= 0x66 )
+ )
+ }
+ function hexToInt(ch) {
+ if (ch >= 0x41 && ch <= 0x46 ) {
+ return 10 + (ch - 0x41 )
+ }
+ if (ch >= 0x61 && ch <= 0x66 ) {
+ return 10 + (ch - 0x61 )
+ }
+ return ch - 0x30
+ }
+
+ pp$1.regexp_eatLegacyOctalEscapeSequence = function(state) {
+ if (this.regexp_eatOctalDigit(state)) {
+ var n1 = state.lastIntValue;
+ if (this.regexp_eatOctalDigit(state)) {
+ var n2 = state.lastIntValue;
+ if (n1 <= 3 && this.regexp_eatOctalDigit(state)) {
+ state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue;
+ } else {
+ state.lastIntValue = n1 * 8 + n2;
+ }
+ } else {
+ state.lastIntValue = n1;
+ }
+ return true
+ }
+ return false
+ };
+
+ pp$1.regexp_eatOctalDigit = function(state) {
+ var ch = state.current();
+ if (isOctalDigit(ch)) {
+ state.lastIntValue = ch - 0x30;
+ state.advance();
+ return true
+ }
+ state.lastIntValue = 0;
+ return false
+ };
+ function isOctalDigit(ch) {
+ return ch >= 0x30 && ch <= 0x37
+ }
+
+ pp$1.regexp_eatFixedHexDigits = function(state, length) {
+ var start = state.pos;
+ state.lastIntValue = 0;
+ for (var i = 0; i < length; ++i) {
+ var ch = state.current();
+ if (!isHexDigit(ch)) {
+ state.pos = start;
+ return false
+ }
+ state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);
+ state.advance();
+ }
+ return true
+ };
+
+
+ var Token = function Token(p) {
+ this.type = p.type;
+ this.value = p.value;
+ this.start = p.start;
+ this.end = p.end;
+ if (p.options.locations)
+ { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); }
+ if (p.options.ranges)
+ { this.range = [p.start, p.end]; }
+ };
+
+
+ var pp = Parser.prototype;
+
+
+ pp.next = function(ignoreEscapeSequenceInKeyword) {
+ if (!ignoreEscapeSequenceInKeyword && this.type.keyword && this.containsEsc)
+ { this.raiseRecoverable(this.start, "Escape sequence in keyword " + this.type.keyword); }
+ if (this.options.onToken)
+ { this.options.onToken(new Token(this)); }
+
+ this.lastTokEnd = this.end;
+ this.lastTokStart = this.start;
+ this.lastTokEndLoc = this.endLoc;
+ this.lastTokStartLoc = this.startLoc;
+ this.nextToken();
+ };
+
+ pp.getToken = function() {
+ this.next();
+ return new Token(this)
+ };
+
+ if (typeof Symbol !== "undefined")
+ { pp[Symbol.iterator] = function() {
+ var this$1$1 = this;
+
+ return {
+ next: function () {
+ var token = this$1$1.getToken();
+ return {
+ done: token.type === types$1.eof,
+ value: token
+ }
+ }
+ }
+ }; }
+
+
+
+ pp.nextToken = function() {
+ var curContext = this.curContext();
+ if (!curContext || !curContext.preserveSpace) { this.skipSpace(); }
+
+ this.start = this.pos;
+ if (this.options.locations) { this.startLoc = this.curPosition(); }
+ if (this.pos >= this.input.length) { return this.finishToken(types$1.eof) }
+
+ if (curContext.override) { return curContext.override(this) }
+ else { this.readToken(this.fullCharCodeAtPos()); }
+ };
+
+ pp.readToken = function(code) {
+ if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 )
+ { return this.readWord() }
+
+ return this.getTokenFromCode(code)
+ };
+
+ pp.fullCharCodeAtPos = function() {
+ var code = this.input.charCodeAt(this.pos);
+ if (code <= 0xd7ff || code >= 0xdc00) { return code }
+ var next = this.input.charCodeAt(this.pos + 1);
+ return next <= 0xdbff || next >= 0xe000 ? code : (code << 10) + next - 0x35fdc00
+ };
+
+ pp.skipBlockComment = function() {
+ var startLoc = this.options.onComment && this.curPosition();
+ var start = this.pos, end = this.input.indexOf("*/", this.pos += 2);
+ if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); }
+ this.pos = end + 2;
+ if (this.options.locations) {
+ for (var nextBreak = (void 0), pos = start; (nextBreak = nextLineBreak(this.input, pos, this.pos)) > -1;) {
+ ++this.curLine;
+ pos = this.lineStart = nextBreak;
+ }
+ }
+ if (this.options.onComment)
+ { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos,
+ startLoc, this.curPosition()); }
+ };
+
+ pp.skipLineComment = function(startSkip) {
+ var start = this.pos;
+ var startLoc = this.options.onComment && this.curPosition();
+ var ch = this.input.charCodeAt(this.pos += startSkip);
+ while (this.pos < this.input.length && !isNewLine(ch)) {
+ ch = this.input.charCodeAt(++this.pos);
+ }
+ if (this.options.onComment)
+ { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos,
+ startLoc, this.curPosition()); }
+ };
+
+
+ pp.skipSpace = function() {
+ loop: while (this.pos < this.input.length) {
+ var ch = this.input.charCodeAt(this.pos);
+ switch (ch) {
+ case 32: case 160:
+ ++this.pos;
+ break
+ case 13:
+ if (this.input.charCodeAt(this.pos + 1) === 10) {
+ ++this.pos;
+ }
+ case 10: case 8232: case 8233:
+ ++this.pos;
+ if (this.options.locations) {
+ ++this.curLine;
+ this.lineStart = this.pos;
+ }
+ break
+ case 47:
+ switch (this.input.charCodeAt(this.pos + 1)) {
+ case 42:
+ this.skipBlockComment();
+ break
+ case 47:
+ this.skipLineComment(2);
+ break
+ default:
+ break loop
+ }
+ break
+ default:
+ if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
+ ++this.pos;
+ } else {
+ break loop
+ }
+ }
+ }
+ };
+
+
+ pp.finishToken = function(type, val) {
+ this.end = this.pos;
+ if (this.options.locations) { this.endLoc = this.curPosition(); }
+ var prevType = this.type;
+ this.type = type;
+ this.value = val;
+
+ this.updateContext(prevType);
+ };
+
+
+ pp.readToken_dot = function() {
+ var next = this.input.charCodeAt(this.pos + 1);
+ if (next >= 48 && next <= 57) { return this.readNumber(true) }
+ var next2 = this.input.charCodeAt(this.pos + 2);
+ if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) {
+ this.pos += 3;
+ return this.finishToken(types$1.ellipsis)
+ } else {
+ ++this.pos;
+ return this.finishToken(types$1.dot)
+ }
+ };
+
+ pp.readToken_slash = function() {
+ var next = this.input.charCodeAt(this.pos + 1);
+ if (this.exprAllowed) { ++this.pos; return this.readRegexp() }
+ if (next === 61) { return this.finishOp(types$1.assign, 2) }
+ return this.finishOp(types$1.slash, 1)
+ };
+
+ pp.readToken_mult_modulo_exp = function(code) {
+ var next = this.input.charCodeAt(this.pos + 1);
+ var size = 1;
+ var tokentype = code === 42 ? types$1.star : types$1.modulo;
+
+ if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) {
+ ++size;
+ tokentype = types$1.starstar;
+ next = this.input.charCodeAt(this.pos + 2);
+ }
+
+ if (next === 61) { return this.finishOp(types$1.assign, size + 1) }
+ return this.finishOp(tokentype, size)
+ };
+
+ pp.readToken_pipe_amp = function(code) {
+ var next = this.input.charCodeAt(this.pos + 1);
+ if (next === code) {
+ if (this.options.ecmaVersion >= 12) {
+ var next2 = this.input.charCodeAt(this.pos + 2);
+ if (next2 === 61) { return this.finishOp(types$1.assign, 3) }
+ }
+ return this.finishOp(code === 124 ? types$1.logicalOR : types$1.logicalAND, 2)
+ }
+ if (next === 61) { return this.finishOp(types$1.assign, 2) }
+ return this.finishOp(code === 124 ? types$1.bitwiseOR : types$1.bitwiseAND, 1)
+ };
+
+ pp.readToken_caret = function() {
+ var next = this.input.charCodeAt(this.pos + 1);
+ if (next === 61) { return this.finishOp(types$1.assign, 2) }
+ return this.finishOp(types$1.bitwiseXOR, 1)
+ };
+
+ pp.readToken_plus_min = function(code) {
+ var next = this.input.charCodeAt(this.pos + 1);
+ if (next === code) {
+ if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 &&
+ (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) {
+ this.skipLineComment(3);
+ this.skipSpace();
+ return this.nextToken()
+ }
+ return this.finishOp(types$1.incDec, 2)
+ }
+ if (next === 61) { return this.finishOp(types$1.assign, 2) }
+ return this.finishOp(types$1.plusMin, 1)
+ };
+
+ pp.readToken_lt_gt = function(code) {
+ var next = this.input.charCodeAt(this.pos + 1);
+ var size = 1;
+ if (next === code) {
+ size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;
+ if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types$1.assign, size + 1) }
+ return this.finishOp(types$1.bitShift, size)
+ }
+ if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 &&
+ this.input.charCodeAt(this.pos + 3) === 45) {
+ this.skipLineComment(4);
+ this.skipSpace();
+ return this.nextToken()
+ }
+ if (next === 61) { size = 2; }
+ return this.finishOp(types$1.relational, size)
+ };
+
+ pp.readToken_eq_excl = function(code) {
+ var next = this.input.charCodeAt(this.pos + 1);
+ if (next === 61) { return this.finishOp(types$1.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2) }
+ if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) {
+ this.pos += 2;
+ return this.finishToken(types$1.arrow)
+ }
+ return this.finishOp(code === 61 ? types$1.eq : types$1.prefix, 1)
+ };
+
+ pp.readToken_question = function() {
+ var ecmaVersion = this.options.ecmaVersion;
+ if (ecmaVersion >= 11) {
+ var next = this.input.charCodeAt(this.pos + 1);
+ if (next === 46) {
+ var next2 = this.input.charCodeAt(this.pos + 2);
+ if (next2 < 48 || next2 > 57) { return this.finishOp(types$1.questionDot, 2) }
+ }
+ if (next === 63) {
+ if (ecmaVersion >= 12) {
+ var next2$1 = this.input.charCodeAt(this.pos + 2);
+ if (next2$1 === 61) { return this.finishOp(types$1.assign, 3) }
+ }
+ return this.finishOp(types$1.coalesce, 2)
+ }
+ }
+ return this.finishOp(types$1.question, 1)
+ };
+
+ pp.readToken_numberSign = function() {
+ var ecmaVersion = this.options.ecmaVersion;
+ var code = 35;
+ if (ecmaVersion >= 13) {
+ ++this.pos;
+ code = this.fullCharCodeAtPos();
+ if (isIdentifierStart(code, true) || code === 92 ) {
+ return this.finishToken(types$1.privateId, this.readWord1())
+ }
+ }
+
+ this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'");
+ };
+
+ pp.getTokenFromCode = function(code) {
+ switch (code) {
+ case 46:
+ return this.readToken_dot()
+
+ case 40: ++this.pos; return this.finishToken(types$1.parenL)
+ case 41: ++this.pos; return this.finishToken(types$1.parenR)
+ case 59: ++this.pos; return this.finishToken(types$1.semi)
+ case 44: ++this.pos; return this.finishToken(types$1.comma)
+ case 91: ++this.pos; return this.finishToken(types$1.bracketL)
+ case 93: ++this.pos; return this.finishToken(types$1.bracketR)
+ case 123: ++this.pos; return this.finishToken(types$1.braceL)
+ case 125: ++this.pos; return this.finishToken(types$1.braceR)
+ case 58: ++this.pos; return this.finishToken(types$1.colon)
+
+ case 96:
+ if (this.options.ecmaVersion < 6) { break }
+ ++this.pos;
+ return this.finishToken(types$1.backQuote)
+
+ case 48:
+ var next = this.input.charCodeAt(this.pos + 1);
+ if (next === 120 || next === 88) { return this.readRadixNumber(16) }
+ if (this.options.ecmaVersion >= 6) {
+ if (next === 111 || next === 79) { return this.readRadixNumber(8) }
+ if (next === 98 || next === 66) { 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(false)
+
+ case 34: case 39:
+ return this.readString(code)
+
+ case 47:
+ return this.readToken_slash()
+
+ case 37: case 42:
+ return this.readToken_mult_modulo_exp(code)
+
+ case 124: case 38:
+ return this.readToken_pipe_amp(code)
+
+ case 94:
+ return this.readToken_caret()
+
+ case 43: case 45:
+ return this.readToken_plus_min(code)
+
+ case 60: case 62:
+ return this.readToken_lt_gt(code)
+
+ case 61: case 33:
+ return this.readToken_eq_excl(code)
+
+ case 63:
+ return this.readToken_question()
+
+ case 126:
+ return this.finishOp(types$1.prefix, 1)
+
+ case 35:
+ return this.readToken_numberSign()
+ }
+
+ this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'");
+ };
+
+ pp.finishOp = function(type, size) {
+ var str = this.input.slice(this.pos, this.pos + size);
+ this.pos += size;
+ return this.finishToken(type, str)
+ };
+
+ pp.readRegexp = function() {
+ var escaped, inClass, start = this.pos;
+ for (;;) {
+ if (this.pos >= this.input.length) { this.raise(start, "Unterminated regular expression"); }
+ var ch = this.input.charAt(this.pos);
+ if (lineBreak.test(ch)) { this.raise(start, "Unterminated regular expression"); }
+ if (!escaped) {
+ if (ch === "[") { inClass = true; }
+ else if (ch === "]" && inClass) { inClass = false; }
+ else if (ch === "/" && !inClass) { break }
+ escaped = ch === "\\";
+ } else { escaped = false; }
+ ++this.pos;
+ }
+ var pattern = this.input.slice(start, this.pos);
+ ++this.pos;
+ var flagsStart = this.pos;
+ var flags = this.readWord1();
+ if (this.containsEsc) { this.unexpected(flagsStart); }
+
+ var state = this.regexpState || (this.regexpState = new RegExpValidationState(this));
+ state.reset(start, pattern, flags);
+ this.validateRegExpFlags(state);
+ this.validateRegExpPattern(state);
+
+ var value = null;
+ try {
+ value = new RegExp(pattern, flags);
+ } catch (e) {
+ }
+
+ return this.finishToken(types$1.regexp, {pattern: pattern, flags: flags, value: value})
+ };
+
+
+ pp.readInt = function(radix, len, maybeLegacyOctalNumericLiteral) {
+ var allowSeparators = this.options.ecmaVersion >= 12 && len === undefined;
+
+ var isLegacyOctalNumericLiteral = maybeLegacyOctalNumericLiteral && this.input.charCodeAt(this.pos) === 48;
+
+ var start = this.pos, total = 0, lastCode = 0;
+ for (var i = 0, e = len == null ? Infinity : len; i < e; ++i, ++this.pos) {
+ var code = this.input.charCodeAt(this.pos), val = (void 0);
+
+ if (allowSeparators && code === 95) {
+ if (isLegacyOctalNumericLiteral) { this.raiseRecoverable(this.pos, "Numeric separator is not allowed in legacy octal numeric literals"); }
+ if (lastCode === 95) { this.raiseRecoverable(this.pos, "Numeric separator must be exactly one underscore"); }
+ if (i === 0) { this.raiseRecoverable(this.pos, "Numeric separator is not allowed at the first of digits"); }
+ lastCode = code;
+ continue
+ }
+
+ if (code >= 97) { val = code - 97 + 10; }
+ else if (code >= 65) { val = code - 65 + 10; }
+ else if (code >= 48 && code <= 57) { val = code - 48; }
+ else { val = Infinity; }
+ if (val >= radix) { break }
+ lastCode = code;
+ total = total * radix + val;
+ }
+
+ if (allowSeparators && lastCode === 95) { this.raiseRecoverable(this.pos - 1, "Numeric separator is not allowed at the last of digits"); }
+ if (this.pos === start || len != null && this.pos - start !== len) { return null }
+
+ return total
+ };
+
+ function stringToNumber(str, isLegacyOctalNumericLiteral) {
+ if (isLegacyOctalNumericLiteral) {
+ return parseInt(str, 8)
+ }
+
+ return parseFloat(str.replace(/_/g, ""))
+ }
+
+ function stringToBigInt(str) {
+ if (typeof BigInt !== "function") {
+ return null
+ }
+
+ return BigInt(str.replace(/_/g, ""))
+ }
+
+ pp.readRadixNumber = function(radix) {
+ var start = this.pos;
+ this.pos += 2;
+ var val = this.readInt(radix);
+ if (val == null) { this.raise(this.start + 2, "Expected number in radix " + radix); }
+ if (this.options.ecmaVersion >= 11 && this.input.charCodeAt(this.pos) === 110) {
+ val = stringToBigInt(this.input.slice(start, this.pos));
+ ++this.pos;
+ } else if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
+ return this.finishToken(types$1.num, val)
+ };
+
+
+ pp.readNumber = function(startsWithDot) {
+ var start = this.pos;
+ if (!startsWithDot && this.readInt(10, undefined, true) === null) { this.raise(start, "Invalid number"); }
+ var octal = this.pos - start >= 2 && this.input.charCodeAt(start) === 48;
+ if (octal && this.strict) { this.raise(start, "Invalid number"); }
+ var next = this.input.charCodeAt(this.pos);
+ if (!octal && !startsWithDot && this.options.ecmaVersion >= 11 && next === 110) {
+ var val$1 = stringToBigInt(this.input.slice(start, this.pos));
+ ++this.pos;
+ if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
+ return this.finishToken(types$1.num, val$1)
+ }
+ if (octal && /[89]/.test(this.input.slice(start, this.pos))) { octal = false; }
+ if (next === 46 && !octal) {
+ ++this.pos;
+ this.readInt(10);
+ next = this.input.charCodeAt(this.pos);
+ }
+ if ((next === 69 || next === 101) && !octal) {
+ next = this.input.charCodeAt(++this.pos);
+ if (next === 43 || next === 45) { ++this.pos; }
+ if (this.readInt(10) === null) { this.raise(start, "Invalid number"); }
+ }
+ if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
+
+ var val = stringToNumber(this.input.slice(start, this.pos), octal);
+ return this.finishToken(types$1.num, val)
+ };
+
+
+ pp.readCodePoint = function() {
+ var ch = this.input.charCodeAt(this.pos), code;
+
+ if (ch === 123) {
+ if (this.options.ecmaVersion < 6) { this.unexpected(); }
+ var codePos = ++this.pos;
+ code = this.readHexChar(this.input.indexOf("}", this.pos) - this.pos);
+ ++this.pos;
+ if (code > 0x10FFFF) { this.invalidStringToken(codePos, "Code point out of bounds"); }
+ } else {
+ code = this.readHexChar(4);
+ }
+ return code
+ };
+
+ pp.readString = function(quote) {
+ var out = "", chunkStart = ++this.pos;
+ for (;;) {
+ if (this.pos >= this.input.length) { this.raise(this.start, "Unterminated string constant"); }
+ var ch = this.input.charCodeAt(this.pos);
+ if (ch === quote) { break }
+ if (ch === 92) {
+ out += this.input.slice(chunkStart, this.pos);
+ out += this.readEscapedChar(false);
+ chunkStart = this.pos;
+ } else if (ch === 0x2028 || ch === 0x2029) {
+ if (this.options.ecmaVersion < 10) { this.raise(this.start, "Unterminated string constant"); }
+ ++this.pos;
+ if (this.options.locations) {
+ this.curLine++;
+ this.lineStart = this.pos;
+ }
+ } else {
+ if (isNewLine(ch)) { this.raise(this.start, "Unterminated string constant"); }
+ ++this.pos;
+ }
+ }
+ out += this.input.slice(chunkStart, this.pos++);
+ return this.finishToken(types$1.string, out)
+ };
+
+
+ var INVALID_TEMPLATE_ESCAPE_ERROR = {};
+
+ pp.tryReadTemplateToken = function() {
+ this.inTemplateElement = true;
+ try {
+ this.readTmplToken();
+ } catch (err) {
+ if (err === INVALID_TEMPLATE_ESCAPE_ERROR) {
+ this.readInvalidTemplateToken();
+ } else {
+ throw err
+ }
+ }
+
+ this.inTemplateElement = false;
+ };
+
+ pp.invalidStringToken = function(position, message) {
+ if (this.inTemplateElement && this.options.ecmaVersion >= 9) {
+ throw INVALID_TEMPLATE_ESCAPE_ERROR
+ } else {
+ this.raise(position, message);
+ }
+ };
+
+ pp.readTmplToken = function() {
+ var out = "", chunkStart = this.pos;
+ for (;;) {
+ if (this.pos >= this.input.length) { this.raise(this.start, "Unterminated template"); }
+ var ch = this.input.charCodeAt(this.pos);
+ if (ch === 96 || ch === 36 && this.input.charCodeAt(this.pos + 1) === 123) {
+ if (this.pos === this.start && (this.type === types$1.template || this.type === types$1.invalidTemplate)) {
+ if (ch === 36) {
+ this.pos += 2;
+ return this.finishToken(types$1.dollarBraceL)
+ } else {
+ ++this.pos;
+ return this.finishToken(types$1.backQuote)
+ }
+ }
+ out += this.input.slice(chunkStart, this.pos);
+ return this.finishToken(types$1.template, out)
+ }
+ if (ch === 92) {
+ out += this.input.slice(chunkStart, this.pos);
+ out += this.readEscapedChar(true);
+ chunkStart = this.pos;
+ } else if (isNewLine(ch)) {
+ out += this.input.slice(chunkStart, this.pos);
+ ++this.pos;
+ switch (ch) {
+ case 13:
+ if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; }
+ case 10:
+ out += "\n";
+ break
+ default:
+ out += String.fromCharCode(ch);
+ break
+ }
+ if (this.options.locations) {
+ ++this.curLine;
+ this.lineStart = this.pos;
+ }
+ chunkStart = this.pos;
+ } else {
+ ++this.pos;
+ }
+ }
+ };
+
+ pp.readInvalidTemplateToken = function() {
+ for (; this.pos < this.input.length; this.pos++) {
+ switch (this.input[this.pos]) {
+ case "\\":
+ ++this.pos;
+ break
+
+ case "$":
+ if (this.input[this.pos + 1] !== "{") { break }
+ case "`":
+ return this.finishToken(types$1.invalidTemplate, this.input.slice(this.start, this.pos))
+
+ case "\r":
+ if (this.input[this.pos + 1] === "\n") { ++this.pos; }
+ case "\n": case "\u2028": case "\u2029":
+ ++this.curLine;
+ this.lineStart = this.pos + 1;
+ break
+ }
+ }
+ this.raise(this.start, "Unterminated template");
+ };
+
+
+ pp.readEscapedChar = function(inTemplate) {
+ var ch = this.input.charCodeAt(++this.pos);
+ ++this.pos;
+ switch (ch) {
+ case 110: return "\n"
+ case 114: return "\r"
+ case 120: return String.fromCharCode(this.readHexChar(2))
+ case 117: return codePointToString(this.readCodePoint())
+ case 116: return "\t"
+ case 98: return "\b"
+ case 118: return "\u000b"
+ case 102: return "\f"
+ case 13: if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; }
+ case 10:
+ if (this.options.locations) { this.lineStart = this.pos; ++this.curLine; }
+ return ""
+ case 56:
+ case 57:
+ if (this.strict) {
+ this.invalidStringToken(
+ this.pos - 1,
+ "Invalid escape sequence"
+ );
+ }
+ if (inTemplate) {
+ var codePos = this.pos - 1;
+
+ this.invalidStringToken(
+ codePos,
+ "Invalid escape sequence in template string"
+ );
+ }
+ default:
+ if (ch >= 48 && ch <= 55) {
+ var octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0];
+ var octal = parseInt(octalStr, 8);
+ if (octal > 255) {
+ octalStr = octalStr.slice(0, -1);
+ octal = parseInt(octalStr, 8);
+ }
+ this.pos += octalStr.length - 1;
+ ch = this.input.charCodeAt(this.pos);
+ if ((octalStr !== "0" || ch === 56 || ch === 57) && (this.strict || inTemplate)) {
+ this.invalidStringToken(
+ this.pos - 1 - octalStr.length,
+ inTemplate
+ ? "Octal literal in template string"
+ : "Octal literal in strict mode"
+ );
+ }
+ return String.fromCharCode(octal)
+ }
+ if (isNewLine(ch)) {
+ if (this.options.locations) { this.lineStart = this.pos; ++this.curLine; }
+ return ""
+ }
+ return String.fromCharCode(ch)
+ }
+ };
+
+
+ pp.readHexChar = function(len) {
+ var codePos = this.pos;
+ var n = this.readInt(16, len);
+ if (n === null) { this.invalidStringToken(codePos, "Bad character escape sequence"); }
+ return n
+ };
+
+
+ pp.readWord1 = function() {
+ this.containsEsc = false;
+ var word = "", first = true, chunkStart = this.pos;
+ var astral = this.options.ecmaVersion >= 6;
+ while (this.pos < this.input.length) {
+ var ch = this.fullCharCodeAtPos();
+ if (isIdentifierChar(ch, astral)) {
+ this.pos += ch <= 0xffff ? 1 : 2;
+ } else if (ch === 92) {
+ this.containsEsc = true;
+ word += this.input.slice(chunkStart, this.pos);
+ var escStart = this.pos;
+ if (this.input.charCodeAt(++this.pos) !== 117)
+ { this.invalidStringToken(this.pos, "Expecting Unicode escape sequence \\uXXXX"); }
+ ++this.pos;
+ var esc = this.readCodePoint();
+ if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral))
+ { this.invalidStringToken(escStart, "Invalid Unicode escape"); }
+ word += codePointToString(esc);
+ chunkStart = this.pos;
+ } else {
+ break
+ }
+ first = false;
+ }
+ return word + this.input.slice(chunkStart, this.pos)
+ };
+
+
+ pp.readWord = function() {
+ var word = this.readWord1();
+ var type = types$1.name;
+ if (this.keywords.test(word)) {
+ type = keywords[word];
+ }
+ return this.finishToken(type, word)
+ };
+
+
+
+ var version = "8.14.0";
+
+ Parser.acorn = {
+ Parser: Parser,
+ version: version,
+ defaultOptions: defaultOptions,
+ Position: Position,
+ SourceLocation: SourceLocation,
+ getLineInfo: getLineInfo,
+ Node: Node,
+ TokenType: TokenType,
+ tokTypes: types$1,
+ keywordTypes: keywords,
+ TokContext: TokContext,
+ tokContexts: types,
+ isIdentifierChar: isIdentifierChar,
+ isIdentifierStart: isIdentifierStart,
+ Token: Token,
+ isNewLine: isNewLine,
+ lineBreak: lineBreak,
+ lineBreakG: lineBreakG,
+ nonASCIIwhitespace: nonASCIIwhitespace
+ };
+
+
+ function parse(input, options) {
+ return Parser.parse(input, options)
+ }
+
+
+ function parseExpressionAt(input, pos, options) {
+ return Parser.parseExpressionAt(input, pos, options)
+ }
+
+
+ function tokenizer(input, options) {
+ return Parser.tokenizer(input, options)
+ }
+
+ exports.Node = Node;
+ exports.Parser = Parser;
+ exports.Position = Position;
+ exports.SourceLocation = SourceLocation;
+ exports.TokContext = TokContext;
+ exports.Token = Token;
+ exports.TokenType = TokenType;
+ exports.defaultOptions = defaultOptions;
+ exports.getLineInfo = getLineInfo;
+ exports.isIdentifierChar = isIdentifierChar;
+ exports.isIdentifierStart = isIdentifierStart;
+ exports.isNewLine = isNewLine;
+ exports.keywordTypes = keywords;
+ exports.lineBreak = lineBreak;
+ exports.lineBreakG = lineBreakG;
+ exports.nonASCIIwhitespace = nonASCIIwhitespace;
+ exports.parse = parse;
+ exports.parseExpressionAt = parseExpressionAt;
+ exports.tokContexts = types;
+ exports.tokTypes = types$1;
+ exports.tokenizer = tokenizer;
+ exports.version = version;
+
+}));
+
+},{}],2:[function(require,module,exports){
+
+},{}],3:[function(require,module,exports){
+function glWiretap(gl, options = {}) {
+ const {
+ contextName = 'gl',
+ throwGetError,
+ useTrackablePrimitives,
+ readPixelsFile,
+ recording = [],
+ variables = {},
+ onReadPixels,
+ onUnrecognizedArgumentLookup,
+ } = options;
+ const proxy = new Proxy(gl, { get: listen });
+ const contextVariables = [];
+ const entityNames = {};
+ let imageCount = 0;
+ let indent = '';
+ let readPixelsVariableName;
+ return proxy;
+ function listen(obj, property) {
+ switch (property) {
+ case 'addComment': return addComment;
+ case 'checkThrowError': return checkThrowError;
+ case 'getReadPixelsVariableName': return readPixelsVariableName;
+ case 'insertVariable': return insertVariable;
+ case 'reset': return reset;
+ case 'setIndent': return setIndent;
+ case 'toString': return toString;
+ case 'getContextVariableName': return getContextVariableName;
+ }
+ if (typeof gl[property] === 'function') {
+ return function() {
+ switch (property) {
+ case 'getError':
+ if (throwGetError) {
+ recording.push(`${indent}if (${contextName}.getError() !== ${contextName}.NONE) throw new Error('error');`);
+ } else {
+ recording.push(`${indent}${contextName}.getError();`);
+ }
+ return gl.getError();
+ case 'getExtension': {
+ const variableName = `${contextName}Variables${contextVariables.length}`;
+ recording.push(`${indent}const ${variableName} = ${contextName}.getExtension('${arguments[0]}');`);
+ const extension = gl.getExtension(arguments[0]);
+ if (extension && typeof extension === 'object') {
+ const tappedExtension = glExtensionWiretap(extension, {
+ getEntity,
+ useTrackablePrimitives,
+ recording,
+ contextName: variableName,
+ contextVariables,
+ variables,
+ indent,
+ onUnrecognizedArgumentLookup,
+ });
+ contextVariables.push(tappedExtension);
+ return tappedExtension;
+ } else {
+ contextVariables.push(null);
+ }
+ return extension;
+ }
+ case 'readPixels':
+ const i = contextVariables.indexOf(arguments[6]);
+ let targetVariableName;
+ if (i === -1) {
+ const variableName = getVariableName(arguments[6]);
+ if (variableName) {
+ targetVariableName = variableName;
+ recording.push(`${indent}${variableName}`);
+ } else {
+ targetVariableName = `${contextName}Variable${contextVariables.length}`;
+ contextVariables.push(arguments[6]);
+ recording.push(`${indent}const ${targetVariableName} = new ${arguments[6].constructor.name}(${arguments[6].length});`);
+ }
+ } else {
+ targetVariableName = `${contextName}Variable${i}`;
+ }
+ readPixelsVariableName = targetVariableName;
+ const argumentAsStrings = [
+ arguments[0],
+ arguments[1],
+ arguments[2],
+ arguments[3],
+ getEntity(arguments[4]),
+ getEntity(arguments[5]),
+ targetVariableName
+ ];
+ recording.push(`${indent}${contextName}.readPixels(${argumentAsStrings.join(', ')});`);
+ if (readPixelsFile) {
+ writePPM(arguments[2], arguments[3]);
+ }
+ if (onReadPixels) {
+ onReadPixels(targetVariableName, argumentAsStrings);
+ }
+ return gl.readPixels.apply(gl, arguments);
+ case 'drawBuffers':
+ recording.push(`${indent}${contextName}.drawBuffers([${argumentsToString(arguments[0], { contextName, contextVariables, getEntity, addVariable, variables, onUnrecognizedArgumentLookup } )}]);`);
+ return gl.drawBuffers(arguments[0]);
+ }
+ let result = gl[property].apply(gl, arguments);
+ switch (typeof result) {
+ case 'undefined':
+ recording.push(`${indent}${methodCallToString(property, arguments)};`);
+ return;
+ case 'number':
+ case 'boolean':
+ if (useTrackablePrimitives && contextVariables.indexOf(trackablePrimitive(result)) === -1) {
+ recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);
+ contextVariables.push(result = trackablePrimitive(result));
+ break;
+ }
+ default:
+ if (result === null) {
+ recording.push(`${methodCallToString(property, arguments)};`);
+ } else {
+ recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);
+ }
+
+ contextVariables.push(result);
+ }
+ return result;
+ }
+ }
+ entityNames[gl[property]] = property;
+ return gl[property];
+ }
+ function toString() {
+ return recording.join('\n');
+ }
+ function reset() {
+ while (recording.length > 0) {
+ recording.pop();
+ }
+ }
+ function insertVariable(name, value) {
+ variables[name] = value;
+ }
+ function getEntity(value) {
+ const name = entityNames[value];
+ if (name) {
+ return contextName + '.' + name;
+ }
+ return value;
+ }
+ function setIndent(spaces) {
+ indent = ' '.repeat(spaces);
+ }
+ function addVariable(value, source) {
+ const variableName = `${contextName}Variable${contextVariables.length}`;
+ recording.push(`${indent}const ${variableName} = ${source};`);
+ contextVariables.push(value);
+ return variableName;
+ }
+ function writePPM(width, height) {
+ const sourceVariable = `${contextName}Variable${contextVariables.length}`;
+ const imageVariable = `imageDatum${imageCount}`;
+ recording.push(`${indent}let ${imageVariable} = ["P3\\n# ${readPixelsFile}.ppm\\n", ${width}, ' ', ${height}, "\\n255\\n"].join("");`);
+ recording.push(`${indent}for (let i = 0; i < ${imageVariable}.length; i += 4) {`);
+ recording.push(`${indent} ${imageVariable} += ${sourceVariable}[i] + ' ' + ${sourceVariable}[i + 1] + ' ' + ${sourceVariable}[i + 2] + ' ';`);
+ recording.push(`${indent}}`);
+ recording.push(`${indent}if (typeof require !== "undefined") {`);
+ recording.push(`${indent} require('fs').writeFileSync('./${readPixelsFile}.ppm', ${imageVariable});`);
+ recording.push(`${indent}}`);
+ imageCount++;
+ }
+ function addComment(value) {
+ recording.push(`${indent}// ${value}`);
+ }
+ function checkThrowError() {
+ recording.push(`${indent}(() => {
+${indent}const error = ${contextName}.getError();
+${indent}if (error !== ${contextName}.NONE) {
+${indent} const names = Object.getOwnPropertyNames(gl);
+${indent} for (let i = 0; i < names.length; i++) {
+${indent} const name = names[i];
+${indent} if (${contextName}[name] === error) {
+${indent} throw new Error('${contextName} threw ' + name);
+${indent} }
+${indent} }
+${indent}}
+${indent}})();`);
+ }
+ function methodCallToString(method, args) {
+ return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`;
+ }
+
+ function getVariableName(value) {
+ if (variables) {
+ for (const name in variables) {
+ if (variables[name] === value) {
+ return name;
+ }
+ }
+ }
+ return null;
+ }
+
+ function getContextVariableName(value) {
+ const i = contextVariables.indexOf(value);
+ if (i !== -1) {
+ return `${contextName}Variable${i}`;
+ }
+ return null;
+ }
+}
+
+function glExtensionWiretap(extension, options) {
+ const proxy = new Proxy(extension, { get: listen });
+ const extensionEntityNames = {};
+ const {
+ contextName,
+ contextVariables,
+ getEntity,
+ useTrackablePrimitives,
+ recording,
+ variables,
+ indent,
+ onUnrecognizedArgumentLookup,
+ } = options;
+ return proxy;
+ function listen(obj, property) {
+ if (typeof obj[property] === 'function') {
+ return function() {
+ switch (property) {
+ case 'drawBuffersWEBGL':
+ recording.push(`${indent}${contextName}.drawBuffersWEBGL([${argumentsToString(arguments[0], { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })}]);`);
+ return extension.drawBuffersWEBGL(arguments[0]);
+ }
+ let result = extension[property].apply(extension, arguments);
+ switch (typeof result) {
+ case 'undefined':
+ recording.push(`${indent}${methodCallToString(property, arguments)};`);
+ return;
+ case 'number':
+ case 'boolean':
+ if (useTrackablePrimitives && contextVariables.indexOf(trackablePrimitive(result)) === -1) {
+ recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);
+ contextVariables.push(result = trackablePrimitive(result));
+ } else {
+ recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);
+ contextVariables.push(result);
+ }
+ break;
+ default:
+ if (result === null) {
+ recording.push(`${methodCallToString(property, arguments)};`);
+ } else {
+ recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);
+ }
+ contextVariables.push(result);
+ }
+ return result;
+ };
+ }
+ extensionEntityNames[extension[property]] = property;
+ return extension[property];
+ }
+
+ function getExtensionEntity(value) {
+ if (extensionEntityNames.hasOwnProperty(value)) {
+ return `${contextName}.${extensionEntityNames[value]}`;
+ }
+ return getEntity(value);
+ }
+
+ function methodCallToString(method, args) {
+ return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`;
+ }
+
+ function addVariable(value, source) {
+ const variableName = `${contextName}Variable${contextVariables.length}`;
+ contextVariables.push(value);
+ recording.push(`${indent}const ${variableName} = ${source};`);
+ return variableName;
+ }
+}
+
+function argumentsToString(args, options) {
+ const { variables, onUnrecognizedArgumentLookup } = options;
+ return (Array.from(args).map((arg) => {
+ const variableName = getVariableName(arg);
+ if (variableName) {
+ return variableName;
+ }
+ return argumentToString(arg, options);
+ }).join(', '));
+
+ function getVariableName(value) {
+ if (variables) {
+ for (const name in variables) {
+ if (!variables.hasOwnProperty(name)) continue;
+ if (variables[name] === value) {
+ return name;
+ }
+ }
+ }
+ if (onUnrecognizedArgumentLookup) {
+ return onUnrecognizedArgumentLookup(value);
+ }
+ return null;
+ }
+}
+
+function argumentToString(arg, options) {
+ const { contextName, contextVariables, getEntity, addVariable, onUnrecognizedArgumentLookup } = options;
+ if (typeof arg === 'undefined') {
+ return 'undefined';
+ }
+ if (arg === null) {
+ return 'null';
+ }
+ const i = contextVariables.indexOf(arg);
+ if (i > -1) {
+ return `${contextName}Variable${i}`;
+ }
+ switch (arg.constructor.name) {
+ case 'String':
+ const hasLines = /\n/.test(arg);
+ const hasSingleQuotes = /'/.test(arg);
+ const hasDoubleQuotes = /"/.test(arg);
+ if (hasLines) {
+ return '`' + arg + '`';
+ } else if (hasSingleQuotes && !hasDoubleQuotes) {
+ return '"' + arg + '"';
+ } else if (!hasSingleQuotes && hasDoubleQuotes) {
+ return "'" + arg + "'";
+ } else {
+ return '\'' + arg + '\'';
+ }
+ case 'Number': return getEntity(arg);
+ case 'Boolean': return getEntity(arg);
+ case 'Array':
+ return addVariable(arg, `new ${arg.constructor.name}([${Array.from(arg).join(',')}])`);
+ case 'Float32Array':
+ case 'Uint8Array':
+ case 'Uint16Array':
+ case 'Int32Array':
+ return addVariable(arg, `new ${arg.constructor.name}(${JSON.stringify(Array.from(arg))})`);
+ default:
+ if (onUnrecognizedArgumentLookup) {
+ const instantiationString = onUnrecognizedArgumentLookup(arg);
+ if (instantiationString) {
+ return instantiationString;
+ }
+ }
+ throw new Error(`unrecognized argument type ${arg.constructor.name}`);
+ }
+}
+
+function trackablePrimitive(value) {
+ return new value.constructor(value);
+}
+
+if (typeof module !== 'undefined') {
+ module.exports = { glWiretap, glExtensionWiretap };
+}
+
+if (typeof window !== 'undefined') {
+ glWiretap.glExtensionWiretap = glExtensionWiretap;
+ window.glWiretap = glWiretap;
+}
+
+},{}],4:[function(require,module,exports){
+function setupArguments(args) {
+ const newArguments = new Array(args.length);
+ for (let i = 0; i < args.length; i++) {
+ const arg = args[i];
+ if (arg.toArray) {
+ newArguments[i] = arg.toArray();
+ } else {
+ newArguments[i] = arg;
+ }
+ }
+ return newArguments;
+}
+
+function mock1D() {
+ const args = setupArguments(arguments);
+ const row = new Float32Array(this.output.x);
+ for (let x = 0; x < this.output.x; x++) {
+ this.thread.x = x;
+ this.thread.y = 0;
+ this.thread.z = 0;
+ row[x] = this._fn.apply(this, args);
+ }
+ return row;
+}
+
+function mock2D() {
+ const args = setupArguments(arguments);
+ const matrix = new Array(this.output.y);
+ for (let y = 0; y < this.output.y; y++) {
+ const row = new Float32Array(this.output.x);
+ for (let x = 0; x < this.output.x; x++) {
+ this.thread.x = x;
+ this.thread.y = y;
+ this.thread.z = 0;
+ row[x] = this._fn.apply(this, args);
+ }
+ matrix[y] = row;
+ }
+ return matrix;
+}
+
+function mock2DGraphical() {
+ const args = setupArguments(arguments);
+ for (let y = 0; y < this.output.y; y++) {
+ for (let x = 0; x < this.output.x; x++) {
+ this.thread.x = x;
+ this.thread.y = y;
+ this.thread.z = 0;
+ this._fn.apply(this, args);
+ }
+ }
+}
+
+function mock3D() {
+ const args = setupArguments(arguments);
+ const cube = new Array(this.output.z);
+ for (let z = 0; z < this.output.z; z++) {
+ const matrix = new Array(this.output.y);
+ for (let y = 0; y < this.output.y; y++) {
+ const row = new Float32Array(this.output.x);
+ for (let x = 0; x < this.output.x; x++) {
+ this.thread.x = x;
+ this.thread.y = y;
+ this.thread.z = z;
+ row[x] = this._fn.apply(this, args);
+ }
+ matrix[y] = row;
+ }
+ cube[z] = matrix;
+ }
+ return cube;
+}
+
+function apiDecorate(kernel) {
+ kernel.setOutput = (output) => {
+ kernel.output = setupOutput(output);
+ if (kernel.graphical) {
+ setupGraphical(kernel);
+ }
+ };
+ kernel.toJSON = () => {
+ throw new Error('Not usable with gpuMock');
+ };
+ kernel.setConstants = (flag) => {
+ kernel.constants = flag;
+ return kernel;
+ };
+ kernel.setGraphical = (flag) => {
+ kernel.graphical = flag;
+ return kernel;
+ };
+ kernel.setCanvas = (flag) => {
+ kernel.canvas = flag;
+ return kernel;
+ };
+ kernel.setContext = (flag) => {
+ kernel.context = flag;
+ return kernel;
+ };
+ kernel.destroy = () => {};
+ kernel.validateSettings = () => {};
+ if (kernel.graphical && kernel.output) {
+ setupGraphical(kernel);
+ }
+ kernel.exec = function() {
+ return new Promise((resolve, reject) => {
+ try {
+ resolve(kernel.apply(kernel, arguments));
+ } catch(e) {
+ reject(e);
+ }
+ });
+ };
+ kernel.getPixels = (flip) => {
+ const {x, y} = kernel.output;
+ return flip ? flipPixels(kernel._imageData.data, x, y) : kernel._imageData.data.slice(0);
+ };
+ kernel.color = function(r, g, b, a) {
+ if (typeof a === 'undefined') {
+ a = 1;
+ }
+
+ r = Math.floor(r * 255);
+ g = Math.floor(g * 255);
+ b = Math.floor(b * 255);
+ a = Math.floor(a * 255);
+
+ const width = kernel.output.x;
+ const height = kernel.output.y;
+
+ const x = kernel.thread.x;
+ const y = height - kernel.thread.y - 1;
+
+ const index = x + y * width;
+
+ kernel._colorData[index * 4 + 0] = r;
+ kernel._colorData[index * 4 + 1] = g;
+ kernel._colorData[index * 4 + 2] = b;
+ kernel._colorData[index * 4 + 3] = a;
+ };
+
+ const mockMethod = () => kernel;
+ const methods = [
+ 'setWarnVarUsage',
+ 'setArgumentTypes',
+ 'setTactic',
+ 'setOptimizeFloatMemory',
+ 'setDebug',
+ 'setLoopMaxIterations',
+ 'setConstantTypes',
+ 'setFunctions',
+ 'setNativeFunctions',
+ 'setInjectedNative',
+ 'setPipeline',
+ 'setPrecision',
+ 'setOutputToTexture',
+ 'setImmutable',
+ 'setStrictIntegers',
+ 'setDynamicOutput',
+ 'setHardcodeConstants',
+ 'setDynamicArguments',
+ 'setUseLegacyEncoder',
+ 'setWarnVarUsage',
+ 'addSubKernel',
+ ];
+ for (let i = 0; i < methods.length; i++) {
+ kernel[methods[i]] = mockMethod;
+ }
+ return kernel;
+}
+
+function setupGraphical(kernel) {
+ const {x, y} = kernel.output;
+ if (kernel.context && kernel.context.createImageData) {
+ const data = new Uint8ClampedArray(x * y * 4);
+ kernel._imageData = kernel.context.createImageData(x, y);
+ kernel._colorData = data;
+ } else {
+ const data = new Uint8ClampedArray(x * y * 4);
+ kernel._imageData = { data };
+ kernel._colorData = data;
+ }
+}
+
+function setupOutput(output) {
+ let result = null;
+ if (output.length) {
+ if (output.length === 3) {
+ const [x,y,z] = output;
+ result = { x, y, z };
+ } else if (output.length === 2) {
+ const [x,y] = output;
+ result = { x, y };
+ } else {
+ const [x] = output;
+ result = { x };
+ }
+ } else {
+ result = output;
+ }
+ return result;
+}
+
+function gpuMock(fn, settings = {}) {
+ const output = settings.output ? setupOutput(settings.output) : null;
+ function kernel() {
+ if (kernel.output.z) {
+ return mock3D.apply(kernel, arguments);
+ } else if (kernel.output.y) {
+ if (kernel.graphical) {
+ return mock2DGraphical.apply(kernel, arguments);
+ }
+ return mock2D.apply(kernel, arguments);
+ } else {
+ return mock1D.apply(kernel, arguments);
+ }
+ }
+ kernel._fn = fn;
+ kernel.constants = settings.constants || null;
+ kernel.context = settings.context || null;
+ kernel.canvas = settings.canvas || null;
+ kernel.graphical = settings.graphical || false;
+ kernel._imageData = null;
+ kernel._colorData = null;
+ kernel.output = output;
+ kernel.thread = {
+ x: 0,
+ y: 0,
+ z: 0
+ };
+ return apiDecorate(kernel);
+}
+
+function flipPixels(pixels, width, height) {
+ const halfHeight = height / 2 | 0;
+ const bytesPerRow = width * 4;
+ const temp = new Uint8ClampedArray(width * 4);
+ const result = pixels.slice(0);
+ for (let y = 0; y < halfHeight; ++y) {
+ const topOffset = y * bytesPerRow;
+ const bottomOffset = (height - y - 1) * bytesPerRow;
+
+ temp.set(result.subarray(topOffset, topOffset + bytesPerRow));
+
+ result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow);
+
+ result.set(temp, bottomOffset);
+ }
+ return result;
+}
+
+module.exports = {
+ gpuMock
+};
+
+},{}],5:[function(require,module,exports){
+const { utils } = require('./utils');
+
+function alias(name, source) {
+ const fnString = source.toString();
+ return new Function(`return function ${ name } (${ utils.getArgumentNamesFromString(fnString).join(', ') }) {
+ ${ utils.getFunctionBodyFromString(fnString) }
+}`)();
+}
+
+module.exports = {
+ alias
+};
+},{"./utils":114}],6:[function(require,module,exports){
+const { FunctionNode } = require('../function-node');
+
+class CPUFunctionNode extends FunctionNode {
+ astFunction(ast, retArr) {
+
+ if (!this.isRootKernel) {
+ retArr.push('function');
+ retArr.push(' ');
+ retArr.push(this.name);
+ retArr.push('(');
+
+ for (let i = 0; i < this.argumentNames.length; ++i) {
+ const argumentName = this.argumentNames[i];
+
+ if (i > 0) {
+ retArr.push(', ');
+ }
+ retArr.push('user_');
+ retArr.push(argumentName);
+ }
+
+ retArr.push(') {\n');
+ }
+
+ for (let i = 0; i < ast.body.body.length; ++i) {
+ this.astGeneric(ast.body.body[i], retArr);
+ retArr.push('\n');
+ }
+
+ if (!this.isRootKernel) {
+ retArr.push('}\n');
+ }
+ return retArr;
+ }
+
+ astReturnStatement(ast, retArr) {
+ const type = this.returnType || this.getType(ast.argument);
+
+ if (!this.returnType) {
+ this.returnType = type;
+ }
+
+ if (this.isRootKernel) {
+ retArr.push(this.leadingReturnStatement);
+ this.astGeneric(ast.argument, retArr);
+ retArr.push(';\n');
+ retArr.push(this.followingReturnStatement);
+ retArr.push('continue;\n');
+ } else if (this.isSubKernel) {
+ retArr.push(`subKernelResult_${ this.name } = `);
+ this.astGeneric(ast.argument, retArr);
+ retArr.push(';');
+ retArr.push(`return subKernelResult_${ this.name };`);
+ } else {
+ retArr.push('return ');
+ this.astGeneric(ast.argument, retArr);
+ retArr.push(';');
+ }
+ return retArr;
+ }
+
+ astLiteral(ast, retArr) {
+
+ if (isNaN(ast.value)) {
+ throw this.astErrorOutput(
+ 'Non-numeric literal not supported : ' + ast.value,
+ ast
+ );
+ }
+
+ retArr.push(ast.value);
+
+ return retArr;
+ }
+
+ astBinaryExpression(ast, retArr) {
+ retArr.push('(');
+ this.astGeneric(ast.left, retArr);
+ retArr.push(ast.operator);
+ this.astGeneric(ast.right, retArr);
+ retArr.push(')');
+ return retArr;
+ }
+
+ astIdentifierExpression(idtNode, retArr) {
+ if (idtNode.type !== 'Identifier') {
+ throw this.astErrorOutput(
+ 'IdentifierExpression - not an Identifier',
+ idtNode
+ );
+ }
+
+ switch (idtNode.name) {
+ case 'Infinity':
+ retArr.push('Infinity');
+ break;
+ default:
+ if (this.constants && this.constants.hasOwnProperty(idtNode.name)) {
+ retArr.push('constants_' + idtNode.name);
+ } else {
+ retArr.push('user_' + idtNode.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) {
+ this.pushState('in-for-loop-init');
+ this.astGeneric(forNode.init, initArr);
+ for (let i = 0; i < initArr.length; i++) {
+ if (initArr[i].includes && initArr[i].includes(',')) {
+ isSafe = false;
+ }
+ }
+ this.popState('in-for-loop-init');
+ } else {
+ isSafe = false;
+ }
+
+ if (forNode.test) {
+ this.astGeneric(forNode.test, testArr);
+ } else {
+ isSafe = false;
+ }
+
+ if (forNode.update) {
+ 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) {
+ retArr.push(`for (${initArr.join('')};${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 (let ${iVariableName}=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
+ );
+ }
+
+ retArr.push('for (let i = 0; i < LOOP_MAX; i++) {');
+ retArr.push('if (');
+ this.astGeneric(whileNode.test, retArr);
+ retArr.push(') {\n');
+ this.astGeneric(whileNode.body, retArr);
+ retArr.push('} else {\n');
+ retArr.push('break;\n');
+ retArr.push('}\n');
+ retArr.push('}\n');
+
+ return retArr;
+ }
+
+ astDoWhileStatement(doWhileNode, retArr) {
+ if (doWhileNode.type !== 'DoWhileStatement') {
+ throw this.astErrorOutput(
+ 'Invalid while statement',
+ doWhileNode
+ );
+ }
+
+ retArr.push('for (let i = 0; i < LOOP_MAX; i++) {');
+ this.astGeneric(doWhileNode.body, retArr);
+ retArr.push('if (!');
+ this.astGeneric(doWhileNode.test, retArr);
+ retArr.push(') {\n');
+ retArr.push('break;\n');
+ retArr.push('}\n');
+ retArr.push('}\n');
+
+ return retArr;
+
+ }
+
+ astAssignmentExpression(assNode, retArr) {
+ const declaration = this.getDeclaration(assNode.left);
+ if (declaration && !declaration.assignable) {
+ throw this.astErrorOutput(`Variable ${assNode.left.name} is not assignable here`, assNode);
+ }
+ this.astGeneric(assNode.left, retArr);
+ retArr.push(assNode.operator);
+ this.astGeneric(assNode.right, retArr);
+ return retArr;
+ }
+
+ astBlockStatement(bNode, retArr) {
+ if (this.isState('loop-body')) {
+ this.pushState('block-body');
+ for (let i = 0; i < bNode.body.length; i++) {
+ this.astGeneric(bNode.body[i], retArr);
+ }
+ this.popState('block-body');
+ } else {
+ retArr.push('{\n');
+ for (let i = 0; i < bNode.body.length; i++) {
+ this.astGeneric(bNode.body[i], retArr);
+ }
+ retArr.push('}\n');
+ }
+ return retArr;
+ }
+
+ astVariableDeclaration(varDecNode, retArr) {
+ retArr.push(`${varDecNode.kind} `);
+ const { declarations } = varDecNode;
+ for (let i = 0; i < declarations.length; i++) {
+ if (i > 0) {
+ retArr.push(',');
+ }
+ const declaration = declarations[i];
+ const info = this.getDeclaration(declaration.id);
+ if (!info.valueType) {
+ info.valueType = this.getType(declaration.init);
+ }
+ this.astGeneric(declaration, retArr);
+ }
+ if (!this.isState('in-for-loop-init')) {
+ retArr.push(';');
+ }
+ return retArr;
+ }
+
+ astIfStatement(ifNode, retArr) {
+ retArr.push('if (');
+ this.astGeneric(ifNode.test, retArr);
+ retArr.push(')');
+ if (ifNode.consequent.type === 'BlockStatement') {
+ this.astGeneric(ifNode.consequent, retArr);
+ } else {
+ retArr.push(' {\n');
+ this.astGeneric(ifNode.consequent, retArr);
+ retArr.push('\n}\n');
+ }
+
+ if (ifNode.alternate) {
+ retArr.push('else ');
+ if (ifNode.alternate.type === 'BlockStatement' || ifNode.alternate.type === 'IfStatement') {
+ this.astGeneric(ifNode.alternate, retArr);
+ } else {
+ retArr.push(' {\n');
+ this.astGeneric(ifNode.alternate, retArr);
+ retArr.push('\n}\n');
+ }
+ }
+ return retArr;
+
+ }
+
+ astSwitchStatement(ast, retArr) {
+ const { discriminant, cases } = ast;
+ retArr.push('switch (');
+ this.astGeneric(discriminant, retArr);
+ retArr.push(') {\n');
+ for (let i = 0; i < cases.length; i++) {
+ if (cases[i].test === null) {
+ retArr.push('default:\n');
+ this.astGeneric(cases[i].consequent, retArr);
+ if (cases[i].consequent && cases[i].consequent.length > 0) {
+ retArr.push('break;\n');
+ }
+ continue;
+ }
+ retArr.push('case ');
+ this.astGeneric(cases[i].test, retArr);
+ retArr.push(':\n');
+ if (cases[i].consequent && cases[i].consequent.length > 0) {
+ this.astGeneric(cases[i].consequent, retArr);
+ retArr.push('break;\n');
+ }
+ }
+ retArr.push('\n}');
+ }
+
+ astThisExpression(tNode, retArr) {
+ retArr.push('_this');
+ return retArr;
+ }
+
+ astMemberExpression(mNode, retArr) {
+ const {
+ signature,
+ type,
+ property,
+ xProperty,
+ yProperty,
+ zProperty,
+ name,
+ origin
+ } = this.getMemberExpressionDetails(mNode);
+ switch (signature) {
+ case 'this.thread.value':
+ retArr.push(`_this.thread.${ name }`);
+ return retArr;
+ case 'this.output.value':
+ switch (name) {
+ case 'x':
+ retArr.push('outputX');
+ break;
+ case 'y':
+ retArr.push('outputY');
+ break;
+ case 'z':
+ retArr.push('outputZ');
+ break;
+ default:
+ throw this.astErrorOutput('Unexpected expression', mNode);
+ }
+ return retArr;
+ case 'value':
+ throw this.astErrorOutput('Unexpected expression', mNode);
+ case 'value[]':
+ case 'value[][]':
+ case 'value[][][]':
+ case 'value.value':
+ if (origin === 'Math') {
+ retArr.push(Math[name]);
+ return retArr;
+ }
+ switch (property) {
+ case 'r':
+ retArr.push(`user_${ name }[0]`);
+ return retArr;
+ case 'g':
+ retArr.push(`user_${ name }[1]`);
+ return retArr;
+ case 'b':
+ retArr.push(`user_${ name }[2]`);
+ return retArr;
+ case 'a':
+ retArr.push(`user_${ name }[3]`);
+ return retArr;
+ }
+ break;
+ case 'this.constants.value':
+ case 'this.constants.value[]':
+ case 'this.constants.value[][]':
+ case 'this.constants.value[][][]':
+ break;
+ case 'fn()[]':
+ this.astGeneric(mNode.object, retArr);
+ retArr.push('[');
+ this.astGeneric(mNode.property, retArr);
+ retArr.push(']');
+ return retArr;
+ case 'fn()[][]':
+ this.astGeneric(mNode.object.object, retArr);
+ retArr.push('[');
+ this.astGeneric(mNode.object.property, retArr);
+ retArr.push(']');
+ retArr.push('[');
+ this.astGeneric(mNode.property, retArr);
+ retArr.push(']');
+ return retArr;
+ default:
+ throw this.astErrorOutput('Unexpected expression', mNode);
+ }
+
+ if (!mNode.computed) {
+ switch (type) {
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ case 'Boolean':
+ retArr.push(`${origin}_${name}`);
+ return retArr;
+ }
+ }
+
+ const markupName = `${origin}_${name}`;
+
+ switch (type) {
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ case 'Matrix(2)':
+ case 'Matrix(3)':
+ case 'Matrix(4)':
+ case 'HTMLImageArray':
+ case 'ArrayTexture(1)':
+ case 'ArrayTexture(2)':
+ case 'ArrayTexture(3)':
+ case 'ArrayTexture(4)':
+ case 'HTMLImage':
+ default:
+ let size;
+ let isInput;
+ if (origin === 'constants') {
+ const constant = this.constants[name];
+ isInput = this.constantTypes[name] === 'Input';
+ size = isInput ? constant.size : null;
+ } else {
+ isInput = this.isInput(name);
+ size = isInput ? this.argumentSizes[this.argumentNames.indexOf(name)] : null;
+ }
+ retArr.push(`${ markupName }`);
+ if (zProperty && yProperty) {
+ if (isInput) {
+ retArr.push('[(');
+ this.astGeneric(zProperty, retArr);
+ retArr.push(`*${ this.dynamicArguments ? '(outputY * outputX)' : size[1] * size[0] })+(`);
+ this.astGeneric(yProperty, retArr);
+ retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`);
+ this.astGeneric(xProperty, retArr);
+ retArr.push(']');
+ } else {
+ retArr.push('[');
+ this.astGeneric(zProperty, retArr);
+ retArr.push(']');
+ retArr.push('[');
+ this.astGeneric(yProperty, retArr);
+ retArr.push(']');
+ retArr.push('[');
+ this.astGeneric(xProperty, retArr);
+ retArr.push(']');
+ }
+ } else if (yProperty) {
+ if (isInput) {
+ retArr.push('[(');
+ this.astGeneric(yProperty, retArr);
+ retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`);
+ this.astGeneric(xProperty, retArr);
+ retArr.push(']');
+ } else {
+ retArr.push('[');
+ this.astGeneric(yProperty, retArr);
+ retArr.push(']');
+ retArr.push('[');
+ this.astGeneric(xProperty, retArr);
+ retArr.push(']');
+ }
+ } else if (typeof xProperty !== 'undefined') {
+ retArr.push('[');
+ this.astGeneric(xProperty, retArr);
+ retArr.push(']');
+ }
+ }
+ return retArr;
+ }
+
+ astCallExpression(ast, retArr) {
+ if (ast.type !== 'CallExpression') {
+ throw this.astErrorOutput('Unknown CallExpression', ast);
+ }
+ let functionName = this.astMemberExpressionUnroll(ast.callee);
+
+ if (this.calledFunctions.indexOf(functionName) < 0) {
+ this.calledFunctions.push(functionName);
+ }
+
+ const isMathFunction = this.isAstMathFunction(ast);
+
+ if (this.onFunctionCall) {
+ this.onFunctionCall(this.name, functionName, ast.arguments);
+ }
+
+ retArr.push(functionName);
+
+ retArr.push('(');
+ const targetTypes = this.lookupFunctionArgumentTypes(functionName) || [];
+ for (let i = 0; i < ast.arguments.length; ++i) {
+ const argument = ast.arguments[i];
+
+ let argumentType = this.getType(argument);
+ if (!targetTypes[i]) {
+ this.triggerImplyArgumentType(functionName, i, argumentType, this);
+ }
+
+ if (i > 0) {
+ retArr.push(', ');
+ }
+ this.astGeneric(argument, retArr);
+ }
+ retArr.push(')');
+
+ return retArr;
+ }
+
+ astArrayExpression(arrNode, retArr) {
+ const returnType = this.getType(arrNode);
+ const arrLen = arrNode.elements.length;
+ const elements = [];
+ for (let i = 0; i < arrLen; ++i) {
+ const element = [];
+ this.astGeneric(arrNode.elements[i], element);
+ elements.push(element.join(''));
+ }
+ switch (returnType) {
+ case 'Matrix(2)':
+ case 'Matrix(3)':
+ case 'Matrix(4)':
+ retArr.push(`[${elements.join(', ')}]`);
+ break;
+ default:
+ retArr.push(`new Float32Array([${elements.join(', ')}])`);
+ }
+ return retArr;
+ }
+
+ astDebuggerStatement(arrNode, retArr) {
+ retArr.push('debugger;');
+ return retArr;
+ }
+}
+
+module.exports = {
+ CPUFunctionNode
+};
+},{"../function-node":10}],7:[function(require,module,exports){
+const { utils } = require('../../utils');
+
+function constantsToString(constants, types) {
+ const results = [];
+ for (const name in types) {
+ if (!types.hasOwnProperty(name)) continue;
+ const type = types[name];
+ const constant = constants[name];
+ switch (type) {
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ case 'Boolean':
+ results.push(`${name}:${constant}`);
+ break;
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ case 'Matrix(2)':
+ case 'Matrix(3)':
+ case 'Matrix(4)':
+ results.push(`${name}:new ${constant.constructor.name}(${JSON.stringify(Array.from(constant))})`);
+ break;
+ }
+ }
+ return `{ ${ results.join() } }`;
+}
+
+function cpuKernelString(cpuKernel, name) {
+ const header = [];
+ const thisProperties = [];
+ const beforeReturn = [];
+
+ const useFunctionKeyword = !/^function/.test(cpuKernel.color.toString());
+
+ header.push(
+ ' const { context, canvas, constants: incomingConstants } = settings;',
+ ` const output = new Int32Array(${JSON.stringify(Array.from(cpuKernel.output))});`,
+ ` const _constantTypes = ${JSON.stringify(cpuKernel.constantTypes)};`,
+ ` const _constants = ${constantsToString(cpuKernel.constants, cpuKernel.constantTypes)};`
+ );
+
+ thisProperties.push(
+ ' constants: _constants,',
+ ' context,',
+ ' output,',
+ ' thread: {x: 0, y: 0, z: 0},'
+ );
+
+ if (cpuKernel.graphical) {
+ header.push(` const _imageData = context.createImageData(${cpuKernel.output[0]}, ${cpuKernel.output[1]});`);
+ header.push(` const _colorData = new Uint8ClampedArray(${cpuKernel.output[0]} * ${cpuKernel.output[1]} * 4);`);
+
+ const colorFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.color.toString(), {
+ thisLookup: (propertyName) => {
+ switch (propertyName) {
+ case '_colorData':
+ return '_colorData';
+ case '_imageData':
+ return '_imageData';
+ case 'output':
+ return 'output';
+ case 'thread':
+ return 'this.thread';
+ }
+ return JSON.stringify(cpuKernel[propertyName]);
+ },
+ findDependency: (object, name) => {
+ return null;
+ }
+ });
+
+ const getPixelsFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.getPixels.toString(), {
+ thisLookup: (propertyName) => {
+ switch (propertyName) {
+ case '_colorData':
+ return '_colorData';
+ case '_imageData':
+ return '_imageData';
+ case 'output':
+ return 'output';
+ case 'thread':
+ return 'this.thread';
+ }
+ return JSON.stringify(cpuKernel[propertyName]);
+ },
+ findDependency: () => {
+ return null;
+ }
+ });
+
+ thisProperties.push(
+ ' _imageData,',
+ ' _colorData,',
+ ` color: ${colorFn},`
+ );
+
+ beforeReturn.push(
+ ` kernel.getPixels = ${getPixelsFn};`
+ );
+ }
+
+ const constantTypes = [];
+ const constantKeys = Object.keys(cpuKernel.constantTypes);
+ for (let i = 0; i < constantKeys.length; i++) {
+ constantTypes.push(cpuKernel.constantTypes[constantKeys]);
+ }
+ if (cpuKernel.argumentTypes.indexOf('HTMLImageArray') !== -1 || constantTypes.indexOf('HTMLImageArray') !== -1) {
+ const flattenedImageTo3DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._imageTo3DArray.toString(), {
+ doNotDefine: ['canvas'],
+ findDependency: (object, name) => {
+ if (object === 'this') {
+ return (useFunctionKeyword ? 'function ' : '') + cpuKernel[name].toString();
+ }
+ return null;
+ },
+ thisLookup: (propertyName) => {
+ switch (propertyName) {
+ case 'canvas':
+ return;
+ case 'context':
+ return 'context';
+ }
+ }
+ });
+ beforeReturn.push(flattenedImageTo3DArray);
+ thisProperties.push(` _mediaTo2DArray,`);
+ thisProperties.push(` _imageTo3DArray,`);
+ } else if (cpuKernel.argumentTypes.indexOf('HTMLImage') !== -1 || constantTypes.indexOf('HTMLImage') !== -1) {
+ const flattenedImageTo2DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._mediaTo2DArray.toString(), {
+ findDependency: (object, name) => {
+ return null;
+ },
+ thisLookup: (propertyName) => {
+ switch (propertyName) {
+ case 'canvas':
+ return 'settings.canvas';
+ case 'context':
+ return 'settings.context';
+ }
+ throw new Error('unhandled thisLookup');
+ }
+ });
+ beforeReturn.push(flattenedImageTo2DArray);
+ thisProperties.push(` _mediaTo2DArray,`);
+ }
+
+ return `function(settings) {
+${ header.join('\n') }
+ for (const p in _constantTypes) {
+ if (!_constantTypes.hasOwnProperty(p)) continue;
+ const type = _constantTypes[p];
+ switch (type) {
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ case 'Boolean':
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ case 'Matrix(2)':
+ case 'Matrix(3)':
+ case 'Matrix(4)':
+ if (incomingConstants.hasOwnProperty(p)) {
+ console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned');
+ }
+ continue;
+ }
+ if (!incomingConstants.hasOwnProperty(p)) {
+ throw new Error('constant ' + p + ' not found');
+ }
+ _constants[p] = incomingConstants[p];
+ }
+ const kernel = (function() {
+${cpuKernel._kernelString}
+ })
+ .apply({ ${thisProperties.join('\n')} });
+ ${ beforeReturn.join('\n') }
+ return kernel;
+}`;
+}
+
+module.exports = {
+ cpuKernelString
+};
+},{"../../utils":114}],8:[function(require,module,exports){
+const { Kernel } = require('../kernel');
+const { FunctionBuilder } = require('../function-builder');
+const { CPUFunctionNode } = require('./function-node');
+const { utils } = require('../../utils');
+const { cpuKernelString } = require('./kernel-string');
+
+class CPUKernel extends Kernel {
+ static getFeatures() {
+ return this.features;
+ }
+ static get features() {
+ return Object.freeze({
+ kernelMap: true,
+ isIntegerDivisionAccurate: true
+ });
+ }
+ static get isSupported() {
+ return true;
+ }
+ static isContextMatch(context) {
+ return false;
+ }
+ 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(combinedKernel) {
+ return combinedKernel;
+ }
+
+ static getSignature(kernel, argumentTypes) {
+ return 'cpu' + (argumentTypes.length > 0 ? ':' + argumentTypes.join(',') : '');
+ }
+
+ constructor(source, settings) {
+ super(source, settings);
+ this.mergeSettings(source.settings || settings);
+
+ this._imageData = null;
+ this._colorData = null;
+ this._kernelString = null;
+ this._prependedString = [];
+ this.thread = {
+ x: 0,
+ y: 0,
+ z: 0
+ };
+ this.translatedSources = null;
+ }
+
+ initCanvas() {
+ if (typeof document !== 'undefined') {
+ return document.createElement('canvas');
+ } else if (typeof OffscreenCanvas !== 'undefined') {
+ return new OffscreenCanvas(0, 0);
+ }
+ }
+
+ initContext() {
+ if (!this.canvas) return null;
+ return this.canvas.getContext('2d');
+ }
+
+ initPlugins(settings) {
+ return [];
+ }
+
+ validateSettings(args) {
+ 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 = utils.getDimensions(argType);
+ } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') {
+ this.output = args[0].output;
+ } else {
+ throw new Error('Auto output not supported for input type: ' + argType);
+ }
+ }
+
+ if (this.graphical) {
+ if (this.output.length !== 2) {
+ throw new Error('Output must have 2 dimensions on graphical mode');
+ }
+ }
+
+ this.checkOutput();
+ }
+
+ translateSource() {
+ this.leadingReturnStatement = this.output.length > 1 ? 'resultX[x] = ' : 'result[x] = ';
+ if (this.subKernels) {
+ const followingReturnStatement = [];
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const {
+ name
+ } = this.subKernels[i];
+ followingReturnStatement.push(this.output.length > 1 ? `resultX_${ name }[x] = subKernelResult_${ name };\n` : `result_${ name }[x] = subKernelResult_${ name };\n`);
+ }
+ this.followingReturnStatement = followingReturnStatement.join('');
+ }
+ const functionBuilder = FunctionBuilder.fromKernel(this, CPUFunctionNode);
+ this.translatedSources = functionBuilder.getPrototypes('kernel');
+ if (!this.graphical && !this.returnType) {
+ this.returnType = functionBuilder.getKernelResultType();
+ }
+ }
+
+ build() {
+ if (this.built) return;
+ this.setupConstants();
+ this.setupArguments(arguments);
+ this.validateSettings(arguments);
+ this.translateSource();
+
+ if (this.graphical) {
+ const {
+ canvas,
+ output
+ } = this;
+ if (!canvas) {
+ throw new Error('no canvas available for using graphical output');
+ }
+ const width = output[0];
+ const height = output[1] || 1;
+ canvas.width = width;
+ canvas.height = height;
+ this._imageData = this.context.createImageData(width, height);
+ this._colorData = new Uint8ClampedArray(width * height * 4);
+ }
+
+ const kernelString = this.getKernelString();
+ this.kernelString = kernelString;
+
+ if (this.debug) {
+ console.log('Function output:');
+ console.log(kernelString);
+ }
+
+ try {
+ this.run = new Function([], kernelString).bind(this)();
+ } catch (e) {
+ console.error('An error occurred compiling the javascript: ', e);
+ }
+ this.buildSignature(arguments);
+ this.built = true;
+ }
+
+ color(r, g, b, a) {
+ if (typeof a === 'undefined') {
+ a = 1;
+ }
+
+ r = Math.floor(r * 255);
+ g = Math.floor(g * 255);
+ b = Math.floor(b * 255);
+ a = Math.floor(a * 255);
+
+ const width = this.output[0];
+ const height = this.output[1];
+
+ const x = this.thread.x;
+ const y = height - this.thread.y - 1;
+
+ const index = x + y * width;
+
+ this._colorData[index * 4 + 0] = r;
+ this._colorData[index * 4 + 1] = g;
+ this._colorData[index * 4 + 2] = b;
+ this._colorData[index * 4 + 3] = a;
+ }
+
+ getKernelString() {
+ if (this._kernelString !== null) return this._kernelString;
+
+ let kernelThreadString = null;
+ let {
+ translatedSources
+ } = this;
+ if (translatedSources.length > 1) {
+ translatedSources = translatedSources.filter(fn => {
+ if (/^function/.test(fn)) return fn;
+ kernelThreadString = fn;
+ return false;
+ });
+ } else {
+ kernelThreadString = translatedSources.shift();
+ }
+ return this._kernelString = ` const LOOP_MAX = ${ this._getLoopMaxString() };
+ ${ this.injectedNative || '' }
+ const _this = this;
+ ${ this._resultKernelHeader() }
+ ${ this._processConstants() }
+ return (${ this.argumentNames.map(argumentName => 'user_' + argumentName).join(', ') }) => {
+ ${ this._prependedString.join('') }
+ ${ this._earlyThrows() }
+ ${ this._processArguments() }
+ ${ this.graphical ? this._graphicalKernelBody(kernelThreadString) : this._resultKernelBody(kernelThreadString) }
+ ${ translatedSources.length > 0 ? translatedSources.join('\n') : '' }
+ };`;
+ }
+
+ toString() {
+ return cpuKernelString(this);
+ }
+
+ _getLoopMaxString() {
+ return (
+ this.loopMaxIterations ?
+ ` ${ parseInt(this.loopMaxIterations) };` :
+ ' 1000;'
+ );
+ }
+
+ _processConstants() {
+ if (!this.constants) return '';
+
+ const result = [];
+ for (let p in this.constants) {
+ const type = this.constantTypes[p];
+ switch (type) {
+ case 'HTMLCanvas':
+ case 'OffscreenCanvas':
+ case 'HTMLImage':
+ case 'ImageBitmap':
+ case 'ImageData':
+ case 'HTMLVideo':
+ result.push(` const constants_${p} = this._mediaTo2DArray(this.constants.${p});\n`);
+ break;
+ case 'HTMLImageArray':
+ result.push(` const constants_${p} = this._imageTo3DArray(this.constants.${p});\n`);
+ break;
+ case 'Input':
+ result.push(` const constants_${p} = this.constants.${p}.value;\n`);
+ break;
+ default:
+ result.push(` const constants_${p} = this.constants.${p};\n`);
+ }
+ }
+ return result.join('');
+ }
+
+ _earlyThrows() {
+ if (this.graphical) return '';
+ if (this.immutable) return '';
+ if (!this.pipeline) return '';
+ const arrayArguments = [];
+ for (let i = 0; i < this.argumentTypes.length; i++) {
+ if (this.argumentTypes[i] === 'Array') {
+ arrayArguments.push(this.argumentNames[i]);
+ }
+ }
+ if (arrayArguments.length === 0) return '';
+ const checks = [];
+ for (let i = 0; i < arrayArguments.length; i++) {
+ const argumentName = arrayArguments[i];
+ const checkSubKernels = this._mapSubKernels(subKernel => `user_${argumentName} === result_${subKernel.name}`).join(' || ');
+ checks.push(`user_${argumentName} === result${checkSubKernels ? ` || ${checkSubKernels}` : ''}`);
+ }
+ return `if (${checks.join(' || ')}) throw new Error('Source and destination arrays are the same. Use immutable = true');`;
+ }
+
+ _processArguments() {
+ const result = [];
+ for (let i = 0; i < this.argumentTypes.length; i++) {
+ const variableName = `user_${this.argumentNames[i]}`;
+ switch (this.argumentTypes[i]) {
+ case 'HTMLCanvas':
+ case 'OffscreenCanvas':
+ case 'HTMLImage':
+ case 'ImageBitmap':
+ case 'ImageData':
+ case 'HTMLVideo':
+ result.push(` ${variableName} = this._mediaTo2DArray(${variableName});\n`);
+ break;
+ case 'HTMLImageArray':
+ result.push(` ${variableName} = this._imageTo3DArray(${variableName});\n`);
+ break;
+ case 'Input':
+ result.push(` ${variableName} = ${variableName}.value;\n`);
+ break;
+ case 'ArrayTexture(1)':
+ case 'ArrayTexture(2)':
+ case 'ArrayTexture(3)':
+ case 'ArrayTexture(4)':
+ case 'NumberTexture':
+ case 'MemoryOptimizedNumberTexture':
+ result.push(`
+ if (${variableName}.toArray) {
+ if (!_this.textureCache) {
+ _this.textureCache = [];
+ _this.arrayCache = [];
+ }
+ const textureIndex = _this.textureCache.indexOf(${variableName});
+ if (textureIndex !== -1) {
+ ${variableName} = _this.arrayCache[textureIndex];
+ } else {
+ _this.textureCache.push(${variableName});
+ ${variableName} = ${variableName}.toArray();
+ _this.arrayCache.push(${variableName});
+ }
+ }`);
+ break;
+ }
+ }
+ return result.join('');
+ }
+
+ _mediaTo2DArray(media) {
+ const canvas = this.canvas;
+ const width = media.width > 0 ? media.width : media.videoWidth;
+ const height = media.height > 0 ? media.height : media.videoHeight;
+ if (canvas.width < width) {
+ canvas.width = width;
+ }
+ if (canvas.height < height) {
+ canvas.height = height;
+ }
+ const ctx = this.context;
+ let pixelsData;
+ if (media.constructor === ImageData) {
+ pixelsData = media.data;
+ } else {
+ ctx.drawImage(media, 0, 0, width, height);
+ pixelsData = ctx.getImageData(0, 0, width, height).data;
+ }
+ const imageArray = new Array(height);
+ let index = 0;
+ for (let y = height - 1; y >= 0; y--) {
+ const row = imageArray[y] = new Array(width);
+ for (let x = 0; x < width; x++) {
+ const pixel = new Float32Array(4);
+ pixel[0] = pixelsData[index++] / 255;
+ pixel[1] = pixelsData[index++] / 255;
+ pixel[2] = pixelsData[index++] / 255;
+ pixel[3] = pixelsData[index++] / 255;
+ row[x] = pixel;
+ }
+ }
+ return imageArray;
+ }
+
+ getPixels(flip) {
+ const [width, height] = this.output;
+ return flip ? utils.flipPixels(this._imageData.data, width, height) : this._imageData.data.slice(0);
+ }
+
+ _imageTo3DArray(images) {
+ const imagesArray = new Array(images.length);
+ for (let i = 0; i < images.length; i++) {
+ imagesArray[i] = this._mediaTo2DArray(images[i]);
+ }
+ return imagesArray;
+ }
+
+ _resultKernelHeader() {
+ if (this.graphical) return '';
+ if (this.immutable) return '';
+ if (!this.pipeline) return '';
+ switch (this.output.length) {
+ case 1:
+ return this._mutableKernel1DResults();
+ case 2:
+ return this._mutableKernel2DResults();
+ case 3:
+ return this._mutableKernel3DResults();
+ }
+ }
+
+ _resultKernelBody(kernelString) {
+ switch (this.output.length) {
+ case 1:
+ return (!this.immutable && this.pipeline ? this._resultMutableKernel1DLoop(kernelString) : this._resultImmutableKernel1DLoop(kernelString)) + this._kernelOutput();
+ case 2:
+ return (!this.immutable && this.pipeline ? this._resultMutableKernel2DLoop(kernelString) : this._resultImmutableKernel2DLoop(kernelString)) + this._kernelOutput();
+ case 3:
+ return (!this.immutable && this.pipeline ? this._resultMutableKernel3DLoop(kernelString) : this._resultImmutableKernel3DLoop(kernelString)) + this._kernelOutput();
+ default:
+ throw new Error('unsupported size kernel');
+ }
+ }
+
+ _graphicalKernelBody(kernelThreadString) {
+ switch (this.output.length) {
+ case 2:
+ return this._graphicalKernel2DLoop(kernelThreadString) + this._graphicalOutput();
+ default:
+ throw new Error('unsupported size kernel');
+ }
+ }
+
+ _graphicalOutput() {
+ return `
+ this._imageData.data.set(this._colorData);
+ this.context.putImageData(this._imageData, 0, 0);
+ return;`
+ }
+
+ _getKernelResultTypeConstructorString() {
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ return 'Float32Array';
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ return 'Array';
+ default:
+ if (this.graphical) {
+ return 'Float32Array';
+ }
+ throw new Error(`unhandled returnType ${ this.returnType }`);
+ }
+ }
+
+ _resultImmutableKernel1DLoop(kernelString) {
+ const constructorString = this._getKernelResultTypeConstructorString();
+ return ` const outputX = _this.output[0];
+ const result = new ${constructorString}(outputX);
+ ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new ${constructorString}(outputX);\n`).join(' ') }
+ ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') }
+ for (let x = 0; x < outputX; x++) {
+ this.thread.x = x;
+ this.thread.y = 0;
+ this.thread.z = 0;
+ ${ kernelString }
+ }`;
+ }
+
+ _mutableKernel1DResults() {
+ const constructorString = this._getKernelResultTypeConstructorString();
+ return ` const outputX = _this.output[0];
+ const result = new ${constructorString}(outputX);
+ ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new ${constructorString}(outputX);\n`).join(' ') }
+ ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') }`;
+ }
+
+ _resultMutableKernel1DLoop(kernelString) {
+ return ` const outputX = _this.output[0];
+ for (let x = 0; x < outputX; x++) {
+ this.thread.x = x;
+ this.thread.y = 0;
+ this.thread.z = 0;
+ ${ kernelString }
+ }`;
+ }
+
+ _resultImmutableKernel2DLoop(kernelString) {
+ const constructorString = this._getKernelResultTypeConstructorString();
+ return ` const outputX = _this.output[0];
+ const outputY = _this.output[1];
+ const result = new Array(outputY);
+ ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\n`).join(' ') }
+ ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') }
+ for (let y = 0; y < outputY; y++) {
+ this.thread.z = 0;
+ this.thread.y = y;
+ const resultX = result[y] = new ${constructorString}(outputX);
+ ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join('') }
+ for (let x = 0; x < outputX; x++) {
+ this.thread.x = x;
+ ${ kernelString }
+ }
+ }`;
+ }
+
+ _mutableKernel2DResults() {
+ const constructorString = this._getKernelResultTypeConstructorString();
+ return ` const outputX = _this.output[0];
+ const outputY = _this.output[1];
+ const result = new Array(outputY);
+ ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\n`).join(' ') }
+ ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') }
+ for (let y = 0; y < outputY; y++) {
+ const resultX = result[y] = new ${constructorString}(outputX);
+ ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join('') }
+ }`;
+ }
+
+ _resultMutableKernel2DLoop(kernelString) {
+ const constructorString = this._getKernelResultTypeConstructorString();
+ return ` const outputX = _this.output[0];
+ const outputY = _this.output[1];
+ for (let y = 0; y < outputY; y++) {
+ this.thread.z = 0;
+ this.thread.y = y;
+ const resultX = result[y];
+ ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join('') }
+ for (let x = 0; x < outputX; x++) {
+ this.thread.x = x;
+ ${ kernelString }
+ }
+ }`;
+ }
+
+ _graphicalKernel2DLoop(kernelString) {
+ return ` const outputX = _this.output[0];
+ const outputY = _this.output[1];
+ for (let y = 0; y < outputY; y++) {
+ this.thread.z = 0;
+ this.thread.y = y;
+ for (let x = 0; x < outputX; x++) {
+ this.thread.x = x;
+ ${ kernelString }
+ }
+ }`;
+ }
+
+ _resultImmutableKernel3DLoop(kernelString) {
+ const constructorString = this._getKernelResultTypeConstructorString();
+ return ` const outputX = _this.output[0];
+ const outputY = _this.output[1];
+ const outputZ = _this.output[2];
+ const result = new Array(outputZ);
+ ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputZ);\n`).join(' ') }
+ ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') }
+ for (let z = 0; z < outputZ; z++) {
+ this.thread.z = z;
+ const resultY = result[z] = new Array(outputY);
+ ${ this._mapSubKernels(subKernel => `const resultY_${ subKernel.name } = result_${subKernel.name}[z] = new Array(outputY);\n`).join(' ') }
+ for (let y = 0; y < outputY; y++) {
+ this.thread.y = y;
+ const resultX = resultY[y] = new ${constructorString}(outputX);
+ ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = resultY_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join(' ') }
+ for (let x = 0; x < outputX; x++) {
+ this.thread.x = x;
+ ${ kernelString }
+ }
+ }
+ }`;
+ }
+
+ _mutableKernel3DResults() {
+ const constructorString = this._getKernelResultTypeConstructorString();
+ return ` const outputX = _this.output[0];
+ const outputY = _this.output[1];
+ const outputZ = _this.output[2];
+ const result = new Array(outputZ);
+ ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputZ);\n`).join(' ') }
+ ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') }
+ for (let z = 0; z < outputZ; z++) {
+ const resultY = result[z] = new Array(outputY);
+ ${ this._mapSubKernels(subKernel => `const resultY_${ subKernel.name } = result_${subKernel.name}[z] = new Array(outputY);\n`).join(' ') }
+ for (let y = 0; y < outputY; y++) {
+ const resultX = resultY[y] = new ${constructorString}(outputX);
+ ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = resultY_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join(' ') }
+ }
+ }`;
+ }
+
+ _resultMutableKernel3DLoop(kernelString) {
+ return ` const outputX = _this.output[0];
+ const outputY = _this.output[1];
+ const outputZ = _this.output[2];
+ for (let z = 0; z < outputZ; z++) {
+ this.thread.z = z;
+ const resultY = result[z];
+ for (let y = 0; y < outputY; y++) {
+ this.thread.y = y;
+ const resultX = resultY[y];
+ for (let x = 0; x < outputX; x++) {
+ this.thread.x = x;
+ ${ kernelString }
+ }
+ }
+ }`;
+ }
+
+ _kernelOutput() {
+ if (!this.subKernels) {
+ return '\n return result;';
+ }
+ return `\n return {
+ result: result,
+ ${ this.subKernels.map(subKernel => `${ subKernel.property }: result_${ subKernel.name }`).join(',\n ') }
+ };`;
+ }
+
+ _mapSubKernels(fn) {
+ return this.subKernels === null ? [''] :
+ this.subKernels.map(fn);
+ }
+
+ destroy(removeCanvasReference) {
+ if (removeCanvasReference) {
+ delete this.canvas;
+ }
+ }
+
+ static destroyContext(context) {}
+
+ toJSON() {
+ const json = super.toJSON();
+ json.functionNodes = FunctionBuilder.fromKernel(this, CPUFunctionNode).toJSON();
+ return json;
+ }
+
+ setOutput(output) {
+ super.setOutput(output);
+ const [width, height] = this.output;
+ if (this.graphical) {
+ this._imageData = this.context.createImageData(width, height);
+ this._colorData = new Uint8ClampedArray(width * height * 4);
+ }
+ }
+
+ prependString(value) {
+ if (this._kernelString) throw new Error('Kernel already built');
+ this._prependedString.push(value);
+ }
+
+ hasPrependString(value) {
+ return this._prependedString.indexOf(value) > -1;
+ }
+}
+
+module.exports = {
+ CPUKernel
+};
+},{"../../utils":114,"../function-builder":9,"../kernel":36,"./function-node":6,"./kernel-string":7}],9:[function(require,module,exports){
+class FunctionBuilder {
+ static fromKernel(kernel, FunctionNode, extraNodeOptions) {
+ const {
+ kernelArguments,
+ kernelConstants,
+ argumentNames,
+ argumentSizes,
+ argumentBitRatios,
+ constants,
+ constantBitRatios,
+ debug,
+ loopMaxIterations,
+ nativeFunctions,
+ output,
+ optimizeFloatMemory,
+ precision,
+ plugins,
+ source,
+ subKernels,
+ functions,
+ leadingReturnStatement,
+ followingReturnStatement,
+ dynamicArguments,
+ dynamicOutput,
+ } = kernel;
+
+ const argumentTypes = new Array(kernelArguments.length);
+ const constantTypes = {};
+
+ for (let i = 0; i < kernelArguments.length; i++) {
+ argumentTypes[i] = kernelArguments[i].type;
+ }
+
+ for (let i = 0; i < kernelConstants.length; i++) {
+ const kernelConstant = kernelConstants[i];
+ constantTypes[kernelConstant.name] = kernelConstant.type;
+ }
+
+ const needsArgumentType = (functionName, index) => {
+ return functionBuilder.needsArgumentType(functionName, index);
+ };
+
+ const assignArgumentType = (functionName, index, type) => {
+ functionBuilder.assignArgumentType(functionName, index, type);
+ };
+
+ const lookupReturnType = (functionName, ast, requestingNode) => {
+ return functionBuilder.lookupReturnType(functionName, ast, requestingNode);
+ };
+
+ const lookupFunctionArgumentTypes = (functionName) => {
+ return functionBuilder.lookupFunctionArgumentTypes(functionName);
+ };
+
+ const lookupFunctionArgumentName = (functionName, argumentIndex) => {
+ return functionBuilder.lookupFunctionArgumentName(functionName, argumentIndex);
+ };
+
+ const lookupFunctionArgumentBitRatio = (functionName, argumentName) => {
+ return functionBuilder.lookupFunctionArgumentBitRatio(functionName, argumentName);
+ };
+
+ const triggerImplyArgumentType = (functionName, i, argumentType, requestingNode) => {
+ functionBuilder.assignArgumentType(functionName, i, argumentType, requestingNode);
+ };
+
+ const triggerImplyArgumentBitRatio = (functionName, argumentName, calleeFunctionName, argumentIndex) => {
+ functionBuilder.assignArgumentBitRatio(functionName, argumentName, calleeFunctionName, argumentIndex);
+ };
+
+ const onFunctionCall = (functionName, calleeFunctionName, args) => {
+ functionBuilder.trackFunctionCall(functionName, calleeFunctionName, args);
+ };
+
+ const onNestedFunction = (ast, source) => {
+ const argumentNames = [];
+ for (let i = 0; i < ast.params.length; i++) {
+ argumentNames.push(ast.params[i].name);
+ }
+ const nestedFunction = new FunctionNode(source, Object.assign({}, nodeOptions, {
+ returnType: null,
+ ast,
+ name: ast.id.name,
+ argumentNames,
+ lookupReturnType,
+ lookupFunctionArgumentTypes,
+ lookupFunctionArgumentName,
+ lookupFunctionArgumentBitRatio,
+ needsArgumentType,
+ assignArgumentType,
+ triggerImplyArgumentType,
+ triggerImplyArgumentBitRatio,
+ onFunctionCall,
+ }));
+ nestedFunction.traceFunctionAST(ast);
+ functionBuilder.addFunctionNode(nestedFunction);
+ };
+
+ const nodeOptions = Object.assign({
+ isRootKernel: false,
+ onNestedFunction,
+ lookupReturnType,
+ lookupFunctionArgumentTypes,
+ lookupFunctionArgumentName,
+ lookupFunctionArgumentBitRatio,
+ needsArgumentType,
+ assignArgumentType,
+ triggerImplyArgumentType,
+ triggerImplyArgumentBitRatio,
+ onFunctionCall,
+ optimizeFloatMemory,
+ precision,
+ constants,
+ constantTypes,
+ constantBitRatios,
+ debug,
+ loopMaxIterations,
+ output,
+ plugins,
+ dynamicArguments,
+ dynamicOutput,
+ }, extraNodeOptions || {});
+
+ const rootNodeOptions = Object.assign({}, nodeOptions, {
+ isRootKernel: true,
+ name: 'kernel',
+ argumentNames,
+ argumentTypes,
+ argumentSizes,
+ argumentBitRatios,
+ leadingReturnStatement,
+ followingReturnStatement,
+ });
+
+ if (typeof source === 'object' && source.functionNodes) {
+ return new FunctionBuilder().fromJSON(source.functionNodes, FunctionNode);
+ }
+
+ const rootNode = new FunctionNode(source, rootNodeOptions);
+
+ let functionNodes = null;
+ if (functions) {
+ functionNodes = functions.map((fn) => new FunctionNode(fn.source, {
+ returnType: fn.returnType,
+ argumentTypes: fn.argumentTypes,
+ output,
+ plugins,
+ constants,
+ constantTypes,
+ constantBitRatios,
+ optimizeFloatMemory,
+ precision,
+ lookupReturnType,
+ lookupFunctionArgumentTypes,
+ lookupFunctionArgumentName,
+ lookupFunctionArgumentBitRatio,
+ needsArgumentType,
+ assignArgumentType,
+ triggerImplyArgumentType,
+ triggerImplyArgumentBitRatio,
+ onFunctionCall,
+ onNestedFunction,
+ }));
+ }
+
+ let subKernelNodes = null;
+ if (subKernels) {
+ subKernelNodes = subKernels.map((subKernel) => {
+ const { name, source } = subKernel;
+ return new FunctionNode(source, Object.assign({}, nodeOptions, {
+ name,
+ isSubKernel: true,
+ isRootKernel: false,
+ }));
+ });
+ }
+
+ const functionBuilder = new FunctionBuilder({
+ kernel,
+ rootNode,
+ functionNodes,
+ nativeFunctions,
+ subKernelNodes
+ });
+
+ return functionBuilder;
+ }
+
+ constructor(settings) {
+ settings = settings || {};
+ this.kernel = settings.kernel;
+ this.rootNode = settings.rootNode;
+ this.functionNodes = settings.functionNodes || [];
+ this.subKernelNodes = settings.subKernelNodes || [];
+ this.nativeFunctions = settings.nativeFunctions || [];
+ this.functionMap = {};
+ this.nativeFunctionNames = [];
+ this.lookupChain = [];
+ this.functionNodeDependencies = {};
+ this.functionCalls = {};
+
+ if (this.rootNode) {
+ this.functionMap['kernel'] = this.rootNode;
+ }
+
+ if (this.functionNodes) {
+ for (let i = 0; i < this.functionNodes.length; i++) {
+ this.functionMap[this.functionNodes[i].name] = this.functionNodes[i];
+ }
+ }
+
+ if (this.subKernelNodes) {
+ for (let i = 0; i < this.subKernelNodes.length; i++) {
+ this.functionMap[this.subKernelNodes[i].name] = this.subKernelNodes[i];
+ }
+ }
+
+ if (this.nativeFunctions) {
+ for (let i = 0; i < this.nativeFunctions.length; i++) {
+ const nativeFunction = this.nativeFunctions[i];
+ this.nativeFunctionNames.push(nativeFunction.name);
+ }
+ }
+ }
+
+ addFunctionNode(functionNode) {
+ if (!functionNode.name) throw new Error('functionNode.name needs set');
+ this.functionMap[functionNode.name] = functionNode;
+ if (functionNode.isRootKernel) {
+ this.rootNode = functionNode;
+ }
+ }
+
+ traceFunctionCalls(functionName, retList) {
+ functionName = functionName || 'kernel';
+ retList = retList || [];
+
+ if (this.nativeFunctionNames.indexOf(functionName) > -1) {
+ const nativeFunctionIndex = retList.indexOf(functionName);
+ if (nativeFunctionIndex === -1) {
+ retList.push(functionName);
+ } else {
+ const dependantNativeFunctionName = retList.splice(nativeFunctionIndex, 1)[0];
+ retList.push(dependantNativeFunctionName);
+ }
+ return retList;
+ }
+
+ const functionNode = this.functionMap[functionName];
+ if (functionNode) {
+ const functionIndex = retList.indexOf(functionName);
+ if (functionIndex === -1) {
+ retList.push(functionName);
+ functionNode.toString();
+ for (let i = 0; i < functionNode.calledFunctions.length; ++i) {
+ this.traceFunctionCalls(functionNode.calledFunctions[i], retList);
+ }
+ } else {
+ const dependantFunctionName = retList.splice(functionIndex, 1)[0];
+ retList.push(dependantFunctionName);
+ }
+ }
+
+ return retList;
+ }
+
+ getPrototypeString(functionName) {
+ return this.getPrototypes(functionName).join('\n');
+ }
+
+ getPrototypes(functionName) {
+ if (this.rootNode) {
+ this.rootNode.toString();
+ }
+ if (functionName) {
+ return this.getPrototypesFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse());
+ }
+ return this.getPrototypesFromFunctionNames(Object.keys(this.functionMap));
+ }
+
+ getStringFromFunctionNames(functionList) {
+ const ret = [];
+ for (let i = 0; i < functionList.length; ++i) {
+ const node = this.functionMap[functionList[i]];
+ if (node) {
+ ret.push(this.functionMap[functionList[i]].toString());
+ }
+ }
+ return ret.join('\n');
+ }
+
+ getPrototypesFromFunctionNames(functionList) {
+ const ret = [];
+ for (let i = 0; i < functionList.length; ++i) {
+ const functionName = functionList[i];
+ const functionIndex = this.nativeFunctionNames.indexOf(functionName);
+ if (functionIndex > -1) {
+ ret.push(this.nativeFunctions[functionIndex].source);
+ continue;
+ }
+ const node = this.functionMap[functionName];
+ if (node) {
+ ret.push(node.toString());
+ }
+ }
+ return ret;
+ }
+
+ toJSON() {
+ return this.traceFunctionCalls(this.rootNode.name).reverse().map(name => {
+ const nativeIndex = this.nativeFunctions.indexOf(name);
+ if (nativeIndex > -1) {
+ return {
+ name,
+ source: this.nativeFunctions[nativeIndex].source
+ };
+ } else if (this.functionMap[name]) {
+ return this.functionMap[name].toJSON();
+ } else {
+ throw new Error(`function ${ name } not found`);
+ }
+ });
+ }
+
+ fromJSON(jsonFunctionNodes, FunctionNode) {
+ this.functionMap = {};
+ for (let i = 0; i < jsonFunctionNodes.length; i++) {
+ const jsonFunctionNode = jsonFunctionNodes[i];
+ this.functionMap[jsonFunctionNode.settings.name] = new FunctionNode(jsonFunctionNode.ast, jsonFunctionNode.settings);
+ }
+ return this;
+ }
+
+ getString(functionName) {
+ if (functionName) {
+ return this.getStringFromFunctionNames(this.traceFunctionCalls(functionName).reverse());
+ }
+ return this.getStringFromFunctionNames(Object.keys(this.functionMap));
+ }
+
+ lookupReturnType(functionName, ast, requestingNode) {
+ if (ast.type !== 'CallExpression') {
+ throw new Error(`expected ast type of "CallExpression", but is ${ ast.type }`);
+ }
+ if (this._isNativeFunction(functionName)) {
+ return this._lookupNativeFunctionReturnType(functionName);
+ } else if (this._isFunction(functionName)) {
+ const node = this._getFunction(functionName);
+ if (node.returnType) {
+ return node.returnType;
+ } else {
+ for (let i = 0; i < this.lookupChain.length; i++) {
+ if (this.lookupChain[i].ast === ast) {
+ if (node.argumentTypes.length === 0 && ast.arguments.length > 0) {
+ const args = ast.arguments;
+ for (let j = 0; j < args.length; j++) {
+ this.lookupChain.push({
+ name: requestingNode.name,
+ ast: args[i],
+ requestingNode
+ });
+ node.argumentTypes[j] = requestingNode.getType(args[j]);
+ this.lookupChain.pop();
+ }
+ return node.returnType = node.getType(node.getJsAST());
+ }
+
+ throw new Error('circlical logic detected!');
+ }
+ }
+ this.lookupChain.push({
+ name: requestingNode.name,
+ ast,
+ requestingNode
+ });
+ const type = node.getType(node.getJsAST());
+ this.lookupChain.pop();
+ return node.returnType = type;
+ }
+ }
+
+ return null;
+ }
+
+ _getFunction(functionName) {
+ if (!this._isFunction(functionName)) {
+ new Error(`Function ${functionName} not found`);
+ }
+ return this.functionMap[functionName];
+ }
+
+ _isFunction(functionName) {
+ return Boolean(this.functionMap[functionName]);
+ }
+
+ _getNativeFunction(functionName) {
+ for (let i = 0; i < this.nativeFunctions.length; i++) {
+ if (this.nativeFunctions[i].name === functionName) return this.nativeFunctions[i];
+ }
+ return null;
+ }
+
+ _isNativeFunction(functionName) {
+ return Boolean(this._getNativeFunction(functionName));
+ }
+
+ _lookupNativeFunctionReturnType(functionName) {
+ let nativeFunction = this._getNativeFunction(functionName);
+ if (nativeFunction) {
+ return nativeFunction.returnType;
+ }
+ throw new Error(`Native function ${ functionName } not found`);
+ }
+
+ lookupFunctionArgumentTypes(functionName) {
+ if (this._isNativeFunction(functionName)) {
+ return this._getNativeFunction(functionName).argumentTypes;
+ } else if (this._isFunction(functionName)) {
+ return this._getFunction(functionName).argumentTypes;
+ }
+ return null;
+ }
+
+ lookupFunctionArgumentName(functionName, argumentIndex) {
+ return this._getFunction(functionName).argumentNames[argumentIndex];
+ }
+
+ lookupFunctionArgumentBitRatio(functionName, argumentName) {
+ if (!this._isFunction(functionName)) {
+ throw new Error('function not found');
+ }
+ if (this.rootNode.name === functionName) {
+ const i = this.rootNode.argumentNames.indexOf(argumentName);
+ if (i !== -1) {
+ return this.rootNode.argumentBitRatios[i];
+ }
+ }
+ const node = this._getFunction(functionName);
+ const i = node.argumentNames.indexOf(argumentName);
+ if (i === -1) {
+ throw new Error('argument not found');
+ }
+ const bitRatio = node.argumentBitRatios[i];
+ if (typeof bitRatio !== 'number') {
+ throw new Error('argument bit ratio not found');
+ }
+ return bitRatio;
+ }
+
+ needsArgumentType(functionName, i) {
+ if (!this._isFunction(functionName)) return false;
+ const fnNode = this._getFunction(functionName);
+ return !fnNode.argumentTypes[i];
+ }
+
+ assignArgumentType(functionName, i, argumentType, requestingNode) {
+ if (!this._isFunction(functionName)) return;
+ const fnNode = this._getFunction(functionName);
+ if (!fnNode.argumentTypes[i]) {
+ fnNode.argumentTypes[i] = argumentType;
+ }
+ }
+
+ assignArgumentBitRatio(functionName, argumentName, calleeFunctionName, argumentIndex) {
+ const node = this._getFunction(functionName);
+ if (this._isNativeFunction(calleeFunctionName)) return null;
+ const calleeNode = this._getFunction(calleeFunctionName);
+ const i = node.argumentNames.indexOf(argumentName);
+ if (i === -1) {
+ throw new Error(`Argument ${argumentName} not found in arguments from function ${functionName}`);
+ }
+ const bitRatio = node.argumentBitRatios[i];
+ if (typeof bitRatio !== 'number') {
+ throw new Error(`Bit ratio for argument ${argumentName} not found in function ${functionName}`);
+ }
+ if (!calleeNode.argumentBitRatios) {
+ calleeNode.argumentBitRatios = new Array(calleeNode.argumentNames.length);
+ }
+ const calleeBitRatio = calleeNode.argumentBitRatios[i];
+ if (typeof calleeBitRatio === 'number') {
+ if (calleeBitRatio !== bitRatio) {
+ throw new Error(`Incompatible bit ratio found at function ${functionName} at argument ${argumentName}`);
+ }
+ return calleeBitRatio;
+ }
+ calleeNode.argumentBitRatios[i] = bitRatio;
+ return bitRatio;
+ }
+
+ trackFunctionCall(functionName, calleeFunctionName, args) {
+ if (!this.functionNodeDependencies[functionName]) {
+ this.functionNodeDependencies[functionName] = new Set();
+ this.functionCalls[functionName] = [];
+ }
+ this.functionNodeDependencies[functionName].add(calleeFunctionName);
+ this.functionCalls[functionName].push(args);
+ }
+
+ getKernelResultType() {
+ return this.rootNode.returnType || this.rootNode.getType(this.rootNode.ast);
+ }
+
+ getSubKernelResultType(index) {
+ const subKernelNode = this.subKernelNodes[index];
+ let called = false;
+ for (let functionCallIndex = 0; functionCallIndex < this.rootNode.functionCalls.length; functionCallIndex++) {
+ const functionCall = this.rootNode.functionCalls[functionCallIndex];
+ if (functionCall.ast.callee.name === subKernelNode.name) {
+ called = true;
+ }
+ }
+ if (!called) {
+ throw new Error(`SubKernel ${ subKernelNode.name } never called by kernel`);
+ }
+ return subKernelNode.returnType || subKernelNode.getType(subKernelNode.getJsAST());
+ }
+
+ getReturnTypes() {
+ const result = {
+ [this.rootNode.name]: this.rootNode.getType(this.rootNode.ast),
+ };
+ const list = this.traceFunctionCalls(this.rootNode.name);
+ for (let i = 0; i < list.length; i++) {
+ const functionName = list[i];
+ const functionNode = this.functionMap[functionName];
+ result[functionName] = functionNode.getType(functionNode.ast);
+ }
+ return result;
+ }
+}
+
+module.exports = {
+ FunctionBuilder
+};
+},{}],10:[function(require,module,exports){
+const acorn = require('acorn');
+const { utils } = require('../utils');
+const { FunctionTracer } = require('./function-tracer');
+
+class FunctionNode {
+ constructor(source, settings) {
+ if (!source && !settings.ast) {
+ throw new Error('source parameter is missing');
+ }
+ settings = settings || {};
+ this.source = source;
+ this.ast = null;
+ this.name = typeof source === 'string' ? settings.isRootKernel ?
+ 'kernel' :
+ (settings.name || utils.getFunctionNameFromString(source)) : null;
+ this.calledFunctions = [];
+ this.constants = {};
+ this.constantTypes = {};
+ this.constantBitRatios = {};
+ this.isRootKernel = false;
+ this.isSubKernel = false;
+ 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 = (typeof this.source === 'string' ? utils.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 = false;
+ this.fixIntegerDivisionAccuracy = null;
+
+ if (settings) {
+ for (const p in settings) {
+ if (!settings.hasOwnProperty(p)) continue;
+ if (!this.hasOwnProperty(p)) continue;
+ this[p] = settings[p];
+ }
+ }
+
+ this.literalTypes = {};
+
+ this.validate();
+ this._string = null;
+ this._internalVariableNames = {};
+ }
+
+ validate() {
+ if (typeof this.source !== 'string' && !this.ast) {
+ throw new Error('this.source not a string');
+ }
+
+ if (!this.ast && !utils.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(name) {
+ if (!this.constants) return false;
+ return this.constants.hasOwnProperty(name);
+ }
+
+ isInput(argumentName) {
+ return this.argumentTypes[this.argumentNames.indexOf(argumentName)] === 'Input';
+ }
+
+ pushState(state) {
+ this.states.push(state);
+ }
+
+ popState(state) {
+ if (this.state !== state) {
+ throw new Error(`Cannot popState ${ state } when in ${ this.state }`);
+ }
+ this.states.pop();
+ }
+
+ isState(state) {
+ return this.state === state;
+ }
+
+ get state() {
+ return this.states[this.states.length - 1];
+ }
+
+ astMemberExpressionUnroll(ast) {
+ if (ast.type === 'Identifier') {
+ return ast.name;
+ } else if (ast.type === 'ThisExpression') {
+ return 'this';
+ }
+
+ if (ast.type === 'MemberExpression') {
+ if (ast.object && ast.property) {
+ if (ast.object.hasOwnProperty('name') && ast.object.name !== 'Math') {
+ return this.astMemberExpressionUnroll(ast.property);
+ }
+
+ return (
+ this.astMemberExpressionUnroll(ast.object) +
+ '.' +
+ this.astMemberExpressionUnroll(ast.property)
+ );
+ }
+ }
+
+ if (ast.hasOwnProperty('expressions')) {
+ const firstExpression = ast.expressions[0];
+ if (firstExpression.type === 'Literal' && firstExpression.value === 0 && ast.expressions.length === 2) {
+ return this.astMemberExpressionUnroll(ast.expressions[1]);
+ }
+ }
+
+ throw this.astErrorOutput('Unknown astMemberExpressionUnroll', ast);
+ }
+
+ getJsAST(inParser) {
+ if (this.ast) {
+ return this.ast;
+ }
+ if (typeof this.source === 'object') {
+ this.traceFunctionAST(this.source);
+ return this.ast = this.source;
+ }
+
+ inParser = inParser || acorn;
+ if (inParser === null) {
+ throw new Error('Missing JS to AST parser');
+ }
+
+ const ast = Object.freeze(inParser.parse(`const parser_${ this.name } = ${ this.source };`, {
+ locations: true
+ }));
+ const functionAST = ast.body[0].declarations[0].init;
+ this.traceFunctionAST(functionAST);
+
+ if (!ast) {
+ throw new Error('Failed to parse JS code');
+ }
+
+ return this.ast = functionAST;
+ }
+
+ traceFunctionAST(ast) {
+ const { contexts, declarations, functions, identifiers, functionCalls } = new FunctionTracer(ast);
+ this.contexts = contexts;
+ this.identifiers = identifiers;
+ this.functionCalls = functionCalls;
+ this.functions = functions;
+ for (let i = 0; i < declarations.length; i++) {
+ const declaration = declarations[i];
+ const { ast, inForLoopInit, inForLoopTest } = declaration;
+ const { init } = ast;
+ const dependencies = this.getDependencies(init);
+ let valueType = null;
+
+ if (inForLoopInit && inForLoopTest) {
+ valueType = 'Integer';
+ } else {
+ if (init) {
+ const realType = this.getType(init);
+ switch (realType) {
+ case 'Integer':
+ case 'Float':
+ case 'Number':
+ if (init.type === 'MemberExpression') {
+ valueType = realType;
+ } else {
+ valueType = 'Number';
+ }
+ break;
+ case 'LiteralInteger':
+ valueType = 'Number';
+ break;
+ default:
+ valueType = realType;
+ }
+ }
+ }
+ declaration.valueType = valueType;
+ declaration.dependencies = dependencies;
+ declaration.isSafe = this.isSafeDependencies(dependencies);
+ }
+
+ for (let i = 0; i < functions.length; i++) {
+ this.onNestedFunction(functions[i], this.source);
+ }
+ }
+
+ getDeclaration(ast) {
+ for (let i = 0; i < this.identifiers.length; i++) {
+ const identifier = this.identifiers[i];
+ if (ast === identifier.ast) {
+ return identifier.declaration;
+ }
+ }
+ return null;
+ }
+
+ getVariableType(ast) {
+ if (ast.type !== 'Identifier') {
+ throw new Error(`ast of ${ast.type} not "Identifier"`);
+ }
+ let type = null;
+ const argumentIndex = this.argumentNames.indexOf(ast.name);
+ if (argumentIndex === -1) {
+ const declaration = this.getDeclaration(ast);
+ if (declaration) {
+ return declaration.valueType;
+ }
+ } else {
+ const argumentType = this.argumentTypes[argumentIndex];
+ if (argumentType) {
+ type = argumentType;
+ }
+ }
+ if (!type && this.strictTypingChecking) {
+ throw new Error(`Declaration of ${name} not found`);
+ }
+ return type;
+ }
+
+ getLookupType(type) {
+ if (!typeLookupMap.hasOwnProperty(type)) {
+ throw new Error(`unknown typeLookupMap ${ type }`);
+ }
+ return typeLookupMap[type];
+ }
+
+ getConstantType(constantName) {
+ if (this.constantTypes[constantName]) {
+ const type = this.constantTypes[constantName];
+ if (type === 'Float') {
+ return 'Number';
+ } else {
+ return type;
+ }
+ }
+ throw new Error(`Type for constant "${ constantName }" not declared`);
+ }
+
+ toString() {
+ if (this._string) return this._string;
+ return this._string = this.astGeneric(this.getJsAST(), []).join('').trim();
+ }
+
+ toJSON() {
+ const settings = {
+ source: this.source,
+ name: this.name,
+ constants: this.constants,
+ constantTypes: this.constantTypes,
+ isRootKernel: this.isRootKernel,
+ isSubKernel: this.isSubKernel,
+ debug: this.debug,
+ output: this.output,
+ loopMaxIterations: this.loopMaxIterations,
+ argumentNames: this.argumentNames,
+ argumentTypes: this.argumentTypes,
+ argumentSizes: this.argumentSizes,
+ returnType: this.returnType,
+ leadingReturnStatement: this.leadingReturnStatement,
+ followingReturnStatement: this.followingReturnStatement,
+ };
+
+ return {
+ ast: this.ast,
+ settings
+ };
+ }
+
+ getType(ast) {
+ if (Array.isArray(ast)) {
+ return this.getType(ast[ast.length - 1]);
+ }
+ switch (ast.type) {
+ case 'BlockStatement':
+ return this.getType(ast.body);
+ case 'ArrayExpression':
+ const childType = this.getType(ast.elements[0]);
+ switch (childType) {
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ return `Matrix(${ast.elements.length})`;
+ }
+ return `Array(${ ast.elements.length })`;
+ case 'Literal':
+ const literalKey = this.astKey(ast);
+ if (this.literalTypes[literalKey]) {
+ return this.literalTypes[literalKey];
+ }
+ if (Number.isInteger(ast.value)) {
+ return 'LiteralInteger';
+ } else if (ast.value === true || ast.value === false) {
+ return 'Boolean';
+ } else {
+ return 'Number';
+ }
+ case 'AssignmentExpression':
+ return this.getType(ast.left);
+ case 'CallExpression':
+ if (this.isAstMathFunction(ast)) {
+ return 'Number';
+ }
+ if (!ast.callee || !ast.callee.name) {
+ if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[ast.callee.expressions.length - 1].property.name) {
+ const functionName = ast.callee.expressions[ast.callee.expressions.length - 1].property.name;
+ this.inferArgumentTypesIfNeeded(functionName, ast.arguments);
+ return this.lookupReturnType(functionName, ast, this);
+ }
+ if (this.getVariableSignature(ast.callee, true) === 'this.color') {
+ return null;
+ }
+ if (ast.callee.type === 'MemberExpression' && ast.callee.object && ast.callee.property && ast.callee.property.name && ast.arguments) {
+ const functionName = ast.callee.property.name;
+ this.inferArgumentTypesIfNeeded(functionName, ast.arguments);
+ return this.lookupReturnType(functionName, ast, this);
+ }
+ throw this.astErrorOutput('Unknown call expression', ast);
+ }
+ if (ast.callee && ast.callee.name) {
+ const functionName = ast.callee.name;
+ this.inferArgumentTypesIfNeeded(functionName, ast.arguments);
+ return this.lookupReturnType(functionName, ast, this);
+ }
+ throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast);
+ case 'LogicalExpression':
+ return 'Boolean';
+ case 'BinaryExpression':
+ switch (ast.operator) {
+ case '%':
+ case '/':
+ if (this.fixIntegerDivisionAccuracy) {
+ return 'Number';
+ } else {
+ break;
+ }
+ case '>':
+ case '<':
+ return 'Boolean';
+ case '&':
+ case '|':
+ case '^':
+ case '<<':
+ case '>>':
+ case '>>>':
+ return 'Integer';
+ }
+ const type = this.getType(ast.left);
+ if (this.isState('skip-literal-correction')) return type;
+ if (type === 'LiteralInteger') {
+ const rightType = this.getType(ast.right);
+ if (rightType === 'LiteralInteger') {
+ if (ast.left.value % 1 === 0) {
+ return 'Integer';
+ } else {
+ return 'Float';
+ }
+ }
+ return rightType;
+ }
+ return typeLookupMap[type] || type;
+ case 'UpdateExpression':
+ return this.getType(ast.argument);
+ case 'UnaryExpression':
+ if (ast.operator === '~') {
+ return 'Integer';
+ }
+ return this.getType(ast.argument);
+ case 'VariableDeclaration': {
+ const declarations = ast.declarations;
+ let lastType;
+ for (let i = 0; i < declarations.length; i++) {
+ const declaration = declarations[i];
+ lastType = this.getType(declaration);
+ }
+ if (!lastType) {
+ throw this.astErrorOutput(`Unable to find type for declaration`, ast);
+ }
+ return lastType;
+ }
+ case 'VariableDeclarator':
+ const declaration = this.getDeclaration(ast.id);
+ if (!declaration) {
+ throw this.astErrorOutput(`Unable to find declarator`, ast);
+ }
+
+ if (!declaration.valueType) {
+ throw this.astErrorOutput(`Unable to find declarator valueType`, ast);
+ }
+
+ return declaration.valueType;
+ case 'Identifier':
+ if (ast.name === 'Infinity') {
+ return 'Number';
+ }
+ if (this.isAstVariable(ast)) {
+ const signature = this.getVariableSignature(ast);
+ if (signature === 'value') {
+ return this.getCheckVariableType(ast);
+ }
+ }
+ const origin = this.findIdentifierOrigin(ast);
+ if (origin && origin.init) {
+ return this.getType(origin.init);
+ }
+ return null;
+ case 'ReturnStatement':
+ return this.getType(ast.argument);
+ case 'MemberExpression':
+ if (this.isAstMathFunction(ast)) {
+ switch (ast.property.name) {
+ case 'ceil':
+ return 'Integer';
+ case 'floor':
+ return 'Integer';
+ case 'round':
+ return 'Integer';
+ }
+ return 'Number';
+ }
+ if (this.isAstVariable(ast)) {
+ const variableSignature = this.getVariableSignature(ast);
+ switch (variableSignature) {
+ case 'value[]':
+ return this.getLookupType(this.getCheckVariableType(ast.object));
+ case 'value[][]':
+ return this.getLookupType(this.getCheckVariableType(ast.object.object));
+ case 'value[][][]':
+ return this.getLookupType(this.getCheckVariableType(ast.object.object.object));
+ case 'value[][][][]':
+ return this.getLookupType(this.getCheckVariableType(ast.object.object.object.object));
+ case 'value.thread.value':
+ case 'this.thread.value':
+ return 'Integer';
+ case 'this.output.value':
+ return this.dynamicOutput ? 'Integer' : 'LiteralInteger';
+ case 'this.constants.value':
+ return this.getConstantType(ast.property.name);
+ case 'this.constants.value[]':
+ return this.getLookupType(this.getConstantType(ast.object.property.name));
+ case 'this.constants.value[][]':
+ return this.getLookupType(this.getConstantType(ast.object.object.property.name));
+ case 'this.constants.value[][][]':
+ return this.getLookupType(this.getConstantType(ast.object.object.object.property.name));
+ case 'this.constants.value[][][][]':
+ return this.getLookupType(this.getConstantType(ast.object.object.object.object.property.name));
+ case 'fn()[]':
+ case 'fn()[][]':
+ case 'fn()[][][]':
+ return this.getLookupType(this.getType(ast.object));
+ case 'value.value':
+ if (this.isAstMathVariable(ast)) {
+ return 'Number';
+ }
+ switch (ast.property.name) {
+ case 'r':
+ case 'g':
+ case 'b':
+ case 'a':
+ return this.getLookupType(this.getCheckVariableType(ast.object));
+ }
+ case '[][]':
+ return 'Number';
+ }
+ throw this.astErrorOutput('Unhandled getType MemberExpression', ast);
+ }
+ throw this.astErrorOutput('Unhandled getType MemberExpression', ast);
+ case 'ConditionalExpression':
+ return this.getType(ast.consequent);
+ case 'FunctionDeclaration':
+ case 'FunctionExpression':
+ const lastReturn = this.findLastReturn(ast.body);
+ if (lastReturn) {
+ return this.getType(lastReturn);
+ }
+ return null;
+ case 'IfStatement':
+ return this.getType(ast.consequent);
+ case 'SequenceExpression':
+ return this.getType(ast.expressions[ast.expressions.length - 1]);
+ default:
+ throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast);
+ }
+ }
+
+ getCheckVariableType(ast) {
+ const type = this.getVariableType(ast);
+ if (!type) {
+ throw this.astErrorOutput(`${ast.type} is not defined`, ast);
+ }
+ return type;
+ }
+
+ inferArgumentTypesIfNeeded(functionName, args) {
+ for (let i = 0; i < args.length; i++) {
+ if (!this.needsArgumentType(functionName, i)) continue;
+ const type = this.getType(args[i]);
+ if (!type) {
+ throw this.astErrorOutput(`Unable to infer argument ${i}`, args[i]);
+ }
+ this.assignArgumentType(functionName, i, type);
+ }
+ }
+
+ isAstMathVariable(ast) {
+ const mathProperties = [
+ 'E',
+ 'PI',
+ 'SQRT2',
+ 'SQRT1_2',
+ 'LN2',
+ 'LN10',
+ 'LOG2E',
+ 'LOG10E',
+ ];
+ return ast.type === 'MemberExpression' &&
+ ast.object && ast.object.type === 'Identifier' &&
+ ast.object.name === 'Math' &&
+ ast.property &&
+ ast.property.type === 'Identifier' &&
+ mathProperties.indexOf(ast.property.name) > -1;
+ }
+
+ isAstMathFunction(ast) {
+ const mathFunctions = [
+ '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',
+ ];
+ return ast.type === 'CallExpression' &&
+ ast.callee &&
+ ast.callee.type === 'MemberExpression' &&
+ ast.callee.object &&
+ ast.callee.object.type === 'Identifier' &&
+ ast.callee.object.name === 'Math' &&
+ ast.callee.property &&
+ ast.callee.property.type === 'Identifier' &&
+ mathFunctions.indexOf(ast.callee.property.name) > -1;
+ }
+
+ isAstVariable(ast) {
+ return ast.type === 'Identifier' || ast.type === 'MemberExpression';
+ }
+
+ isSafe(ast) {
+ return this.isSafeDependencies(this.getDependencies(ast));
+ }
+
+ isSafeDependencies(dependencies) {
+ return dependencies && dependencies.every ? dependencies.every(dependency => dependency.isSafe) : true;
+ }
+
+ getDependencies(ast, dependencies, isNotSafe) {
+ if (!dependencies) {
+ dependencies = [];
+ }
+ if (!ast) return null;
+ if (Array.isArray(ast)) {
+ for (let i = 0; i < ast.length; i++) {
+ this.getDependencies(ast[i], dependencies, isNotSafe);
+ }
+ return dependencies;
+ }
+ switch (ast.type) {
+ case 'AssignmentExpression':
+ this.getDependencies(ast.left, dependencies, isNotSafe);
+ this.getDependencies(ast.right, dependencies, isNotSafe);
+ return dependencies;
+ case 'ConditionalExpression':
+ this.getDependencies(ast.test, dependencies, isNotSafe);
+ this.getDependencies(ast.alternate, dependencies, isNotSafe);
+ this.getDependencies(ast.consequent, dependencies, isNotSafe);
+ return dependencies;
+ case 'Literal':
+ dependencies.push({
+ origin: 'literal',
+ value: ast.value,
+ isSafe: isNotSafe === true ? false : ast.value > -Infinity && ast.value < Infinity && !isNaN(ast.value)
+ });
+ break;
+ case 'VariableDeclarator':
+ return this.getDependencies(ast.init, dependencies, isNotSafe);
+ case 'Identifier':
+ const declaration = this.getDeclaration(ast);
+ if (declaration) {
+ dependencies.push({
+ name: ast.name,
+ origin: 'declaration',
+ isSafe: isNotSafe ? false : this.isSafeDependencies(declaration.dependencies),
+ });
+ } else if (this.argumentNames.indexOf(ast.name) > -1) {
+ dependencies.push({
+ name: ast.name,
+ origin: 'argument',
+ isSafe: false,
+ });
+ } else if (this.strictTypingChecking) {
+ throw new Error(`Cannot find identifier origin "${ast.name}"`);
+ }
+ break;
+ case 'FunctionDeclaration':
+ return this.getDependencies(ast.body.body[ast.body.body.length - 1], dependencies, isNotSafe);
+ case 'ReturnStatement':
+ return this.getDependencies(ast.argument, dependencies);
+ case 'BinaryExpression':
+ case 'LogicalExpression':
+ isNotSafe = (ast.operator === '/' || ast.operator === '*');
+ this.getDependencies(ast.left, dependencies, isNotSafe);
+ this.getDependencies(ast.right, dependencies, isNotSafe);
+ return dependencies;
+ case 'UnaryExpression':
+ case 'UpdateExpression':
+ return this.getDependencies(ast.argument, dependencies, isNotSafe);
+ case 'VariableDeclaration':
+ return this.getDependencies(ast.declarations, dependencies, isNotSafe);
+ case 'ArrayExpression':
+ dependencies.push({
+ origin: 'declaration',
+ isSafe: true,
+ });
+ return dependencies;
+ case 'CallExpression':
+ dependencies.push({
+ origin: 'function',
+ isSafe: true,
+ });
+ return dependencies;
+ case 'MemberExpression':
+ const details = this.getMemberExpressionDetails(ast);
+ switch (details.signature) {
+ case 'value[]':
+ this.getDependencies(ast.object, dependencies, isNotSafe);
+ break;
+ case 'value[][]':
+ this.getDependencies(ast.object.object, dependencies, isNotSafe);
+ break;
+ case 'value[][][]':
+ this.getDependencies(ast.object.object.object, dependencies, isNotSafe);
+ break;
+ case 'this.output.value':
+ if (this.dynamicOutput) {
+ dependencies.push({
+ name: details.name,
+ origin: 'output',
+ isSafe: false,
+ });
+ }
+ break;
+ }
+ if (details) {
+ if (details.property) {
+ this.getDependencies(details.property, dependencies, isNotSafe);
+ }
+ if (details.xProperty) {
+ this.getDependencies(details.xProperty, dependencies, isNotSafe);
+ }
+ if (details.yProperty) {
+ this.getDependencies(details.yProperty, dependencies, isNotSafe);
+ }
+ if (details.zProperty) {
+ this.getDependencies(details.zProperty, dependencies, isNotSafe);
+ }
+ return dependencies;
+ }
+ case 'SequenceExpression':
+ return this.getDependencies(ast.expressions, dependencies, isNotSafe);
+ default:
+ throw this.astErrorOutput(`Unhandled type ${ ast.type } in getDependencies`, ast);
+ }
+ return dependencies;
+ }
+
+ getVariableSignature(ast, returnRawValue) {
+ if (!this.isAstVariable(ast)) {
+ throw new Error(`ast of type "${ ast.type }" is not a variable signature`);
+ }
+ if (ast.type === 'Identifier') {
+ return 'value';
+ }
+ const signature = [];
+ while (true) {
+ if (!ast) break;
+ if (ast.computed) {
+ signature.push('[]');
+ } else if (ast.type === 'ThisExpression') {
+ signature.unshift('this');
+ } else if (ast.property && ast.property.name) {
+ if (
+ ast.property.name === 'x' ||
+ ast.property.name === 'y' ||
+ ast.property.name === 'z'
+ ) {
+ signature.unshift(returnRawValue ? '.' + ast.property.name : '.value');
+ } else if (
+ ast.property.name === 'constants' ||
+ ast.property.name === 'thread' ||
+ ast.property.name === 'output'
+ ) {
+ signature.unshift('.' + ast.property.name);
+ } else {
+ signature.unshift(returnRawValue ? '.' + ast.property.name : '.value');
+ }
+ } else if (ast.name) {
+ signature.unshift(returnRawValue ? ast.name : 'value');
+ } else if (ast.callee && ast.callee.name) {
+ signature.unshift(returnRawValue ? ast.callee.name + '()' : 'fn()');
+ } else if (ast.elements) {
+ signature.unshift('[]');
+ } else {
+ signature.unshift('unknown');
+ }
+ ast = ast.object;
+ }
+
+ const signatureString = signature.join('');
+ if (returnRawValue) {
+ return signatureString;
+ }
+
+ const allowedExpressions = [
+ '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()[][][]',
+ '[][]',
+ ];
+ if (allowedExpressions.indexOf(signatureString) > -1) {
+ return signatureString;
+ }
+ return null;
+ }
+
+ build() {
+ return this.toString().length > 0;
+ }
+
+ astGeneric(ast, retArr) {
+ if (ast === null) {
+ throw this.astErrorOutput('NULL ast', ast);
+ } else {
+ if (Array.isArray(ast)) {
+ for (let i = 0; i < ast.length; i++) {
+ this.astGeneric(ast[i], retArr);
+ }
+ return retArr;
+ }
+
+ switch (ast.type) {
+ case 'FunctionDeclaration':
+ return this.astFunctionDeclaration(ast, retArr);
+ case 'FunctionExpression':
+ return this.astFunctionExpression(ast, retArr);
+ case 'ReturnStatement':
+ return this.astReturnStatement(ast, retArr);
+ case 'Literal':
+ return this.astLiteral(ast, retArr);
+ case 'BinaryExpression':
+ return this.astBinaryExpression(ast, retArr);
+ case 'Identifier':
+ return this.astIdentifierExpression(ast, retArr);
+ case 'AssignmentExpression':
+ return this.astAssignmentExpression(ast, retArr);
+ case 'ExpressionStatement':
+ return this.astExpressionStatement(ast, retArr);
+ case 'EmptyStatement':
+ return this.astEmptyStatement(ast, retArr);
+ case 'BlockStatement':
+ return this.astBlockStatement(ast, retArr);
+ case 'IfStatement':
+ return this.astIfStatement(ast, retArr);
+ case 'SwitchStatement':
+ return this.astSwitchStatement(ast, retArr);
+ case 'BreakStatement':
+ return this.astBreakStatement(ast, retArr);
+ case 'ContinueStatement':
+ return this.astContinueStatement(ast, retArr);
+ case 'ForStatement':
+ return this.astForStatement(ast, retArr);
+ case 'WhileStatement':
+ return this.astWhileStatement(ast, retArr);
+ case 'DoWhileStatement':
+ return this.astDoWhileStatement(ast, retArr);
+ case 'VariableDeclaration':
+ return this.astVariableDeclaration(ast, retArr);
+ case 'VariableDeclarator':
+ return this.astVariableDeclarator(ast, retArr);
+ case 'ThisExpression':
+ return this.astThisExpression(ast, retArr);
+ case 'SequenceExpression':
+ return this.astSequenceExpression(ast, retArr);
+ case 'UnaryExpression':
+ return this.astUnaryExpression(ast, retArr);
+ case 'UpdateExpression':
+ return this.astUpdateExpression(ast, retArr);
+ case 'LogicalExpression':
+ return this.astLogicalExpression(ast, retArr);
+ case 'MemberExpression':
+ return this.astMemberExpression(ast, retArr);
+ case 'CallExpression':
+ return this.astCallExpression(ast, retArr);
+ case 'ArrayExpression':
+ return this.astArrayExpression(ast, retArr);
+ case 'DebuggerStatement':
+ return this.astDebuggerStatement(ast, retArr);
+ case 'ConditionalExpression':
+ return this.astConditionalExpression(ast, retArr);
+ }
+
+ throw this.astErrorOutput('Unknown ast type : ' + ast.type, ast);
+ }
+ }
+ astErrorOutput(error, ast) {
+ if (typeof this.source !== 'string') {
+ return new Error(error);
+ }
+
+ const debugString = utils.getAstString(this.source, ast);
+ const leadingSource = this.source.substr(ast.start);
+ const splitLines = leadingSource.split(/\n/);
+ const lineBefore = splitLines.length > 0 ? splitLines[splitLines.length - 1] : 0;
+ return new Error(`${error} on line ${ splitLines.length }, position ${ lineBefore.length }:\n ${ debugString }`);
+ }
+
+ astDebuggerStatement(arrNode, retArr) {
+ return retArr;
+ }
+
+ astConditionalExpression(ast, retArr) {
+ if (ast.type !== 'ConditionalExpression') {
+ throw this.astErrorOutput('Not a conditional expression', ast);
+ }
+ retArr.push('(');
+ this.astGeneric(ast.test, retArr);
+ retArr.push('?');
+ this.astGeneric(ast.consequent, retArr);
+ retArr.push(':');
+ this.astGeneric(ast.alternate, retArr);
+ retArr.push(')');
+ return retArr;
+ }
+
+ astFunction(ast, retArr) {
+ throw new Error(`"astFunction" not defined on ${ this.constructor.name }`);
+ }
+
+ astFunctionDeclaration(ast, retArr) {
+ if (this.isChildFunction(ast)) {
+ return retArr;
+ }
+ return this.astFunction(ast, retArr);
+ }
+ astFunctionExpression(ast, retArr) {
+ if (this.isChildFunction(ast)) {
+ return retArr;
+ }
+ return this.astFunction(ast, retArr);
+ }
+ isChildFunction(ast) {
+ for (let i = 0; i < this.functions.length; i++) {
+ if (this.functions[i] === ast) {
+ return true;
+ }
+ }
+ return false;
+ }
+ astReturnStatement(ast, retArr) {
+ return retArr;
+ }
+ astLiteral(ast, retArr) {
+ this.literalTypes[this.astKey(ast)] = 'Number';
+ return retArr;
+ }
+ astBinaryExpression(ast, retArr) {
+ return retArr;
+ }
+ astIdentifierExpression(ast, retArr) {
+ return retArr;
+ }
+ astAssignmentExpression(ast, retArr) {
+ return retArr;
+ }
+ astExpressionStatement(esNode, retArr) {
+ this.astGeneric(esNode.expression, retArr);
+ retArr.push(';');
+ return retArr;
+ }
+ astEmptyStatement(eNode, retArr) {
+ return retArr;
+ }
+ astBlockStatement(ast, retArr) {
+ return retArr;
+ }
+ astIfStatement(ast, retArr) {
+ return retArr;
+ }
+ astSwitchStatement(ast, retArr) {
+ return retArr;
+ }
+ astBreakStatement(brNode, retArr) {
+ retArr.push('break;');
+ return retArr;
+ }
+ astContinueStatement(crNode, retArr) {
+ retArr.push('continue;\n');
+ return retArr;
+ }
+ astForStatement(ast, retArr) {
+ return retArr;
+ }
+ astWhileStatement(ast, retArr) {
+ return retArr;
+ }
+ astDoWhileStatement(ast, retArr) {
+ return retArr;
+ }
+ astVariableDeclarator(iVarDecNode, retArr) {
+ this.astGeneric(iVarDecNode.id, retArr);
+ if (iVarDecNode.init !== null) {
+ retArr.push('=');
+ this.astGeneric(iVarDecNode.init, retArr);
+ }
+ return retArr;
+ }
+ astThisExpression(ast, retArr) {
+ return retArr;
+ }
+ astSequenceExpression(sNode, retArr) {
+ const { expressions } = sNode;
+ const sequenceResult = [];
+ for (let i = 0; i < expressions.length; i++) {
+ const expression = expressions[i];
+ const expressionResult = [];
+ this.astGeneric(expression, expressionResult);
+ sequenceResult.push(expressionResult.join(''));
+ }
+ if (sequenceResult.length > 1) {
+ retArr.push('(', sequenceResult.join(','), ')');
+ } else {
+ retArr.push(sequenceResult[0]);
+ }
+ return retArr;
+ }
+ astUnaryExpression(uNode, retArr) {
+ const unaryResult = this.checkAndUpconvertBitwiseUnary(uNode, retArr);
+ if (unaryResult) {
+ 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;
+ }
+
+ checkAndUpconvertBitwiseUnary(uNode, retArr) {}
+
+ astUpdateExpression(uNode, 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;
+ }
+ astLogicalExpression(logNode, retArr) {
+ retArr.push('(');
+ this.astGeneric(logNode.left, retArr);
+ retArr.push(logNode.operator);
+ this.astGeneric(logNode.right, retArr);
+ retArr.push(')');
+ return retArr;
+ }
+ astMemberExpression(ast, retArr) {
+ return retArr;
+ }
+ astCallExpression(ast, retArr) {
+ return retArr;
+ }
+ astArrayExpression(ast, retArr) {
+ return retArr;
+ }
+
+ getMemberExpressionDetails(ast) {
+ if (ast.type !== 'MemberExpression') {
+ throw this.astErrorOutput(`Expression ${ ast.type } not a MemberExpression`, ast);
+ }
+ let name = null;
+ let type = null;
+ const variableSignature = this.getVariableSignature(ast);
+ switch (variableSignature) {
+ case 'value':
+ return null;
+ case 'value.thread.value':
+ case 'this.thread.value':
+ case 'this.output.value':
+ return {
+ signature: variableSignature,
+ type: 'Integer',
+ name: ast.property.name
+ };
+ case 'value[]':
+ if (typeof ast.object.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.object.name;
+ return {
+ name,
+ origin: 'user',
+ signature: variableSignature,
+ type: this.getVariableType(ast.object),
+ xProperty: ast.property
+ };
+ case 'value[][]':
+ if (typeof ast.object.object.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.object.object.name;
+ return {
+ name,
+ origin: 'user',
+ signature: variableSignature,
+ type: this.getVariableType(ast.object.object),
+ yProperty: ast.object.property,
+ xProperty: ast.property,
+ };
+ case 'value[][][]':
+ if (typeof ast.object.object.object.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.object.object.object.name;
+ return {
+ name,
+ origin: 'user',
+ signature: variableSignature,
+ type: this.getVariableType(ast.object.object.object),
+ zProperty: ast.object.object.property,
+ yProperty: ast.object.property,
+ xProperty: ast.property,
+ };
+ case 'value[][][][]':
+ if (typeof ast.object.object.object.object.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.object.object.object.object.name;
+ return {
+ name,
+ origin: 'user',
+ signature: variableSignature,
+ type: this.getVariableType(ast.object.object.object.object),
+ zProperty: ast.object.object.property,
+ yProperty: ast.object.property,
+ xProperty: ast.property,
+ };
+ case 'value.value':
+ if (typeof ast.property.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ if (this.isAstMathVariable(ast)) {
+ name = ast.property.name;
+ return {
+ name,
+ origin: 'Math',
+ type: 'Number',
+ signature: variableSignature,
+ };
+ }
+ switch (ast.property.name) {
+ case 'r':
+ case 'g':
+ case 'b':
+ case 'a':
+ name = ast.object.name;
+ return {
+ name,
+ property: ast.property.name,
+ origin: 'user',
+ signature: variableSignature,
+ type: 'Number'
+ };
+ default:
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ case 'this.constants.value':
+ if (typeof ast.property.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.property.name;
+ type = this.getConstantType(name);
+ if (!type) {
+ throw this.astErrorOutput('Constant has no type', ast);
+ }
+ return {
+ name,
+ type,
+ origin: 'constants',
+ signature: variableSignature,
+ };
+ case 'this.constants.value[]':
+ if (typeof ast.object.property.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.object.property.name;
+ type = this.getConstantType(name);
+ if (!type) {
+ throw this.astErrorOutput('Constant has no type', ast);
+ }
+ return {
+ name,
+ type,
+ origin: 'constants',
+ signature: variableSignature,
+ xProperty: ast.property,
+ };
+ case 'this.constants.value[][]': {
+ if (typeof ast.object.object.property.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.object.object.property.name;
+ type = this.getConstantType(name);
+ if (!type) {
+ throw this.astErrorOutput('Constant has no type', ast);
+ }
+ return {
+ name,
+ type,
+ origin: 'constants',
+ signature: variableSignature,
+ yProperty: ast.object.property,
+ xProperty: ast.property,
+ };
+ }
+ case 'this.constants.value[][][]': {
+ if (typeof ast.object.object.object.property.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.object.object.object.property.name;
+ type = this.getConstantType(name);
+ if (!type) {
+ throw this.astErrorOutput('Constant has no type', ast);
+ }
+ return {
+ name,
+ type,
+ origin: 'constants',
+ signature: variableSignature,
+ zProperty: ast.object.object.property,
+ yProperty: ast.object.property,
+ xProperty: ast.property,
+ };
+ }
+ case 'fn()[]':
+ case 'fn()[][]':
+ case '[][]':
+ return {
+ signature: variableSignature,
+ property: ast.property,
+ };
+ default:
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ }
+
+ findIdentifierOrigin(astToFind) {
+ const stack = [this.ast];
+
+ while (stack.length > 0) {
+ const atNode = stack[0];
+ if (atNode.type === 'VariableDeclarator' && atNode.id && atNode.id.name && atNode.id.name === astToFind.name) {
+ return atNode;
+ }
+ stack.shift();
+ if (atNode.argument) {
+ stack.push(atNode.argument);
+ } else if (atNode.body) {
+ stack.push(atNode.body);
+ } else if (atNode.declarations) {
+ stack.push(atNode.declarations);
+ } else if (Array.isArray(atNode)) {
+ for (let i = 0; i < atNode.length; i++) {
+ stack.push(atNode[i]);
+ }
+ }
+ }
+ return null;
+ }
+
+ findLastReturn(ast) {
+ const stack = [ast || this.ast];
+
+ while (stack.length > 0) {
+ const atNode = stack.pop();
+ if (atNode.type === 'ReturnStatement') {
+ return atNode;
+ }
+ if (atNode.type === 'FunctionDeclaration') {
+ continue;
+ }
+ if (atNode.argument) {
+ stack.push(atNode.argument);
+ } else if (atNode.body) {
+ stack.push(atNode.body);
+ } else if (atNode.declarations) {
+ stack.push(atNode.declarations);
+ } else if (Array.isArray(atNode)) {
+ for (let i = 0; i < atNode.length; i++) {
+ stack.push(atNode[i]);
+ }
+ } else if (atNode.consequent) {
+ stack.push(atNode.consequent);
+ } else if (atNode.cases) {
+ stack.push(atNode.cases);
+ }
+ }
+ return null;
+ }
+
+ getInternalVariableName(name) {
+ if (!this._internalVariableNames.hasOwnProperty(name)) {
+ this._internalVariableNames[name] = 0;
+ }
+ this._internalVariableNames[name]++;
+ if (this._internalVariableNames[name] === 1) {
+ return name;
+ }
+ return name + this._internalVariableNames[name];
+ }
+
+ astKey(ast, separator = ',') {
+ if (!ast.start || !ast.end) throw new Error('AST start and end needed');
+ return `${ast.start}${separator}${ast.end}`;
+ }
+}
+
+const typeLookupMap = {
+ '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)',
+};
+
+module.exports = {
+ FunctionNode
+};
+},{"../utils":114,"./function-tracer":11,"acorn":1}],11:[function(require,module,exports){
+const { utils } = require('../utils');
+
+function last(array) {
+ return array.length > 0 ? array[array.length - 1] : null;
+}
+
+const states = {
+ trackIdentifiers: 'trackIdentifiers',
+ memberExpression: 'memberExpression',
+ inForLoopInit: 'inForLoopInit'
+};
+
+class FunctionTracer {
+ constructor(ast) {
+ 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(ast);
+ }
+
+ isState(state) {
+ return this.states[this.states.length - 1] === state;
+ }
+
+ hasState(state) {
+ return this.states.indexOf(state) > -1;
+ }
+
+ pushState(state) {
+ this.states.push(state);
+ }
+
+ popState(state) {
+ if (this.isState(state)) {
+ this.states.pop();
+ } else {
+ throw new Error(`Cannot pop the non-active state "${state}"`);
+ }
+ }
+
+ get currentFunctionContext() {
+ return last(this.functionContexts);
+ }
+
+ get currentContext() {
+ return last(this.runningContexts);
+ }
+
+ newFunctionContext() {
+ const newContext = { '@contextType': 'function' };
+ this.contexts.push(newContext);
+ this.functionContexts.push(newContext);
+ }
+
+ newContext(run) {
+ const newContext = Object.assign({ '@contextType': 'const/let' }, this.currentContext);
+ this.contexts.push(newContext);
+ this.runningContexts.push(newContext);
+ run();
+ const { currentFunctionContext } = this;
+ for (const p in currentFunctionContext) {
+ if (!currentFunctionContext.hasOwnProperty(p) || newContext.hasOwnProperty(p)) continue;
+ newContext[p] = currentFunctionContext[p];
+ }
+ this.runningContexts.pop();
+ return newContext;
+ }
+
+ useFunctionContext(run) {
+ const functionContext = last(this.functionContexts);
+ this.runningContexts.push(functionContext);
+ run();
+ this.runningContexts.pop();
+ }
+
+ getIdentifiers(run) {
+ const trackedIdentifiers = this.trackedIdentifiers = [];
+ this.pushState(states.trackIdentifiers);
+ run();
+ this.trackedIdentifiers = null;
+ this.popState(states.trackIdentifiers);
+ return trackedIdentifiers;
+ }
+
+ getDeclaration(name) {
+ const { currentContext, currentFunctionContext, runningContexts } = this;
+ const declaration = currentContext[name] || currentFunctionContext[name] || null;
+
+ if (
+ !declaration &&
+ currentContext === currentFunctionContext &&
+ runningContexts.length > 0
+ ) {
+ const previousRunningContext = runningContexts[runningContexts.length - 2];
+ if (previousRunningContext[name]) {
+ return previousRunningContext[name];
+ }
+ }
+
+ return declaration;
+ }
+
+ scan(ast) {
+ if (!ast) return;
+ if (Array.isArray(ast)) {
+ for (let i = 0; i < ast.length; i++) {
+ this.scan(ast[i]);
+ }
+ return;
+ }
+ switch (ast.type) {
+ case 'Program':
+ this.useFunctionContext(() => {
+ this.scan(ast.body);
+ });
+ break;
+ case 'BlockStatement':
+ this.newContext(() => {
+ this.scan(ast.body);
+ });
+ break;
+ case 'AssignmentExpression':
+ case 'LogicalExpression':
+ this.scan(ast.left);
+ this.scan(ast.right);
+ break;
+ case 'BinaryExpression':
+ this.scan(ast.left);
+ this.scan(ast.right);
+ break;
+ case 'UpdateExpression':
+ if (ast.operator === '++') {
+ const declaration = this.getDeclaration(ast.argument.name);
+ if (declaration) {
+ declaration.suggestedType = 'Integer';
+ }
+ }
+ this.scan(ast.argument);
+ break;
+ case 'UnaryExpression':
+ this.scan(ast.argument);
+ break;
+ case 'VariableDeclaration':
+ if (ast.kind === 'var') {
+ this.useFunctionContext(() => {
+ ast.declarations = utils.normalizeDeclarations(ast);
+ this.scan(ast.declarations);
+ });
+ } else {
+ ast.declarations = utils.normalizeDeclarations(ast);
+ this.scan(ast.declarations);
+ }
+ break;
+ case 'VariableDeclarator': {
+ const { currentContext } = this;
+ const inForLoopInit = this.hasState(states.inForLoopInit);
+ const declaration = {
+ ast: ast,
+ context: currentContext,
+ name: ast.id.name,
+ origin: 'declaration',
+ inForLoopInit,
+ inForLoopTest: null,
+ assignable: currentContext === this.currentFunctionContext || (!inForLoopInit && !currentContext.hasOwnProperty(ast.id.name)),
+ suggestedType: null,
+ valueType: null,
+ dependencies: null,
+ isSafe: null,
+ };
+ if (!currentContext[ast.id.name]) {
+ currentContext[ast.id.name] = declaration;
+ }
+ this.declarations.push(declaration);
+ this.scan(ast.id);
+ this.scan(ast.init);
+ break;
+ }
+ case 'FunctionExpression':
+ case 'FunctionDeclaration':
+ if (this.runningContexts.length === 0) {
+ this.scan(ast.body);
+ } else {
+ this.functions.push(ast);
+ }
+ break;
+ case 'IfStatement':
+ this.scan(ast.test);
+ this.scan(ast.consequent);
+ if (ast.alternate) this.scan(ast.alternate);
+ break;
+ case 'ForStatement': {
+ let testIdentifiers;
+ const context = this.newContext(() => {
+ this.pushState(states.inForLoopInit);
+ this.scan(ast.init);
+ this.popState(states.inForLoopInit);
+
+ testIdentifiers = this.getIdentifiers(() => {
+ this.scan(ast.test);
+ });
+
+ this.scan(ast.update);
+ this.newContext(() => {
+ this.scan(ast.body);
+ });
+ });
+
+ if (testIdentifiers) {
+ for (const p in context) {
+ if (p === '@contextType') continue;
+ if (testIdentifiers.indexOf(p) > -1) {
+ context[p].inForLoopTest = true;
+ }
+ }
+ }
+ break;
+ }
+ case 'DoWhileStatement':
+ case 'WhileStatement':
+ this.newContext(() => {
+ this.scan(ast.body);
+ this.scan(ast.test);
+ });
+ break;
+ case 'Identifier': {
+ if (this.isState(states.trackIdentifiers)) {
+ this.trackedIdentifiers.push(ast.name);
+ }
+ this.identifiers.push({
+ context: this.currentContext,
+ declaration: this.getDeclaration(ast.name),
+ ast,
+ });
+ break;
+ }
+ case 'ReturnStatement':
+ this.returnStatements.push(ast);
+ this.scan(ast.argument);
+ break;
+ case 'MemberExpression':
+ this.pushState(states.memberExpression);
+ this.scan(ast.object);
+ this.scan(ast.property);
+ this.popState(states.memberExpression);
+ break;
+ case 'ExpressionStatement':
+ this.scan(ast.expression);
+ break;
+ case 'SequenceExpression':
+ this.scan(ast.expressions);
+ break;
+ case 'CallExpression':
+ this.functionCalls.push({
+ context: this.currentContext,
+ ast,
+ });
+ this.scan(ast.arguments);
+ break;
+ case 'ArrayExpression':
+ this.scan(ast.elements);
+ break;
+ case 'ConditionalExpression':
+ this.scan(ast.test);
+ this.scan(ast.alternate);
+ this.scan(ast.consequent);
+ break;
+ case 'SwitchStatement':
+ this.scan(ast.discriminant);
+ this.scan(ast.cases);
+ break;
+ case 'SwitchCase':
+ this.scan(ast.test);
+ this.scan(ast.consequent);
+ break;
+
+ case 'ThisExpression':
+ case 'Literal':
+ case 'DebuggerStatement':
+ case 'EmptyStatement':
+ case 'BreakStatement':
+ case 'ContinueStatement':
+ break;
+ default:
+ throw new Error(`unhandled type "${ast.type}"`);
+ }
+ }
+}
+
+module.exports = {
+ FunctionTracer,
+};
+},{"../utils":114}],12:[function(require,module,exports){
+const { glWiretap } = require('gl-wiretap');
+const { utils } = require('../../utils');
+
+function toStringWithoutUtils(fn) {
+ return fn.toString()
+ .replace('=>', '')
+ .replace(/^function /, '')
+ .replace(/utils[.]/g, '/*utils.*/');
+}
+
+function glKernelString(Kernel, args, originKernel, setupContextString, destroyContextString) {
+ if (!originKernel.built) {
+ originKernel.build.apply(originKernel, args);
+ }
+ args = args ? Array.from(args).map(arg => {
+ switch (typeof arg) {
+ case 'boolean':
+ return new Boolean(arg);
+ case 'number':
+ return new Number(arg);
+ default:
+ return arg;
+ }
+ }) : null;
+ const uploadedValues = [];
+ const postResult = [];
+ const context = glWiretap(originKernel.context, {
+ useTrackablePrimitives: true,
+ onReadPixels: (targetName) => {
+ if (kernel.subKernels) {
+ if (!subKernelsResultVariableSetup) {
+ postResult.push(` const result = { result: ${getRenderString(targetName, kernel)} };`);
+ subKernelsResultVariableSetup = true;
+ } else {
+ const property = kernel.subKernels[subKernelsResultIndex++].property;
+ postResult.push(` result${isNaN(property) ? '.' + property : `[${property}]`} = ${getRenderString(targetName, kernel)};`);
+ }
+ if (subKernelsResultIndex === kernel.subKernels.length) {
+ postResult.push(' return result;');
+ }
+ return;
+ }
+ if (targetName) {
+ postResult.push(` return ${getRenderString(targetName, kernel)};`);
+ } else {
+ postResult.push(` return null;`);
+ }
+ },
+ onUnrecognizedArgumentLookup: (argument) => {
+ const argumentName = findKernelValue(argument, kernel.kernelArguments, [], context, uploadedValues);
+ if (argumentName) {
+ return argumentName;
+ }
+ const constantName = findKernelValue(argument, kernel.kernelConstants, constants ? Object.keys(constants).map(key => constants[key]) : [], context, uploadedValues);
+ if (constantName) {
+ return constantName;
+ }
+ return null;
+ }
+ });
+ let subKernelsResultVariableSetup = false;
+ let subKernelsResultIndex = 0;
+ const {
+ source,
+ canvas,
+ output,
+ pipeline,
+ graphical,
+ loopMaxIterations,
+ constants,
+ optimizeFloatMemory,
+ precision,
+ fixIntegerDivisionAccuracy,
+ functions,
+ nativeFunctions,
+ subKernels,
+ immutable,
+ argumentTypes,
+ constantTypes,
+ kernelArguments,
+ kernelConstants,
+ tactic,
+ } = originKernel;
+ const kernel = new Kernel(source, {
+ canvas,
+ context,
+ checkContext: false,
+ output,
+ pipeline,
+ graphical,
+ loopMaxIterations,
+ constants,
+ optimizeFloatMemory,
+ precision,
+ fixIntegerDivisionAccuracy,
+ functions,
+ nativeFunctions,
+ subKernels,
+ immutable,
+ argumentTypes,
+ constantTypes,
+ tactic,
+ });
+ let result = [];
+ context.setIndent(2);
+ kernel.build.apply(kernel, args);
+ result.push(context.toString());
+ context.reset();
+
+ kernel.kernelArguments.forEach((kernelArgument, i) => {
+ switch (kernelArgument.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':
+ context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue);
+ break;
+ case 'HTMLImageArray':
+ for (let imageIndex = 0; imageIndex < args[i].length; imageIndex++) {
+ const arg = args[i];
+ context.insertVariable(`uploadValue_${kernelArgument.name}[${imageIndex}]`, arg[imageIndex]);
+ }
+ break;
+ case 'Input':
+ context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue);
+ break;
+ case 'MemoryOptimizedNumberTexture':
+ case 'NumberTexture':
+ case 'Array1D(2)':
+ case 'Array1D(3)':
+ case 'Array1D(4)':
+ case 'Array2D(2)':
+ case 'Array2D(3)':
+ case 'Array2D(4)':
+ case 'Array3D(2)':
+ case 'Array3D(3)':
+ case 'Array3D(4)':
+ case 'ArrayTexture(1)':
+ case 'ArrayTexture(2)':
+ case 'ArrayTexture(3)':
+ case 'ArrayTexture(4)':
+ context.insertVariable(`uploadValue_${kernelArgument.name}`, args[i].texture);
+ break;
+ default:
+ throw new Error(`unhandled kernelArgumentType insertion for glWiretap of type ${kernelArgument.type}`);
+ }
+ });
+ result.push('/** start of injected functions **/');
+ result.push(`function ${toStringWithoutUtils(utils.flattenTo)}`);
+ result.push(`function ${toStringWithoutUtils(utils.flatten2dArrayTo)}`);
+ result.push(`function ${toStringWithoutUtils(utils.flatten3dArrayTo)}`);
+ result.push(`function ${toStringWithoutUtils(utils.flatten4dArrayTo)}`);
+ result.push(`function ${toStringWithoutUtils(utils.isArray)}`);
+ if (kernel.renderOutput !== kernel.renderTexture && kernel.formatValues) {
+ result.push(
+ ` const renderOutput = function ${toStringWithoutUtils(kernel.formatValues)};`
+ );
+ }
+ result.push('/** end of injected functions **/');
+ result.push(` const innerKernel = function (${kernel.kernelArguments.map(kernelArgument => kernelArgument.varName).join(', ')}) {`);
+ context.setIndent(4);
+ kernel.run.apply(kernel, args);
+ if (kernel.renderKernels) {
+ kernel.renderKernels();
+ } else if (kernel.renderOutput) {
+ kernel.renderOutput();
+ }
+ result.push(' /** start setup uploads for kernel values **/');
+ kernel.kernelArguments.forEach(kernelArgument => {
+ result.push(' ' + kernelArgument.getStringValueHandler().split('\n').join('\n '));
+ });
+ result.push(' /** end setup uploads for kernel values **/');
+ result.push(context.toString());
+ if (kernel.renderOutput === kernel.renderTexture) {
+ context.reset();
+ const framebufferName = context.getContextVariableName(kernel.framebuffer);
+ if (kernel.renderKernels) {
+ const results = kernel.renderKernels();
+ const textureName = context.getContextVariableName(kernel.texture.texture);
+ result.push(` return {
+ result: {
+ texture: ${ textureName },
+ type: '${ results.result.type }',
+ toArray: ${ getToArrayString(results.result, textureName, framebufferName) }
+ },`);
+ const { subKernels, mappedTextures } = kernel;
+ for (let i = 0; i < subKernels.length; i++) {
+ const texture = mappedTextures[i];
+ const subKernel = subKernels[i];
+ const subKernelResult = results[subKernel.property];
+ const subKernelTextureName = context.getContextVariableName(texture.texture);
+ result.push(`
+ ${subKernel.property}: {
+ texture: ${ subKernelTextureName },
+ type: '${ subKernelResult.type }',
+ toArray: ${ getToArrayString(subKernelResult, subKernelTextureName, framebufferName) }
+ },`);
+ }
+ result.push(` };`);
+ } else {
+ const rendered = kernel.renderOutput();
+ const textureName = context.getContextVariableName(kernel.texture.texture);
+ result.push(` return {
+ texture: ${ textureName },
+ type: '${ rendered.type }',
+ toArray: ${ getToArrayString(rendered, textureName, framebufferName) }
+ };`);
+ }
+ }
+ result.push(` ${destroyContextString ? '\n' + destroyContextString + ' ': ''}`);
+ result.push(postResult.join('\n'));
+ result.push(' };');
+ if (kernel.graphical) {
+ result.push(getGetPixelsString(kernel));
+ result.push(` innerKernel.getPixels = getPixels;`);
+ }
+ result.push(' return innerKernel;');
+
+ let constantsUpload = [];
+ kernelConstants.forEach((kernelConstant) => {
+ constantsUpload.push(`${kernelConstant.getStringValueHandler()}`);
+ });
+ return `function kernel(settings) {
+ const { context, constants } = settings;
+ ${constantsUpload.join('')}
+ ${setupContextString ? setupContextString : ''}
+${result.join('\n')}
+}`;
+}
+
+function getRenderString(targetName, kernel) {
+ const readBackValue = kernel.precision === 'single' ? targetName : `new Float32Array(${targetName}.buffer)`;
+ if (kernel.output[2]) {
+ return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]}, ${kernel.output[2]})`;
+ }
+ if (kernel.output[1]) {
+ return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]})`;
+ }
+
+ return `renderOutput(${readBackValue}, ${kernel.output[0]})`;
+}
+
+function getGetPixelsString(kernel) {
+ const getPixels = kernel.getPixels.toString();
+ const useFunctionKeyword = !/^function/.test(getPixels);
+ return utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ getPixels }`, {
+ findDependency: (object, name) => {
+ if (object === 'utils') {
+ return `const ${name} = ${utils[name].toString()};`;
+ }
+ return null;
+ },
+ thisLookup: (property) => {
+ if (property === 'context') {
+ return null;
+ }
+ if (kernel.hasOwnProperty(property)) {
+ return JSON.stringify(kernel[property]);
+ }
+ throw new Error(`unhandled thisLookup ${ property }`);
+ }
+ });
+}
+
+function getToArrayString(kernelResult, textureName, framebufferName) {
+ const toArray = kernelResult.toArray.toString();
+ const useFunctionKeyword = !/^function/.test(toArray);
+ const flattenedFunctions = utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ toArray }`, {
+ findDependency: (object, name) => {
+ if (object === 'utils') {
+ return `const ${name} = ${utils[name].toString()};`;
+ } else if (object === 'this') {
+ if (name === 'framebuffer') {
+ return '';
+ }
+ return `${useFunctionKeyword ? 'function ' : ''}${kernelResult[name].toString()}`;
+ } else {
+ throw new Error('unhandled fromObject');
+ }
+ },
+ thisLookup: (property, isDeclaration) => {
+ if (property === 'texture') {
+ return textureName;
+ }
+ if (property === 'context') {
+ if (isDeclaration) return null;
+ return 'gl';
+ }
+ if (kernelResult.hasOwnProperty(property)) {
+ return JSON.stringify(kernelResult[property]);
+ }
+ throw new Error(`unhandled thisLookup ${ property }`);
+ }
+ });
+ return `() => {
+ function framebuffer() { return ${framebufferName}; };
+ ${flattenedFunctions}
+ return toArray();
+ }`;
+}
+
+function findKernelValue(argument, kernelValues, values, context, uploadedValues) {
+ if (argument === null) return null;
+ if (kernelValues === null) return null;
+ switch (typeof argument) {
+ case 'boolean':
+ case 'number':
+ return null;
+ }
+ if (
+ typeof HTMLImageElement !== 'undefined' &&
+ argument instanceof HTMLImageElement
+ ) {
+ for (let i = 0; i < kernelValues.length; i++) {
+ const kernelValue = kernelValues[i];
+ if (kernelValue.type !== 'HTMLImageArray' && kernelValue) continue;
+ if (kernelValue.uploadValue !== argument) continue;
+ const variableIndex = values[i].indexOf(argument);
+ if (variableIndex === -1) continue;
+ const variableName = `uploadValue_${kernelValue.name}[${variableIndex}]`;
+ context.insertVariable(variableName, argument);
+ return variableName;
+ }
+ }
+
+ for (let i = 0; i < kernelValues.length; i++) {
+ const kernelValue = kernelValues[i];
+ if (argument !== kernelValue.uploadValue) continue;
+ const variable = `uploadValue_${kernelValue.name}`;
+ context.insertVariable(variable, kernelValue);
+ return variable;
+ }
+ return null;
+}
+
+module.exports = {
+ glKernelString
+};
+},{"../../utils":114,"gl-wiretap":3}],13:[function(require,module,exports){
+const { Kernel } = require('../kernel');
+const { utils } = require('../../utils');
+const { GLTextureArray2Float } = require('./texture/array-2-float');
+const { GLTextureArray2Float2D } = require('./texture/array-2-float-2d');
+const { GLTextureArray2Float3D } = require('./texture/array-2-float-3d');
+const { GLTextureArray3Float } = require('./texture/array-3-float');
+const { GLTextureArray3Float2D } = require('./texture/array-3-float-2d');
+const { GLTextureArray3Float3D } = require('./texture/array-3-float-3d');
+const { GLTextureArray4Float } = require('./texture/array-4-float');
+const { GLTextureArray4Float2D } = require('./texture/array-4-float-2d');
+const { GLTextureArray4Float3D } = require('./texture/array-4-float-3d');
+const { GLTextureFloat } = require('./texture/float');
+const { GLTextureFloat2D } = require('./texture/float-2d');
+const { GLTextureFloat3D } = require('./texture/float-3d');
+const { GLTextureMemoryOptimized } = require('./texture/memory-optimized');
+const { GLTextureMemoryOptimized2D } = require('./texture/memory-optimized-2d');
+const { GLTextureMemoryOptimized3D } = require('./texture/memory-optimized-3d');
+const { GLTextureUnsigned } = require('./texture/unsigned');
+const { GLTextureUnsigned2D } = require('./texture/unsigned-2d');
+const { GLTextureUnsigned3D } = require('./texture/unsigned-3d');
+const { GLTextureGraphical } = require('./texture/graphical');
+
+class GLKernel extends Kernel {
+ static get mode() {
+ return 'gpu';
+ }
+
+ static getIsFloatRead() {
+ const kernelString = `function kernelFunction() {
+ return 1;
+ }`;
+ const kernel = new this(kernelString, {
+ context: this.testContext,
+ canvas: this.testCanvas,
+ validate: false,
+ output: [1],
+ precision: 'single',
+ returnType: 'Number',
+ tactic: 'speed',
+ });
+ kernel.build();
+ kernel.run();
+ const result = kernel.renderOutput();
+ kernel.destroy(true);
+ return result[0] === 1;
+ }
+
+ static getIsIntegerDivisionAccurate() {
+ function kernelFunction(v1, v2) {
+ return v1[this.thread.x] / v2[this.thread.x];
+ }
+ const kernel = new this(kernelFunction.toString(), {
+ context: this.testContext,
+ canvas: this.testCanvas,
+ validate: false,
+ output: [2],
+ returnType: 'Number',
+ precision: 'unsigned',
+ tactic: 'speed',
+ });
+ const args = [
+ [6, 6030401],
+ [3, 3991]
+ ];
+ kernel.build.apply(kernel, args);
+ kernel.run.apply(kernel, args);
+ const result = kernel.renderOutput();
+ kernel.destroy(true);
+ return result[0] === 2 && result[1] === 1511;
+ }
+
+ static getIsSpeedTacticSupported() {
+ function kernelFunction(value) {
+ return value[this.thread.x];
+ }
+ const kernel = new this(kernelFunction.toString(), {
+ context: this.testContext,
+ canvas: this.testCanvas,
+ validate: false,
+ output: [4],
+ returnType: 'Number',
+ precision: 'unsigned',
+ tactic: 'speed',
+ });
+ const args = [
+ [0, 1, 2, 3]
+ ];
+ kernel.build.apply(kernel, args);
+ kernel.run.apply(kernel, args);
+ const result = kernel.renderOutput();
+ kernel.destroy(true);
+ return Math.round(result[0]) === 0 && Math.round(result[1]) === 1 && Math.round(result[2]) === 2 && Math.round(result[3]) === 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 gl = this.testContext;
+ const isDrawBuffers = this.getIsDrawBuffers();
+ return Object.freeze({
+ isFloatRead: this.getIsFloatRead(),
+ isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(),
+ isSpeedTacticSupported: this.getIsSpeedTacticSupported(),
+ isTextureFloat: this.getIsTextureFloat(),
+ isDrawBuffers,
+ kernelMap: isDrawBuffers,
+ channelCount: this.getChannelCount(),
+ maxTextureSize: this.getMaxTextureSize(),
+ lowIntPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_INT),
+ lowFloatPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_FLOAT),
+ mediumIntPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_INT),
+ mediumFloatPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT),
+ highIntPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_INT),
+ highFloatPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT),
+ });
+ }
+
+ static setupFeatureChecks() {
+ throw new Error(`"setupFeatureChecks" not defined on ${ this.name }`);
+ }
+
+ static getSignature(kernel, argumentTypes) {
+ return kernel.getVariablePrecisionString() + (argumentTypes.length > 0 ? ':' + argumentTypes.join(',') : '');
+ }
+
+ setFixIntegerDivisionAccuracy(fix) {
+ this.fixIntegerDivisionAccuracy = fix;
+ return this;
+ }
+
+ setPrecision(flag) {
+ this.precision = flag;
+ return this;
+ }
+
+ setFloatTextures(flag) {
+ utils.warnDeprecated('method', 'setFloatTextures', 'setOptimizeFloatMemory');
+ this.floatTextures = flag;
+ return this;
+ }
+
+ static nativeFunctionArguments(source) {
+ const argumentTypes = [];
+ const argumentNames = [];
+ const states = [];
+ const isStartingVariableName = /^[a-zA-Z_]/;
+ const isVariableChar = /[a-zA-Z_0-9]/;
+ let i = 0;
+ let argumentName = null;
+ let argumentType = null;
+ while (i < source.length) {
+ const char = source[i];
+ const nextChar = source[i + 1];
+ const state = states.length > 0 ? states[states.length - 1] : null;
+
+ if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '*') {
+ states.push('MULTI_LINE_COMMENT');
+ i += 2;
+ continue;
+ } else if (state === 'MULTI_LINE_COMMENT' && char === '*' && nextChar === '/') {
+ states.pop();
+ i += 2;
+ continue;
+ }
+
+ else if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '/') {
+ states.push('COMMENT');
+ i += 2;
+ continue;
+ } else if (state === 'COMMENT' && char === '\n') {
+ states.pop();
+ i++;
+ continue;
+ }
+
+ else if (state === null && char === '(') {
+ states.push('FUNCTION_ARGUMENTS');
+ i++;
+ continue;
+ } else if (state === 'FUNCTION_ARGUMENTS') {
+ if (char === ')') {
+ states.pop();
+ break;
+ }
+ if (char === 'f' && nextChar === 'l' && source[i + 2] === 'o' && source[i + 3] === 'a' && source[i + 4] === 't' && source[i + 5] === ' ') {
+ states.push('DECLARE_VARIABLE');
+ argumentType = 'float';
+ argumentName = '';
+ i += 6;
+ continue;
+ } else if (char === 'i' && nextChar === 'n' && source[i + 2] === 't' && source[i + 3] === ' ') {
+ states.push('DECLARE_VARIABLE');
+ argumentType = 'int';
+ argumentName = '';
+ i += 4;
+ continue;
+ } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '2' && source[i + 4] === ' ') {
+ states.push('DECLARE_VARIABLE');
+ argumentType = 'vec2';
+ argumentName = '';
+ i += 5;
+ continue;
+ } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '3' && source[i + 4] === ' ') {
+ states.push('DECLARE_VARIABLE');
+ argumentType = 'vec3';
+ argumentName = '';
+ i += 5;
+ continue;
+ } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '4' && source[i + 4] === ' ') {
+ states.push('DECLARE_VARIABLE');
+ argumentType = 'vec4';
+ argumentName = '';
+ i += 5;
+ continue;
+ }
+ }
+
+ else if (state === 'DECLARE_VARIABLE') {
+ if (argumentName === '') {
+ if (char === ' ') {
+ i++;
+ continue;
+ }
+ if (!isStartingVariableName.test(char)) {
+ throw new Error('variable name is not expected string');
+ }
+ }
+ argumentName += char;
+ if (!isVariableChar.test(nextChar)) {
+ states.pop();
+ argumentNames.push(argumentName);
+ argumentTypes.push(typeMap[argumentType]);
+ }
+ }
+
+ i++;
+ }
+ if (states.length > 0) {
+ throw new Error('GLSL function was not parsable');
+ }
+ return {
+ argumentNames,
+ argumentTypes,
+ };
+ }
+
+ static nativeFunctionReturnType(source) {
+ return typeMap[source.match(/int|float|vec[2-4]/)[0]];
+ }
+
+ static combineKernels(combinedKernel, lastKernel) {
+ combinedKernel.apply(null, arguments);
+ const {
+ texSize,
+ context,
+ threadDim
+ } = lastKernel.texSize;
+ let result;
+ if (lastKernel.precision === 'single') {
+ const w = texSize[0];
+ const h = Math.ceil(texSize[1] / 4);
+ result = new Float32Array(w * h * 4 * 4);
+ context.readPixels(0, 0, w, h * 4, context.RGBA, context.FLOAT, result);
+ } else {
+ const bytes = new Uint8Array(texSize[0] * texSize[1] * 4);
+ context.readPixels(0, 0, texSize[0], texSize[1], context.RGBA, context.UNSIGNED_BYTE, bytes);
+ result = new Float32Array(bytes.buffer);
+ }
+
+ result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]);
+
+ if (lastKernel.output.length === 1) {
+ return result;
+ } else if (lastKernel.output.length === 2) {
+ return utils.splitArray(result, lastKernel.output[0]);
+ } else if (lastKernel.output.length === 3) {
+ const cube = utils.splitArray(result, lastKernel.output[0] * lastKernel.output[1]);
+ return cube.map(function(x) {
+ return utils.splitArray(x, lastKernel.output[0]);
+ });
+ }
+ }
+
+ constructor(source, settings) {
+ super(source, settings);
+ 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 } = this.constructor;
+ if (this.texSize[0] > features.maxTextureSize || this.texSize[1] > features.maxTextureSize) {
+ throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${features.maxTextureSize},${features.maxTextureSize}]`);
+ }
+ }
+
+ translateSource() {
+ throw new Error(`"translateSource" not defined on ${this.constructor.name}`);
+ }
+
+ pickRenderStrategy(args) {
+ if (this.graphical) {
+ this.renderRawOutput = this.readPackedPixelsToUint8Array;
+ this.transferValues = (pixels) => pixels;
+ this.TextureConstructor = GLTextureGraphical;
+ return null;
+ }
+ if (this.precision === 'unsigned') {
+ this.renderRawOutput = this.readPackedPixelsToUint8Array;
+ this.transferValues = this.readPackedPixelsToFloat32Array;
+ if (this.pipeline) {
+ this.renderOutput = this.renderTexture;
+ if (this.subKernels !== null) {
+ this.renderKernels = this.renderKernelsToTextures;
+ }
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Float':
+ case 'Number':
+ case 'Integer':
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureUnsigned3D;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureUnsigned2D;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureUnsigned;
+ return null;
+ }
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ return this.requestFallback(args);
+ }
+ } else {
+ if (this.subKernels !== null) {
+ this.renderKernels = this.renderKernelsToArrays;
+ }
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Float':
+ case 'Number':
+ case 'Integer':
+ this.renderOutput = this.renderValues;
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureUnsigned3D;
+ this.formatValues = utils.erect3DPackedFloat;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureUnsigned2D;
+ this.formatValues = utils.erect2DPackedFloat;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureUnsigned;
+ this.formatValues = utils.erectPackedFloat;
+ return null;
+ }
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ return this.requestFallback(args);
+ }
+ }
+ } else if (this.precision === 'single') {
+ this.renderRawOutput = this.readFloatPixelsToFloat32Array;
+ this.transferValues = this.readFloatPixelsToFloat32Array;
+ if (this.pipeline) {
+ this.renderOutput = this.renderTexture;
+ if (this.subKernels !== null) {
+ this.renderKernels = this.renderKernelsToTextures;
+ }
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Float':
+ case 'Number':
+ case 'Integer': {
+ if (this.optimizeFloatMemory) {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureMemoryOptimized3D;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureMemoryOptimized2D;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureMemoryOptimized;
+ return null;
+ }
+ } else {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureFloat3D;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureFloat2D;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureFloat;
+ return null;
+ }
+ }
+ }
+ case 'Array(2)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray2Float3D;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray2Float2D;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray2Float;
+ return null;
+ }
+ }
+ case 'Array(3)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray3Float3D;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray3Float2D;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray3Float;
+ return null;
+ }
+ }
+ case 'Array(4)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray4Float3D;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray4Float2D;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray4Float;
+ return null;
+ }
+ }
+ }
+ }
+ this.renderOutput = this.renderValues;
+ if (this.subKernels !== null) {
+ this.renderKernels = this.renderKernelsToArrays;
+ }
+ if (this.optimizeFloatMemory) {
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Float':
+ case 'Number':
+ case 'Integer': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureMemoryOptimized3D;
+ this.formatValues = utils.erectMemoryOptimized3DFloat;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureMemoryOptimized2D;
+ this.formatValues = utils.erectMemoryOptimized2DFloat;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureMemoryOptimized;
+ this.formatValues = utils.erectMemoryOptimizedFloat;
+ return null;
+ }
+ }
+ case 'Array(2)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray2Float3D;
+ this.formatValues = utils.erect3DArray2;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray2Float2D;
+ this.formatValues = utils.erect2DArray2;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray2Float;
+ this.formatValues = utils.erectArray2;
+ return null;
+ }
+ }
+ case 'Array(3)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray3Float3D;
+ this.formatValues = utils.erect3DArray3;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray3Float2D;
+ this.formatValues = utils.erect2DArray3;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray3Float;
+ this.formatValues = utils.erectArray3;
+ return null;
+ }
+ }
+ case 'Array(4)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray4Float3D;
+ this.formatValues = utils.erect3DArray4;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray4Float2D;
+ this.formatValues = utils.erect2DArray4;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray4Float;
+ this.formatValues = utils.erectArray4;
+ return null;
+ }
+ }
+ }
+ } else {
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Float':
+ case 'Number':
+ case 'Integer': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureFloat3D;
+ this.formatValues = utils.erect3DFloat;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureFloat2D;
+ this.formatValues = utils.erect2DFloat;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureFloat;
+ this.formatValues = utils.erectFloat;
+ return null;
+ }
+ }
+ case 'Array(2)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray2Float3D;
+ this.formatValues = utils.erect3DArray2;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray2Float2D;
+ this.formatValues = utils.erect2DArray2;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray2Float;
+ this.formatValues = utils.erectArray2;
+ return null;
+ }
+ }
+ case 'Array(3)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray3Float3D;
+ this.formatValues = utils.erect3DArray3;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray3Float2D;
+ this.formatValues = utils.erect2DArray3;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray3Float;
+ this.formatValues = utils.erectArray3;
+ return null;
+ }
+ }
+ case 'Array(4)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray4Float3D;
+ this.formatValues = utils.erect3DArray4;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray4Float2D;
+ this.formatValues = utils.erect2DArray4;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray4Float;
+ this.formatValues = utils.erectArray4;
+ return null;
+ }
+ }
+ }
+ }
+ } else {
+ throw new Error(`unhandled precision of "${this.precision}"`);
+ }
+
+ 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() {
+ if (this.graphical) {
+ return this.getMainResultGraphical();
+ } else if (this.precision === 'single') {
+ if (this.optimizeFloatMemory) {
+ return this.getMainResultMemoryOptimizedFloats();
+ }
+ return this.getMainResultTexture();
+ } else {
+ return this.getMainResultPackedPixels();
+ }
+ }
+
+ getMainResultNumberTexture() {
+ return utils.linesToString(this.getMainResultKernelNumberTexture()) +
+ utils.linesToString(this.getMainResultSubKernelNumberTexture());
+ }
+
+ getMainResultArray2Texture() {
+ return utils.linesToString(this.getMainResultKernelArray2Texture()) +
+ utils.linesToString(this.getMainResultSubKernelArray2Texture());
+ }
+
+ getMainResultArray3Texture() {
+ return utils.linesToString(this.getMainResultKernelArray3Texture()) +
+ utils.linesToString(this.getMainResultSubKernelArray3Texture());
+ }
+
+ getMainResultArray4Texture() {
+ return utils.linesToString(this.getMainResultKernelArray4Texture()) +
+ utils.linesToString(this.getMainResultSubKernelArray4Texture());
+ }
+
+ getFloatTacticDeclaration() {
+ const variablePrecision = this.getVariablePrecisionString(this.texSize, this.tactic);
+ return `precision ${variablePrecision} float;\n`;
+ }
+
+ getIntTacticDeclaration() {
+ return `precision ${this.getVariablePrecisionString(this.texSize, this.tactic, true)} 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 (this.precision !== 'unsigned') throw new Error('Requires this.precision to be "unsigned"');
+ const {
+ texSize,
+ context: gl
+ } = this;
+ const result = new Uint8Array(texSize[0] * texSize[1] * 4);
+ gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, result);
+ return result;
+ }
+
+ readPackedPixelsToFloat32Array() {
+ return new Float32Array(this.readPackedPixelsToUint8Array().buffer);
+ }
+
+ readFloatPixelsToFloat32Array() {
+ if (this.precision !== 'single') throw new Error('Requires this.precision to be "single"');
+ const {
+ texSize,
+ context: gl
+ } = this;
+ const w = texSize[0];
+ const h = texSize[1];
+ const result = new Float32Array(w * h * 4);
+ gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result);
+ return result;
+ }
+
+ getPixels(flip) {
+ const {
+ context: gl,
+ output
+ } = this;
+ const [width, height] = output;
+ const pixels = new Uint8Array(width * height * 4);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+ return new Uint8ClampedArray((flip ? pixels : utils.flipPixels(pixels, width, height)).buffer);
+ }
+
+ renderKernelsToArrays() {
+ const result = {
+ result: this.renderOutput(),
+ };
+ for (let i = 0; i < this.subKernels.length; i++) {
+ result[this.subKernels[i].property] = this.mappedTextures[i].toArray();
+ }
+ return result;
+ }
+
+ renderKernelsToTextures() {
+ const result = {
+ result: this.renderOutput(),
+ };
+ 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) {
+ if (!this.dynamicOutput) {
+ throw new Error('Resizing a kernel with dynamicOutput: false is not possible');
+ }
+ const newThreadDim = [newOutput[0], newOutput[1] || 1, newOutput[2] || 1];
+ const newTexSize = utils.getKernelTextureSize({
+ optimizeFloatMemory: this.optimizeFloatMemory,
+ precision: this.precision,
+ }, newThreadDim);
+ const oldTexSize = this.texSize;
+ if (oldTexSize) {
+ const oldPrecision = this.getVariablePrecisionString(oldTexSize, this.tactic);
+ const newPrecision = this.getVariablePrecisionString(newTexSize, this.tactic);
+ if (oldPrecision !== newPrecision) {
+ if (this.debug) {
+ console.warn('Precision requirement changed, asking GPU instance to recompile');
+ }
+ this.switchKernels({
+ type: 'outputPrecisionMismatch',
+ precision: newPrecision,
+ needed: output
+ });
+ return;
+ }
+ }
+ this.output = newOutput;
+ this.threadDim = newThreadDim;
+ this.texSize = newTexSize;
+ const { context: gl } = this;
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
+ this.updateMaxTexSize();
+ this.framebuffer.width = this.texSize[0];
+ this.framebuffer.height = this.texSize[1];
+ gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);
+ this.canvas.width = this.maxTexSize[0];
+ this.canvas.height = this.maxTexSize[1];
+ if (this.texture) {
+ this.texture.delete();
+ }
+ this.texture = null;
+ this._setupOutputTexture();
+ if (this.mappedTextures && this.mappedTextures.length > 0) {
+ for (let i = 0; i < this.mappedTextures.length; i++) {
+ this.mappedTextures[i].delete();
+ }
+ this.mappedTextures = null;
+ this._setupSubOutputTextures();
+ }
+ } else {
+ this.output = newOutput;
+ }
+ return this;
+ }
+ 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';
+ const low = this.constructor.features[isInt ? 'lowIntPrecision' : 'lowFloatPrecision'];
+ const medium = this.constructor.features[isInt ? 'mediumIntPrecision' : 'mediumFloatPrecision'];
+ const high = this.constructor.features[isInt ? 'highIntPrecision' : 'highFloatPrecision'];
+ const requiredSize = Math.log2(textureSize[0] * textureSize[1]);
+ if (requiredSize <= low.rangeMax) {
+ return 'lowp';
+ } else if (requiredSize <= medium.rangeMax) {
+ return 'mediump';
+ } else if (requiredSize <= high.rangeMax) {
+ return 'highp';
+ } else {
+ throw new Error(`The required size exceeds that of the ability of your system`);
+ }
+ }
+ switch (tactic) {
+ case 'speed':
+ return 'lowp';
+ case 'balanced':
+ return 'mediump';
+ case 'precision':
+ return 'highp';
+ default:
+ throw new Error(`Unknown tactic "${tactic}" use "speed", "balanced", "precision", or empty for auto`);
+ }
+ }
+
+ updateTextureArgumentRefs(kernelValue, arg) {
+ if (!this.immutable) return;
+ if (this.texture.texture === arg.texture) {
+ const { prevArg } = kernelValue;
+ if (prevArg) {
+ if (prevArg.texture._refs === 1) {
+ this.texture.delete();
+ this.texture = prevArg.clone();
+ this._textureSwitched = true;
+ }
+ prevArg.delete();
+ }
+ kernelValue.prevArg = arg.clone();
+ } else if (this.mappedTextures && this.mappedTextures.length > 0) {
+ const { mappedTextures } = this;
+ for (let i = 0; i < mappedTextures.length; i++) {
+ const mappedTexture = mappedTextures[i];
+ if (mappedTexture.texture === arg.texture) {
+ const { prevArg } = kernelValue;
+ if (prevArg) {
+ if (prevArg.texture._refs === 1) {
+ mappedTexture.delete();
+ mappedTextures[i] = prevArg.clone();
+ this._mappedTextureSwitched[i] = true;
+ }
+ prevArg.delete();
+ }
+ kernelValue.prevArg = arg.clone();
+ return;
+ }
+ }
+ }
+ }
+
+ onActivate(previousKernel) {
+ this._textureSwitched = true;
+ this.texture = previousKernel.texture;
+ if (this.mappedTextures) {
+ for (let i = 0; i < this.mappedTextures.length; i++) {
+ this._mappedTextureSwitched[i] = true;
+ }
+ this.mappedTextures = previousKernel.mappedTextures;
+ }
+ }
+
+ initCanvas() {}
+}
+
+const typeMap = {
+ int: 'Integer',
+ float: 'Number',
+ vec2: 'Array(2)',
+ vec3: 'Array(3)',
+ vec4: 'Array(4)',
+};
+
+module.exports = {
+ GLKernel
+};
+},{"../../utils":114,"../kernel":36,"./texture/array-2-float":16,"./texture/array-2-float-2d":14,"./texture/array-2-float-3d":15,"./texture/array-3-float":19,"./texture/array-3-float-2d":17,"./texture/array-3-float-3d":18,"./texture/array-4-float":22,"./texture/array-4-float-2d":20,"./texture/array-4-float-3d":21,"./texture/float":25,"./texture/float-2d":23,"./texture/float-3d":24,"./texture/graphical":26,"./texture/memory-optimized":30,"./texture/memory-optimized-2d":28,"./texture/memory-optimized-3d":29,"./texture/unsigned":33,"./texture/unsigned-2d":31,"./texture/unsigned-3d":32}],14:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray2Float2D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(2)';
+ }
+ toArray() {
+ return utils.erect2DArray2(this.renderValues(), this.output[0], this.output[1]);
+ }
+}
+
+module.exports = {
+ GLTextureArray2Float2D
+};
+},{"../../../utils":114,"./float":25}],15:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray2Float3D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(2)';
+ }
+ toArray() {
+ return utils.erect3DArray2(this.renderValues(), this.output[0], this.output[1], this.output[2]);
+ }
+}
+
+module.exports = {
+ GLTextureArray2Float3D
+};
+},{"../../../utils":114,"./float":25}],16:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray2Float extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(2)';
+ }
+ toArray() {
+ return utils.erectArray2(this.renderValues(), this.output[0], this.output[1]);
+ }
+}
+
+module.exports = {
+ GLTextureArray2Float
+};
+},{"../../../utils":114,"./float":25}],17:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray3Float2D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(3)';
+ }
+ toArray() {
+ return utils.erect2DArray3(this.renderValues(), this.output[0], this.output[1]);
+ }
+}
+
+module.exports = {
+ GLTextureArray3Float2D
+};
+},{"../../../utils":114,"./float":25}],18:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray3Float3D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(3)';
+ }
+ toArray() {
+ return utils.erect3DArray3(this.renderValues(), this.output[0], this.output[1], this.output[2]);
+ }
+}
+
+module.exports = {
+ GLTextureArray3Float3D
+};
+},{"../../../utils":114,"./float":25}],19:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray3Float extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(3)';
+ }
+ toArray() {
+ return utils.erectArray3(this.renderValues(), this.output[0]);
+ }
+}
+
+module.exports = {
+ GLTextureArray3Float
+};
+},{"../../../utils":114,"./float":25}],20:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray4Float2D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(4)';
+ }
+ toArray() {
+ return utils.erect2DArray4(this.renderValues(), this.output[0], this.output[1]);
+ }
+}
+
+module.exports = {
+ GLTextureArray4Float2D
+};
+},{"../../../utils":114,"./float":25}],21:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray4Float3D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(4)';
+ }
+ toArray() {
+ return utils.erect3DArray4(this.renderValues(), this.output[0], this.output[1], this.output[2]);
+ }
+}
+
+module.exports = {
+ GLTextureArray4Float3D
+};
+},{"../../../utils":114,"./float":25}],22:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray4Float extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(4)';
+ }
+ toArray() {
+ return utils.erectArray4(this.renderValues(), this.output[0]);
+ }
+}
+
+module.exports = {
+ GLTextureArray4Float
+};
+},{"../../../utils":114,"./float":25}],23:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureFloat2D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(1)';
+ }
+ toArray() {
+ return utils.erect2DFloat(this.renderValues(), this.output[0], this.output[1]);
+ }
+}
+
+module.exports = {
+ GLTextureFloat2D
+};
+},{"../../../utils":114,"./float":25}],24:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureFloat3D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(1)';
+ }
+ toArray() {
+ return utils.erect3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]);
+ }
+}
+
+module.exports = {
+ GLTextureFloat3D
+};
+},{"../../../utils":114,"./float":25}],25:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTexture } = require('./index');
+
+class GLTextureFloat extends GLTexture {
+ get textureType() {
+ return this.context.FLOAT;
+ }
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(1)';
+ }
+ renderRawOutput() {
+ const gl = this.context;
+ const size = this.size;
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer());
+ gl.framebufferTexture2D(
+ gl.FRAMEBUFFER,
+ gl.COLOR_ATTACHMENT0,
+ gl.TEXTURE_2D,
+ this.texture,
+ 0
+ );
+ const result = new Float32Array(size[0] * size[1] * 4);
+ gl.readPixels(0, 0, size[0], size[1], gl.RGBA, gl.FLOAT, result);
+ return result;
+ }
+ renderValues() {
+ if (this._deleted) return null;
+ return this.renderRawOutput();
+ }
+ toArray() {
+ return utils.erectFloat(this.renderValues(), this.output[0]);
+ }
+}
+
+module.exports = {
+ GLTextureFloat
+};
+},{"../../../utils":114,"./index":27}],26:[function(require,module,exports){
+const { GLTextureUnsigned } = require('./unsigned');
+
+class GLTextureGraphical extends GLTextureUnsigned {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(4)';
+ }
+ toArray() {
+ return this.renderValues();
+ }
+}
+
+module.exports = {
+ GLTextureGraphical
+};
+},{"./unsigned":33}],27:[function(require,module,exports){
+const { Texture } = require('../../../texture');
+
+class GLTexture extends Texture {
+ get textureType() {
+ throw new Error(`"textureType" not implemented on ${ this.name }`);
+ }
+
+ clone() {
+ return new this.constructor(this);
+ }
+
+ beforeMutate() {
+ if (this.texture._refs > 1) {
+ this.newTexture();
+ return true;
+ }
+ return false;
+ }
+
+ cloneTexture() {
+ this.texture._refs--;
+ const { context: gl, size, texture, kernel } = this;
+ if (kernel.debug) {
+ console.warn('cloning internal texture');
+ }
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer());
+ selectTexture(gl, texture);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ const target = gl.createTexture();
+ selectTexture(gl, target);
+ gl.texImage2D(gl.TEXTURE_2D, 0, this.internalFormat, size[0], size[1], 0, this.textureFormat, this.textureType, null);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, size[0], size[1]);
+ target._refs = 1;
+ this.texture = target;
+ }
+
+ newTexture() {
+ this.texture._refs--;
+ const gl = this.context;
+ const size = this.size;
+ const kernel = this.kernel;
+ if (kernel.debug) {
+ console.warn('new internal texture');
+ }
+ const target = gl.createTexture();
+ selectTexture(gl, target);
+ gl.texImage2D(gl.TEXTURE_2D, 0, this.internalFormat, size[0], size[1], 0, this.textureFormat, this.textureType, null);
+ target._refs = 1;
+ this.texture = target;
+ }
+
+ clear() {
+ if (this.texture._refs) {
+ this.texture._refs--;
+ const gl = this.context;
+ const target = this.texture = gl.createTexture();
+ selectTexture(gl, target);
+ const size = this.size;
+ target._refs = 1;
+ gl.texImage2D(gl.TEXTURE_2D, 0, this.internalFormat, size[0], size[1], 0, this.textureFormat, this.textureType, null);
+ }
+ const { context: gl, texture } = this;
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer());
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ selectTexture(gl, texture);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ gl.clearColor(0, 0, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ }
+
+ delete() {
+ if (this._deleted) return;
+ this._deleted = true;
+ if (this.texture._refs) {
+ this.texture._refs--;
+ if (this.texture._refs) return;
+ }
+ this.context.deleteTexture(this.texture);
+ }
+
+ framebuffer() {
+ if (!this._framebuffer) {
+ this._framebuffer = this.kernel.getRawValueFramebuffer(this.size[0], this.size[1]);
+ }
+ return this._framebuffer;
+ }
+}
+
+function selectTexture(gl, texture) {
+ gl.activeTexture(gl.TEXTURE15);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+}
+
+module.exports = { GLTexture };
+},{"../../../texture":113}],28:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureMemoryOptimized2D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'MemoryOptimizedNumberTexture';
+ }
+ toArray() {
+ return utils.erectMemoryOptimized2DFloat(this.renderValues(), this.output[0], this.output[1]);
+ }
+}
+
+module.exports = {
+ GLTextureMemoryOptimized2D
+};
+},{"../../../utils":114,"./float":25}],29:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureMemoryOptimized3D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'MemoryOptimizedNumberTexture';
+ }
+ toArray() {
+ return utils.erectMemoryOptimized3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]);
+ }
+}
+
+module.exports = {
+ GLTextureMemoryOptimized3D
+};
+},{"../../../utils":114,"./float":25}],30:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureMemoryOptimized extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'MemoryOptimizedNumberTexture';
+ }
+ toArray() {
+ return utils.erectMemoryOptimizedFloat(this.renderValues(), this.output[0]);
+ }
+}
+
+module.exports = {
+ GLTextureMemoryOptimized
+};
+},{"../../../utils":114,"./float":25}],31:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureUnsigned } = require('./unsigned');
+
+class GLTextureUnsigned2D extends GLTextureUnsigned {
+ constructor(settings) {
+ super(settings);
+ this.type = 'NumberTexture';
+ }
+ toArray() {
+ return utils.erect2DPackedFloat(this.renderValues(), this.output[0], this.output[1]);
+ }
+}
+
+module.exports = {
+ GLTextureUnsigned2D
+};
+},{"../../../utils":114,"./unsigned":33}],32:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTextureUnsigned } = require('./unsigned');
+
+class GLTextureUnsigned3D extends GLTextureUnsigned {
+ constructor(settings) {
+ super(settings);
+ this.type = 'NumberTexture';
+ }
+ toArray() {
+ return utils.erect3DPackedFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]);
+ }
+}
+
+module.exports = {
+ GLTextureUnsigned3D
+};
+},{"../../../utils":114,"./unsigned":33}],33:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { GLTexture } = require('./index');
+
+class GLTextureUnsigned extends GLTexture {
+ get textureType() {
+ return this.context.UNSIGNED_BYTE;
+ }
+ constructor(settings) {
+ super(settings);
+ this.type = 'NumberTexture';
+ }
+ renderRawOutput() {
+ const { context: gl } = this;
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer());
+ gl.framebufferTexture2D(
+ gl.FRAMEBUFFER,
+ gl.COLOR_ATTACHMENT0,
+ gl.TEXTURE_2D,
+ this.texture,
+ 0
+ );
+ const result = new Uint8Array(this.size[0] * this.size[1] * 4);
+ gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.UNSIGNED_BYTE, result);
+ return result;
+ }
+ renderValues() {
+ if (this._deleted) return null;
+ return new Float32Array(this.renderRawOutput().buffer);
+ }
+ toArray() {
+ return utils.erectPackedFloat(this.renderValues(), this.output[0]);
+ }
+}
+
+module.exports = {
+ GLTextureUnsigned
+};
+},{"../../../utils":114,"./index":27}],34:[function(require,module,exports){
+const getContext = require('gl');
+const { WebGLKernel } = require('../web-gl/kernel');
+const { glKernelString } = require('../gl/kernel-string');
+
+let isSupported = null;
+let testCanvas = null;
+let testContext = null;
+let testExtensions = null;
+let features = null;
+
+class HeadlessGLKernel extends WebGLKernel {
+ static get isSupported() {
+ if (isSupported !== null) return isSupported;
+ this.setupFeatureChecks();
+ isSupported = testContext !== null;
+ return isSupported;
+ }
+
+ static setupFeatureChecks() {
+ testCanvas = null;
+ testExtensions = null;
+ if (typeof getContext !== 'function') return;
+ try {
+ testContext = getContext(2, 2, {
+ preserveDrawingBuffer: true
+ });
+ if (!testContext || !testContext.getExtension) return;
+ testExtensions = {
+ STACKGL_resize_drawingbuffer: testContext.getExtension('STACKGL_resize_drawingbuffer'),
+ STACKGL_destroy_context: testContext.getExtension('STACKGL_destroy_context'),
+ OES_texture_float: testContext.getExtension('OES_texture_float'),
+ OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'),
+ OES_element_index_uint: testContext.getExtension('OES_element_index_uint'),
+ WEBGL_draw_buffers: testContext.getExtension('WEBGL_draw_buffers'),
+ WEBGL_color_buffer_float: testContext.getExtension('WEBGL_color_buffer_float'),
+ };
+ features = this.getFeatures();
+ } catch (e) {
+ console.warn(e);
+ }
+ }
+
+ static isContextMatch(context) {
+ try {
+ return context.getParameter(context.RENDERER) === 'ANGLE';
+ } catch (e) {
+ return false;
+ }
+ }
+
+ static getIsTextureFloat() {
+ return Boolean(testExtensions.OES_texture_float);
+ }
+
+ static getIsDrawBuffers() {
+ return Boolean(testExtensions.WEBGL_draw_buffers);
+ }
+
+ static getChannelCount() {
+ return testExtensions.WEBGL_draw_buffers ?
+ testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) :
+ 1;
+ }
+
+ static getMaxTextureSize() {
+ return testContext.getParameter(testContext.MAX_TEXTURE_SIZE);
+ }
+
+ static get testCanvas() {
+ return testCanvas;
+ }
+
+ static get testContext() {
+ return testContext;
+ }
+
+ static get features() {
+ return features;
+ }
+
+ initCanvas() {
+ return {};
+ }
+
+ initContext() {
+ return getContext(2, 2, {
+ preserveDrawingBuffer: true
+ });
+ }
+
+ 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);
+ if (!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(context) {
+ const extension = context.getExtension('STACKGL_destroy_context');
+ if (extension && extension.destroy) {
+ extension.destroy();
+ }
+ }
+
+ toString() {
+ const setupContextString = `const gl = context || require('gl')(1, 1);\n`;
+ const destroyContextString = ` if (!context) { gl.getExtension('STACKGL_destroy_context').destroy(); }\n`;
+ return glKernelString(this.constructor, arguments, this, setupContextString, destroyContextString);
+ }
+
+ setOutput(output) {
+ super.setOutput(output);
+ if (this.graphical && this.extensions.STACKGL_resize_drawingbuffer) {
+ this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0], this.maxTexSize[1]);
+ }
+ return this;
+ }
+}
+
+module.exports = {
+ HeadlessGLKernel
+};
+},{"../gl/kernel-string":12,"../web-gl/kernel":70,"gl":2}],35:[function(require,module,exports){
+class KernelValue {
+ constructor(value, settings) {
+ const {
+ name,
+ kernel,
+ context,
+ checkContext,
+ onRequestContextHandle,
+ onUpdateValueMismatch,
+ origin,
+ strictIntegers,
+ type,
+ tactic,
+ } = settings;
+ if (!name) {
+ throw new Error('name not set');
+ }
+ if (!type) {
+ throw new Error('type not set');
+ }
+ if (!origin) {
+ throw new Error('origin not set');
+ }
+ if (origin !== 'user' && origin !== 'constants') {
+ throw new Error(`origin must be "user" or "constants" value is "${ origin }"`);
+ }
+ if (!onRequestContextHandle) {
+ throw new Error('onRequestContextHandle is not set');
+ }
+ this.name = name;
+ this.origin = origin;
+ this.tactic = tactic;
+ this.varName = origin === 'constants' ? `constants.${name}` : name;
+ this.kernel = kernel;
+ this.strictIntegers = strictIntegers;
+ this.type = value.type || type;
+ this.size = value.size || null;
+ this.index = null;
+ this.context = context;
+ this.checkContext = checkContext !== null && checkContext !== undefined ? checkContext : true;
+ this.contextHandle = null;
+ this.onRequestContextHandle = onRequestContextHandle;
+ this.onUpdateValueMismatch = onUpdateValueMismatch;
+ this.forceUploadEachRun = null;
+ }
+
+ get id() {
+ return `${this.origin}_${name}`;
+ }
+
+ getSource() {
+ throw new Error(`"getSource" not defined on ${ this.constructor.name }`);
+ }
+
+ updateValue(value) {
+ throw new Error(`"updateValue" not defined on ${ this.constructor.name }`);
+ }
+}
+
+module.exports = {
+ KernelValue
+};
+},{}],36:[function(require,module,exports){
+const { utils } = require('../utils');
+const { Input } = require('../input');
+
+class Kernel {
+ static get isSupported() {
+ throw new Error(`"isSupported" not implemented on ${ this.name }`);
+ }
+
+ static isContextMatch(context) {
+ throw new Error(`"isContextMatch" not implemented on ${ this.name }`);
+ }
+
+ static getFeatures() {
+ throw new Error(`"getFeatures" not implemented on ${ this.name }`);
+ }
+
+ static destroyContext(context) {
+ 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(source, settings) {
+ if (typeof source !== 'object') {
+ if (typeof source !== 'string') {
+ throw new Error('source not a string');
+ }
+ if (!utils.isFunctionString(source)) {
+ throw new Error('source not a function string');
+ }
+ }
+ this.useLegacyEncoder = false;
+ this.fallbackRequested = false;
+ this.onRequestFallback = null;
+
+ this.argumentNames = typeof source === 'string' ? utils.getArgumentNamesFromString(source) : null;
+ this.argumentTypes = null;
+ this.argumentSizes = null;
+ this.argumentBitRatios = null;
+ this.kernelArguments = null;
+ this.kernelConstants = null;
+ this.forceUploadKernelConstants = null;
+
+
+ this.source = source;
+
+ this.output = null;
+
+ this.debug = false;
+
+ this.graphical = false;
+
+ this.loopMaxIterations = 0;
+
+ this.constants = null;
+
+ this.constantTypes = null;
+
+ this.constantBitRatios = null;
+
+ this.dynamicArguments = false;
+
+ this.dynamicOutput = false;
+
+ 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 = true;
+
+ this.immutable = false;
+
+ this.pipeline = false;
+
+ this.precision = null;
+
+ this.tactic = null;
+
+ this.plugins = null;
+
+ this.returnType = null;
+ this.leadingReturnStatement = null;
+ this.followingReturnStatement = null;
+ this.optimizeFloatMemory = null;
+ this.strictIntegers = false;
+ this.fixIntegerDivisionAccuracy = null;
+ this.built = false;
+ this.signature = null;
+ }
+
+ mergeSettings(settings) {
+ for (let p in settings) {
+ if (!settings.hasOwnProperty(p) || !this.hasOwnProperty(p)) continue;
+ switch (p) {
+ case 'output':
+ if (!Array.isArray(settings.output)) {
+ this.setOutput(settings.output);
+ continue;
+ }
+ break;
+ case 'functions':
+ this.functions = [];
+ for (let i = 0; i < settings.functions.length; i++) {
+ this.addFunction(settings.functions[i]);
+ }
+ continue;
+ case 'graphical':
+ if (settings[p] && !settings.hasOwnProperty('precision')) {
+ this.precision = 'unsigned';
+ }
+ this[p] = settings[p];
+ continue;
+ case 'nativeFunctions':
+ if (!settings.nativeFunctions) continue;
+ this.nativeFunctions = [];
+ for (let i = 0; i < settings.nativeFunctions.length; i++) {
+ const s = settings.nativeFunctions[i];
+ const { name, source } = s;
+ this.addNativeFunction(name, source, s);
+ }
+ continue;
+ }
+ this[p] = settings[p];
+ }
+
+ if (!this.canvas) this.canvas = this.initCanvas();
+ if (!this.context) this.context = this.initContext();
+ if (!this.plugins) this.plugins = this.initPlugins(settings);
+ }
+ build() {
+ throw new Error(`"build" not defined on ${ this.constructor.name }`);
+ }
+
+ run() {
+ throw new Error(`"run" not defined on ${ this.constructor.name }`)
+ }
+
+ initCanvas() {
+ throw new Error(`"initCanvas" not defined on ${ this.constructor.name }`);
+ }
+
+ initContext() {
+ throw new Error(`"initContext" not defined on ${ this.constructor.name }`);
+ }
+
+ initPlugins(settings) {
+ throw new Error(`"initPlugins" not defined on ${ this.constructor.name }`);
+ }
+
+ addFunction(source, settings = {}) {
+ if (source.name && source.source && source.argumentTypes && 'returnType' in source) {
+ this.functions.push(source);
+ } else if ('settings' in source && 'source' in source) {
+ this.functions.push(this.functionToIGPUFunction(source.source, source.settings));
+ } else if (typeof source === 'string' || typeof source === 'function') {
+ this.functions.push(this.functionToIGPUFunction(source, settings));
+ } else {
+ throw new Error(`function not properly defined`);
+ }
+ return this;
+ }
+
+ addNativeFunction(name, source, settings = {}) {
+ const { argumentTypes, argumentNames } = settings.argumentTypes ?
+ splitArgumentTypes(settings.argumentTypes) :
+ this.constructor.nativeFunctionArguments(source) || {};
+ this.nativeFunctions.push({
+ name,
+ source,
+ settings,
+ argumentTypes,
+ argumentNames,
+ returnType: settings.returnType || this.constructor.nativeFunctionReturnType(source)
+ });
+ return this;
+ }
+
+ setupArguments(args) {
+ this.kernelArguments = [];
+ if (!this.argumentTypes) {
+ if (!this.argumentTypes) {
+ this.argumentTypes = [];
+ for (let i = 0; i < args.length; i++) {
+ const argType = utils.getVariableType(args[i], this.strictIntegers);
+ const type = argType === 'Integer' ? 'Number' : argType;
+ this.argumentTypes.push(type);
+ this.kernelArguments.push({
+ type
+ });
+ }
+ }
+ } else {
+ for (let i = 0; i < this.argumentTypes.length; i++) {
+ this.kernelArguments.push({
+ type: this.argumentTypes[i]
+ });
+ }
+ }
+
+ this.argumentSizes = new Array(args.length);
+ this.argumentBitRatios = new Int32Array(args.length);
+
+ for (let i = 0; i < args.length; i++) {
+ const arg = args[i];
+ this.argumentSizes[i] = arg.constructor === Input ? arg.size : null;
+ this.argumentBitRatios[i] = this.getBitRatio(arg);
+ }
+
+ if (this.argumentNames.length !== args.length) {
+ throw new Error(`arguments are miss-aligned`);
+ }
+ }
+
+ setupConstants() {
+ this.kernelConstants = [];
+ let needsConstantTypes = this.constantTypes === null;
+ if (needsConstantTypes) {
+ this.constantTypes = {};
+ }
+ this.constantBitRatios = {};
+ if (this.constants) {
+ for (let name in this.constants) {
+ if (needsConstantTypes) {
+ const type = utils.getVariableType(this.constants[name], this.strictIntegers);
+ this.constantTypes[name] = type;
+ this.kernelConstants.push({
+ name,
+ type
+ });
+ } else {
+ this.kernelConstants.push({
+ name,
+ type: this.constantTypes[name]
+ });
+ }
+ this.constantBitRatios[name] = this.getBitRatio(this.constants[name]);
+ }
+ }
+ }
+
+ setOptimizeFloatMemory(flag) {
+ this.optimizeFloatMemory = flag;
+ return this;
+ }
+
+ toKernelOutput(output) {
+ if (output.hasOwnProperty('x')) {
+ if (output.hasOwnProperty('y')) {
+ if (output.hasOwnProperty('z')) {
+ return [output.x, output.y, output.z];
+ } else {
+ return [output.x, output.y];
+ }
+ } else {
+ return [output.x];
+ }
+ } else {
+ return output;
+ }
+ }
+
+ setOutput(output) {
+ this.output = this.toKernelOutput(output);
+ return this;
+ }
+
+ setDebug(flag) {
+ this.debug = flag;
+ return this;
+ }
+
+ setGraphical(flag) {
+ this.graphical = flag;
+ this.precision = 'unsigned';
+ return this;
+ }
+
+ setLoopMaxIterations(max) {
+ this.loopMaxIterations = max;
+ return this;
+ }
+
+ setConstants(constants) {
+ this.constants = constants;
+ return this;
+ }
+
+ setConstantTypes(constantTypes) {
+ this.constantTypes = constantTypes;
+ return this;
+ }
+
+ setFunctions(functions) {
+ for (let i = 0; i < functions.length; i++) {
+ this.addFunction(functions[i]);
+ }
+ return this;
+ }
+
+ setNativeFunctions(nativeFunctions) {
+ for (let i = 0; i < nativeFunctions.length; i++) {
+ const settings = nativeFunctions[i];
+ const { name, source } = settings;
+ this.addNativeFunction(name, source, settings);
+ }
+ return this;
+ }
+
+ setInjectedNative(injectedNative) {
+ this.injectedNative = injectedNative;
+ return this;
+ }
+
+ setPipeline(flag) {
+ this.pipeline = flag;
+ return this;
+ }
+
+ setPrecision(flag) {
+ this.precision = flag;
+ return this;
+ }
+
+ setDimensions(flag) {
+ utils.warnDeprecated('method', 'setDimensions', 'setOutput');
+ this.output = flag;
+ return this;
+ }
+
+ setOutputToTexture(flag) {
+ utils.warnDeprecated('method', 'setOutputToTexture', 'setPipeline');
+ this.pipeline = flag;
+ return this;
+ }
+
+ setImmutable(flag) {
+ this.immutable = flag;
+ return this;
+ }
+
+ setCanvas(canvas) {
+ this.canvas = canvas;
+ return this;
+ }
+
+ setStrictIntegers(flag) {
+ this.strictIntegers = flag;
+ return this;
+ }
+
+ setDynamicOutput(flag) {
+ this.dynamicOutput = flag;
+ return this;
+ }
+
+ setHardcodeConstants(flag) {
+ utils.warnDeprecated('method', 'setHardcodeConstants');
+ this.setDynamicOutput(flag);
+ this.setDynamicArguments(flag);
+ return this;
+ }
+
+ setDynamicArguments(flag) {
+ this.dynamicArguments = flag;
+ return this;
+ }
+
+ setUseLegacyEncoder(flag) {
+ this.useLegacyEncoder = flag;
+ return this;
+ }
+
+ setWarnVarUsage(flag) {
+ utils.warnDeprecated('method', 'setWarnVarUsage');
+ return this;
+ }
+
+ getCanvas() {
+ utils.warnDeprecated('method', 'getCanvas');
+ return this.canvas;
+ }
+
+ getWebGl() {
+ utils.warnDeprecated('method', 'getWebGl');
+ return this.context;
+ }
+
+ setContext(context) {
+ this.context = context;
+ return this;
+ }
+
+ setArgumentTypes(argumentTypes) {
+ if (Array.isArray(argumentTypes)) {
+ this.argumentTypes = argumentTypes;
+ } else {
+ this.argumentTypes = [];
+ for (const p in argumentTypes) {
+ if (!argumentTypes.hasOwnProperty(p)) continue;
+ const argumentIndex = this.argumentNames.indexOf(p);
+ if (argumentIndex === -1) throw new Error(`unable to find argument ${ p }`);
+ this.argumentTypes[argumentIndex] = argumentTypes[p];
+ }
+ }
+ return this;
+ }
+
+ setTactic(tactic) {
+ this.tactic = tactic;
+ return this;
+ }
+
+ requestFallback(args) {
+ if (!this.onRequestFallback) {
+ throw new Error(`"onRequestFallback" not defined on ${ this.constructor.name }`);
+ }
+ this.fallbackRequested = true;
+ return this.onRequestFallback(args);
+ }
+
+ validateSettings() {
+ throw new Error(`"validateSettings" not defined on ${ this.constructor.name }`);
+ }
+
+ addSubKernel(subKernel) {
+ if (this.subKernels === null) {
+ this.subKernels = [];
+ }
+ if (!subKernel.source) throw new Error('subKernel missing "source" property');
+ if (!subKernel.property && isNaN(subKernel.property)) throw new Error('subKernel missing "property" property');
+ if (!subKernel.name) throw new Error('subKernel missing "name" property');
+ this.subKernels.push(subKernel);
+ return this;
+ }
+
+ destroy(removeCanvasReferences) {
+ throw new Error(`"destroy" called on ${ this.constructor.name }`);
+ }
+
+ getBitRatio(value) {
+ if (this.precision === 'single') {
+ return 4;
+ } else if (Array.isArray(value[0])) {
+ return this.getBitRatio(value[0]);
+ } else if (value.constructor === Input) {
+ return this.getBitRatio(value.value);
+ }
+ switch (value.constructor) {
+ case Uint8ClampedArray:
+ case Uint8Array:
+ case Int8Array:
+ return 1;
+ case Uint16Array:
+ case Int16Array:
+ return 2;
+ case Float32Array:
+ case Int32Array:
+ default:
+ return 4;
+ }
+ }
+
+ getPixels(flip) {
+ throw new Error(`"getPixels" called on ${ this.constructor.name }`);
+ }
+
+ checkOutput() {
+ if (!this.output || !utils.isArray(this.output)) throw new Error('kernel.output not an array');
+ if (this.output.length < 1) throw new Error('kernel.output is empty, needs at least 1 value');
+ for (let i = 0; i < this.output.length; i++) {
+ if (isNaN(this.output[i]) || this.output[i] < 1) {
+ throw new Error(`${ this.constructor.name }.output[${ i }] incorrectly defined as \`${ this.output[i] }\`, needs to be numeric, and greater than 0`);
+ }
+ }
+ }
+
+ prependString(value) {
+ throw new Error(`"prependString" called on ${ this.constructor.name }`);
+ }
+
+ hasPrependString(value) {
+ throw new Error(`"hasPrependString" called on ${ this.constructor.name }`);
+ }
+
+ toJSON() {
+ return {
+ settings: {
+ output: this.output,
+ pipeline: this.pipeline,
+ argumentNames: this.argumentNames,
+ argumentsTypes: this.argumentTypes,
+ constants: this.constants,
+ pluginNames: this.plugins ? this.plugins.map(plugin => plugin.name) : null,
+ returnType: this.returnType,
+ }
+ };
+ }
+
+ buildSignature(args) {
+ const Constructor = this.constructor;
+ this.signature = Constructor.getSignature(this, Constructor.getArgumentTypes(this, args));
+ }
+
+ static getArgumentTypes(kernel, args) {
+ const argumentTypes = new Array(args.length);
+ for (let i = 0; i < args.length; i++) {
+ const arg = args[i];
+ const type = kernel.argumentTypes[i];
+ if (arg.type) {
+ argumentTypes[i] = arg.type;
+ } else {
+ switch (type) {
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ case 'ArrayTexture(1)':
+ argumentTypes[i] = utils.getVariableType(arg);
+ break;
+ default:
+ argumentTypes[i] = type;
+ }
+ }
+ }
+ return argumentTypes;
+ }
+
+ static getSignature(kernel, argumentTypes) {
+ throw new Error(`"getSignature" not implemented on ${ this.name }`);
+ }
+
+ functionToIGPUFunction(source, settings = {}) {
+ if (typeof source !== 'string' && typeof source !== 'function') throw new Error('source not a string or function');
+ const sourceString = typeof source === 'string' ? source : source.toString();
+ let argumentTypes = [];
+
+ if (Array.isArray(settings.argumentTypes)) {
+ argumentTypes = settings.argumentTypes;
+ } else if (typeof settings.argumentTypes === 'object') {
+ argumentTypes = utils.getArgumentNamesFromString(sourceString)
+ .map(name => settings.argumentTypes[name]) || [];
+ } else {
+ argumentTypes = settings.argumentTypes || [];
+ }
+
+ return {
+ name: utils.getFunctionNameFromString(sourceString) || null,
+ source: sourceString,
+ argumentTypes,
+ returnType: settings.returnType || null,
+ };
+ }
+
+ onActivate(previousKernel) {}
+}
+
+function splitArgumentTypes(argumentTypesObject) {
+ const argumentNames = Object.keys(argumentTypesObject);
+ const argumentTypes = [];
+ for (let i = 0; i < argumentNames.length; i++) {
+ const argumentName = argumentNames[i];
+ argumentTypes.push(argumentTypesObject[argumentName]);
+ }
+ return { argumentTypes, argumentNames };
+}
+
+module.exports = {
+ Kernel
+};
+},{"../input":110,"../utils":114}],37:[function(require,module,exports){
+const fragmentShader = `__HEADER__;
+__FLOAT_TACTIC_DECLARATION__;
+__INT_TACTIC_DECLARATION__;
+__SAMPLER_2D_TACTIC_DECLARATION__;
+
+const int LOOP_MAX = __LOOP_MAX__;
+
+__PLUGINS__;
+__CONSTANTS__;
+
+varying vec2 vTexCoord;
+
+float acosh(float x) {
+ return log(x + sqrt(x * x - 1.0));
+}
+
+float sinh(float x) {
+ return (pow(${Math.E}, x) - pow(${Math.E}, -x)) / 2.0;
+}
+
+float asinh(float x) {
+ return log(x + sqrt(x * x + 1.0));
+}
+
+float atan2(float v1, float v2) {
+ if (v1 == 0.0 || v2 == 0.0) return 0.0;
+ return atan(v1 / v2);
+}
+
+float atanh(float x) {
+ x = (x + 1.0) / (x - 1.0);
+ if (x < 0.0) {
+ return 0.5 * log(-x);
+ }
+ return 0.5 * log(x);
+}
+
+float cbrt(float x) {
+ if (x >= 0.0) {
+ return pow(x, 1.0 / 3.0);
+ } else {
+ return -pow(x, 1.0 / 3.0);
+ }
+}
+
+float cosh(float x) {
+ return (pow(${Math.E}, x) + pow(${Math.E}, -x)) / 2.0;
+}
+
+float expm1(float x) {
+ return pow(${Math.E}, x) - 1.0;
+}
+
+float fround(highp float x) {
+ return x;
+}
+
+float imul(float v1, float v2) {
+ return float(int(v1) * int(v2));
+}
+
+float log10(float x) {
+ return log2(x) * (1.0 / log2(10.0));
+}
+
+float log1p(float x) {
+ return log(1.0 + x);
+}
+
+float _pow(float v1, float v2) {
+ if (v2 == 0.0) return 1.0;
+ return pow(v1, v2);
+}
+
+float tanh(float x) {
+ float e = exp(2.0 * x);
+ return (e - 1.0) / (e + 1.0);
+}
+
+float trunc(float x) {
+ if (x >= 0.0) {
+ return floor(x);
+ } else {
+ return ceil(x);
+ }
+}
+
+vec4 _round(vec4 x) {
+ return floor(x + 0.5);
+}
+
+float _round(float x) {
+ return floor(x + 0.5);
+}
+
+const int BIT_COUNT = 32;
+int modi(int x, int y) {
+ return x - y * (x / y);
+}
+
+int bitwiseOr(int a, int b) {
+ int result = 0;
+ int n = 1;
+
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {
+ result += n;
+ }
+ a = a / 2;
+ b = b / 2;
+ n = n * 2;
+ if(!(a > 0 || b > 0)) {
+ break;
+ }
+ }
+ return result;
+}
+int bitwiseXOR(int a, int b) {
+ int result = 0;
+ int n = 1;
+
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {
+ result += n;
+ }
+ a = a / 2;
+ b = b / 2;
+ n = n * 2;
+ if(!(a > 0 || b > 0)) {
+ break;
+ }
+ }
+ return result;
+}
+int bitwiseAnd(int a, int b) {
+ int result = 0;
+ int n = 1;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {
+ result += n;
+ }
+ a = a / 2;
+ b = b / 2;
+ n = n * 2;
+ if(!(a > 0 && b > 0)) {
+ break;
+ }
+ }
+ return result;
+}
+int bitwiseNot(int a) {
+ int result = 0;
+ int n = 1;
+
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (modi(a, 2) == 0) {
+ result += n;
+ }
+ a = a / 2;
+ n = n * 2;
+ }
+ return result;
+}
+int bitwiseZeroFillLeftShift(int n, int shift) {
+ int maxBytes = BIT_COUNT;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (maxBytes >= n) {
+ break;
+ }
+ maxBytes *= 2;
+ }
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= shift) {
+ break;
+ }
+ n *= 2;
+ }
+
+ int result = 0;
+ int byteVal = 1;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= maxBytes) break;
+ if (modi(n, 2) > 0) { result += byteVal; }
+ n = int(n / 2);
+ byteVal *= 2;
+ }
+ return result;
+}
+
+int bitwiseSignedRightShift(int num, int shifts) {
+ return int(floor(float(num) / pow(2.0, float(shifts))));
+}
+
+int bitwiseZeroFillRightShift(int n, int shift) {
+ int maxBytes = BIT_COUNT;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (maxBytes >= n) {
+ break;
+ }
+ maxBytes *= 2;
+ }
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= shift) {
+ break;
+ }
+ n /= 2;
+ }
+ int result = 0;
+ int byteVal = 1;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= maxBytes) break;
+ if (modi(n, 2) > 0) { result += byteVal; }
+ n = int(n / 2);
+ byteVal *= 2;
+ }
+ return result;
+}
+
+vec2 integerMod(vec2 x, float y) {
+ vec2 res = floor(mod(x, y));
+ return res * step(1.0 - floor(y), -res);
+}
+
+vec3 integerMod(vec3 x, float y) {
+ vec3 res = floor(mod(x, y));
+ return res * step(1.0 - floor(y), -res);
+}
+
+vec4 integerMod(vec4 x, vec4 y) {
+ vec4 res = floor(mod(x, y));
+ return res * step(1.0 - floor(y), -res);
+}
+
+float integerMod(float x, float y) {
+ float res = floor(mod(x, y));
+ return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);
+}
+
+int integerMod(int x, int y) {
+ return x - (y * int(x / y));
+}
+
+__DIVIDE_WITH_INTEGER_CHECK__;
+
+// Here be dragons!
+// DO NOT OPTIMIZE THIS CODE
+// YOU WILL BREAK SOMETHING ON SOMEBODY\'S MACHINE
+// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME
+const vec2 MAGIC_VEC = vec2(1.0, -256.0);
+const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);
+const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536
+float decode32(vec4 texel) {
+ __DECODE32_ENDIANNESS__;
+ texel *= 255.0;
+ vec2 gte128;
+ gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;
+ gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;
+ float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);
+ float res = exp2(_round(exponent));
+ texel.b = texel.b - 128.0 * gte128.x;
+ res = dot(texel, SCALE_FACTOR) * exp2(_round(exponent-23.0)) + res;
+ res *= gte128.y * -2.0 + 1.0;
+ return res;
+}
+
+float decode16(vec4 texel, int index) {
+ int channel = integerMod(index, 2);
+ if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0;
+ if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0;
+ return 0.0;
+}
+
+float decode8(vec4 texel, int index) {
+ int channel = integerMod(index, 4);
+ if (channel == 0) return texel.r * 255.0;
+ if (channel == 1) return texel.g * 255.0;
+ if (channel == 2) return texel.b * 255.0;
+ if (channel == 3) return texel.a * 255.0;
+ return 0.0;
+}
+
+vec4 legacyEncode32(float f) {
+ float F = abs(f);
+ float sign = f < 0.0 ? 1.0 : 0.0;
+ float exponent = floor(log2(F));
+ float mantissa = (exp2(-exponent) * F);
+ // exponent += floor(log2(mantissa));
+ vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;
+ texel.rg = integerMod(texel.rg, 256.0);
+ texel.b = integerMod(texel.b, 128.0);
+ texel.a = exponent*0.5 + 63.5;
+ texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;
+ texel = floor(texel);
+ texel *= 0.003921569; // 1/255
+ __ENCODE32_ENDIANNESS__;
+ return texel;
+}
+
+// https://github.com/gpujs/gpu.js/wiki/Encoder-details
+vec4 encode32(float value) {
+ if (value == 0.0) return vec4(0, 0, 0, 0);
+
+ float exponent;
+ float mantissa;
+ vec4 result;
+ float sgn;
+
+ sgn = step(0.0, -value);
+ value = abs(value);
+
+ exponent = floor(log2(value));
+
+ mantissa = value*pow(2.0, -exponent)-1.0;
+ exponent = exponent+127.0;
+ result = vec4(0,0,0,0);
+
+ result.a = floor(exponent/2.0);
+ exponent = exponent - result.a*2.0;
+ result.a = result.a + 128.0*sgn;
+
+ result.b = floor(mantissa * 128.0);
+ mantissa = mantissa - result.b / 128.0;
+ result.b = result.b + exponent*128.0;
+
+ result.g = floor(mantissa*32768.0);
+ mantissa = mantissa - result.g/32768.0;
+
+ result.r = floor(mantissa*8388608.0);
+ return result/255.0;
+}
+// Dragons end here
+
+int index;
+ivec3 threadId;
+
+ivec3 indexTo3D(int idx, ivec3 texDim) {
+ int z = int(idx / (texDim.x * texDim.y));
+ idx -= z * int(texDim.x * texDim.y);
+ int y = int(idx / texDim.x);
+ int x = int(integerMod(idx, texDim.x));
+ return ivec3(x, y, z);
+}
+
+float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture2D(tex, st / vec2(texSize));
+ return decode32(texel);
+}
+
+float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int w = texSize.x * 2;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y));
+ return decode16(texel, index);
+}
+
+float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int w = texSize.x * 4;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y));
+ return decode8(texel, index);
+}
+
+float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int channel = integerMod(index, 4);
+ index = index / 4;
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture2D(tex, st / vec2(texSize));
+ if (channel == 0) return texel.r;
+ if (channel == 1) return texel.g;
+ if (channel == 2) return texel.b;
+ if (channel == 3) return texel.a;
+ return 0.0;
+}
+
+vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ return texture2D(tex, st / vec2(texSize));
+}
+
+float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
+ return result[0];
+}
+
+vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
+ return vec2(result[0], result[1]);
+}
+
+vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + (texDim.x * (y + (texDim.y * z)));
+ int channel = integerMod(index, 2);
+ index = index / 2;
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture2D(tex, st / vec2(texSize));
+ if (channel == 0) return vec2(texel.r, texel.g);
+ if (channel == 1) return vec2(texel.b, texel.a);
+ return vec2(0.0, 0.0);
+}
+
+vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
+ return vec3(result[0], result[1], result[2]);
+}
+
+vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));
+ int vectorIndex = fieldIndex / 4;
+ int vectorOffset = fieldIndex - vectorIndex * 4;
+ int readY = vectorIndex / texSize.x;
+ int readX = vectorIndex - readY * texSize.x;
+ vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));
+
+ if (vectorOffset == 0) {
+ return tex1.xyz;
+ } else if (vectorOffset == 1) {
+ return tex1.yzw;
+ } else {
+ readX++;
+ if (readX >= texSize.x) {
+ readX = 0;
+ readY++;
+ }
+ vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize));
+ if (vectorOffset == 2) {
+ return vec3(tex1.z, tex1.w, tex2.x);
+ } else {
+ return vec3(tex1.w, tex2.x, tex2.y);
+ }
+ }
+}
+
+vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ return getImage2D(tex, texSize, texDim, z, y, x);
+}
+
+vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int channel = integerMod(index, 2);
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture2D(tex, st / vec2(texSize));
+ return vec4(texel.r, texel.g, texel.b, texel.a);
+}
+
+vec4 actualColor;
+void color(float r, float g, float b, float a) {
+ actualColor = vec4(r,g,b,a);
+}
+
+void color(float r, float g, float b) {
+ color(r,g,b,1.0);
+}
+
+void color(sampler2D image) {
+ actualColor = texture2D(image, vTexCoord);
+}
+
+float modulo(float number, float divisor) {
+ if (number < 0.0) {
+ number = abs(number);
+ if (divisor < 0.0) {
+ divisor = abs(divisor);
+ }
+ return -mod(number, divisor);
+ }
+ if (divisor < 0.0) {
+ divisor = abs(divisor);
+ }
+ return mod(number, divisor);
+}
+
+__INJECTED_NATIVE__;
+__MAIN_CONSTANTS__;
+__MAIN_ARGUMENTS__;
+__KERNEL__;
+
+void main(void) {
+ index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;
+ __MAIN_RESULT__;
+}`;
+
+module.exports = {
+ fragmentShader
+};
+},{}],38:[function(require,module,exports){
+const { utils } = require('../../utils');
+const { FunctionNode } = require('../function-node');
+
+class WebGLFunctionNode extends FunctionNode {
+ constructor(source, settings) {
+ super(source, settings);
+ if (settings && settings.hasOwnProperty('fixIntegerDivisionAccuracy')) {
+ this.fixIntegerDivisionAccuracy = settings.fixIntegerDivisionAccuracy;
+ }
+ }
+
+ 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;
+ }
+ retArr.push('(');
+ this.astGeneric(ast.test, retArr);
+ retArr.push('?');
+ this.astGeneric(ast.consequent, retArr);
+ retArr.push(':');
+ this.astGeneric(ast.alternate, retArr);
+ retArr.push(')');
+ return retArr;
+ }
+
+ astFunction(ast, retArr) {
+ if (this.isRootKernel) {
+ retArr.push('void');
+ } else {
+ 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;
+ if (!returnType) {
+ retArr.push('void');
+ } else {
+ const type = typeMap[returnType];
+ if (!type) {
+ throw new Error(`unknown type ${returnType}`);
+ }
+ retArr.push(type);
+ }
+ }
+ retArr.push(' ');
+ retArr.push(this.name);
+ retArr.push('(');
+
+ if (!this.isRootKernel) {
+ 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 type = typeMap[argumentType];
+ if (!type) {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ const name = utils.sanitizeName(argumentName);
+ if (type === 'sampler2D' || type === 'sampler2DArray') {
+ retArr.push(`${type} user_${name},ivec2 user_${name}Size,ivec3 user_${name}Dim`);
+ } else {
+ retArr.push(`${type} user_${name}`);
+ }
+ }
+ }
+
+ 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('float(');
+ this.astGeneric(ast.argument, result);
+ result.push(')');
+ break;
+ case 'LiteralInteger':
+ this.castLiteralToFloat(ast.argument, result);
+
+ if (this.getType(ast) === 'Integer') {
+ result.unshift('float(');
+ 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 'Array(4)':
+ case 'Array(3)':
+ case 'Array(2)':
+ case 'Matrix(2)':
+ case 'Matrix(3)':
+ case 'Matrix(4)':
+ case 'Input':
+ this.astGeneric(ast.argument, result);
+ break;
+ default:
+ throw this.astErrorOutput(`unhandled return type ${this.returnType}`, ast);
+ }
+
+ if (this.isRootKernel) {
+ retArr.push(`kernelResult = ${ result.join('') };`);
+ retArr.push('return;');
+ } else if (this.isSubKernel) {
+ retArr.push(`subKernelResult_${ this.name } = ${ result.join('') };`);
+ retArr.push(`return subKernelResult_${ this.name };`);
+ } else {
+ retArr.push(`return ${ result.join('') };`);
+ }
+ return retArr;
+ }
+
+ astLiteral(ast, 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(`${ast.value}`);
+ } else if (this.isState('casting-to-float') || this.isState('building-float')) {
+ this.literalTypes[key] = 'Number';
+ retArr.push(`${ast.value}.0`);
+ } else {
+ this.literalTypes[key] = 'Number';
+ retArr.push(`${ast.value}.0`);
+ }
+ } else if (this.isState('casting-to-integer') || this.isState('building-integer')) {
+ this.literalTypes[key] = 'Integer';
+ retArr.push(Math.round(ast.value));
+ } else {
+ this.literalTypes[key] = 'Number';
+ retArr.push(`${ast.value}`);
+ }
+ return retArr;
+ }
+
+ astBinaryExpression(ast, retArr) {
+ if (this.checkAndUpconvertOperator(ast, retArr)) {
+ return retArr;
+ }
+
+ if (this.fixIntegerDivisionAccuracy && ast.operator === '/') {
+ retArr.push('divWithIntCheck(');
+ 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(', ');
+ 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';
+ if (!leftType || !rightType) {
+ throw this.astErrorOutput(`Unhandled binary expression`, ast);
+ }
+ 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);
+ 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('int(');
+ 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.astGeneric(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) {
+ const bitwiseResult = this.checkAndUpconvertBitwiseOperators(ast, retArr);
+ if (bitwiseResult) {
+ return bitwiseResult;
+ }
+ const upconvertableOperators = {
+ '%': this.fixIntegerDivisionAccuracy ? 'integerCorrectionModulo' : 'modulo',
+ '**': 'pow',
+ };
+ const foundOperator = upconvertableOperators[ast.operator];
+ if (!foundOperator) return null;
+ retArr.push(foundOperator);
+ 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 upconvertableOperators = {
+ '&': 'bitwiseAnd',
+ '|': 'bitwiseOr',
+ '^': 'bitwiseXOR',
+ '<<': 'bitwiseZeroFillLeftShift',
+ '>>': 'bitwiseSignedRightShift',
+ '>>>': 'bitwiseZeroFillRightShift',
+ };
+ const foundOperator = upconvertableOperators[ast.operator];
+ if (!foundOperator) return null;
+ retArr.push(foundOperator);
+ retArr.push('(');
+ const leftType = this.getType(ast.left);
+ switch (leftType) {
+ case 'Number':
+ case 'Float':
+ this.castValueToInteger(ast.left, retArr);
+ break;
+ case 'LiteralInteger':
+ this.castLiteralToInteger(ast.left, retArr);
+ break;
+ default:
+ this.astGeneric(ast.left, retArr);
+ }
+ retArr.push(',');
+ const rightType = this.getType(ast.right);
+ switch (rightType) {
+ case 'Number':
+ case 'Float':
+ this.castValueToInteger(ast.right, retArr);
+ break;
+ case 'LiteralInteger':
+ this.castLiteralToInteger(ast.right, retArr);
+ break;
+ default:
+ this.astGeneric(ast.right, retArr);
+ }
+ retArr.push(')');
+ return retArr;
+ }
+
+ checkAndUpconvertBitwiseUnary(ast, retArr) {
+ const upconvertableOperators = {
+ '~': 'bitwiseNot',
+ };
+ const foundOperator = upconvertableOperators[ast.operator];
+ if (!foundOperator) return null;
+ retArr.push(foundOperator);
+ 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;
+ }
+
+ 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('int(');
+ this.astGeneric(ast, retArr);
+ retArr.push(')');
+ this.popState('casting-to-integer');
+ return retArr;
+ }
+
+ castValueToFloat(ast, retArr) {
+ this.pushState('casting-to-float');
+ retArr.push('float(');
+ 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('3.402823466e+38');
+ } else if (type === 'Boolean') {
+ if (this.argumentNames.indexOf(name) > -1) {
+ retArr.push(`bool(user_${name})`);
+ } else {
+ retArr.push(`user_${name}`);
+ }
+ } else {
+ 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) {
+ 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 (int ${iVariableName}=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 (int ${iVariableName}=0;${iVariableName} 0) {
+ declarationSets.push(declarationSet.join(','));
+ }
+
+ result.push(declarationSets.join(';'));
+
+ retArr.push(result.join(''));
+ retArr.push(';');
+ return retArr;
+ }
+
+ astIfStatement(ifNode, retArr) {
+ retArr.push('if (');
+ this.astGeneric(ifNode.test, retArr);
+ retArr.push(')');
+ if (ifNode.consequent.type === 'BlockStatement') {
+ this.astGeneric(ifNode.consequent, retArr);
+ } else {
+ retArr.push(' {\n');
+ this.astGeneric(ifNode.consequent, retArr);
+ retArr.push('\n}\n');
+ }
+
+ if (ifNode.alternate) {
+ retArr.push('else ');
+ if (ifNode.alternate.type === 'BlockStatement' || ifNode.alternate.type === 'IfStatement') {
+ this.astGeneric(ifNode.alternate, retArr);
+ } else {
+ retArr.push(' {\n');
+ this.astGeneric(ifNode.alternate, retArr);
+ retArr.push('\n}\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(`float ${varName} = `);
+ this.astGeneric(discriminant, retArr);
+ retArr.push(';\n');
+ break;
+ case 'Integer':
+ retArr.push(`int ${varName} = `);
+ this.astGeneric(discriminant, retArr);
+ retArr.push(';\n');
+ break;
+ }
+ if (cases.length === 1 && !cases[0].test) {
+ this.astGeneric(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.astGeneric(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 if (type === 'Float') {
+ 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;
+ }
+ } else {
+ throw new Error('unhanlded');
+ }
+ if (!cases[i].consequent || cases[i].consequent.length === 0) {
+ fallingThrough = true;
+ retArr.push(' || ');
+ continue;
+ }
+ retArr.push(`) {\n`);
+ }
+ this.astGeneric(cases[i].consequent, retArr);
+ retArr.push('\n}');
+ }
+ if (movingDefaultToEnd) {
+ retArr.push(' else {');
+ retArr.push(defaultResult.join(''));
+ retArr.push('}');
+ }
+ return retArr;
+ }
+
+ astThisExpression(tNode, retArr) {
+ retArr.push('this');
+ return retArr;
+ }
+
+ 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);
+ }
+ retArr.push(`threadId.${name}`);
+ return retArr;
+ case 'this.output.value':
+ if (this.dynamicOutput) {
+ switch (name) {
+ case 'x':
+ if (this.isState('casting-to-float')) {
+ retArr.push('float(uOutputDim.x)');
+ } else {
+ retArr.push('uOutputDim.x');
+ }
+ break;
+ case 'y':
+ if (this.isState('casting-to-float')) {
+ retArr.push('float(uOutputDim.y)');
+ } else {
+ retArr.push('uOutputDim.y');
+ }
+ break;
+ case 'z':
+ if (this.isState('casting-to-float')) {
+ retArr.push('float(uOutputDim.z)');
+ } else {
+ retArr.push('uOutputDim.z');
+ }
+ break;
+ default:
+ throw this.astErrorOutput('Unexpected expression', mNode);
+ }
+ } else {
+ switch (name) {
+ case 'x':
+ if (this.isState('casting-to-integer')) {
+ retArr.push(this.output[0]);
+ } else {
+ retArr.push(this.output[0], '.0');
+ }
+ break;
+ case 'y':
+ if (this.isState('casting-to-integer')) {
+ retArr.push(this.output[1]);
+ } else {
+ retArr.push(this.output[1], '.0');
+ }
+ break;
+ case 'z':
+ if (this.isState('casting-to-integer')) {
+ retArr.push(this.output[2]);
+ } else {
+ retArr.push(this.output[2], '.0');
+ }
+ break;
+ default:
+ throw this.astErrorOutput('Unexpected expression', mNode);
+ }
+ }
+ 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(Math[name]);
+ return retArr;
+ }
+ const cleanName = utils.sanitizeName(name);
+ switch (property) {
+ case 'r':
+ retArr.push(`user_${ cleanName }.r`);
+ return retArr;
+ case 'g':
+ retArr.push(`user_${ cleanName }.g`);
+ return retArr;
+ case 'b':
+ retArr.push(`user_${ cleanName }.b`);
+ return retArr;
+ case 'a':
+ retArr.push(`user_${ cleanName }.a`);
+ return retArr;
+ }
+ break;
+ case 'this.constants.value':
+ if (typeof xProperty === 'undefined') {
+ switch (type) {
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ retArr.push(`constants_${ utils.sanitizeName(name) }`);
+ return retArr;
+ }
+ }
+ 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;
+ case 'fn()[][]':
+ this.astCallExpression(mNode.object.object, retArr);
+ retArr.push('[');
+ retArr.push(this.memberExpressionPropertyMarkup(mNode.object.property));
+ retArr.push(']');
+ retArr.push('[');
+ retArr.push(this.memberExpressionPropertyMarkup(mNode.property));
+ retArr.push(']');
+ return retArr;
+ case '[][]':
+ this.astArrayExpression(mNode.object, retArr);
+ retArr.push('[');
+ retArr.push(this.memberExpressionPropertyMarkup(property));
+ retArr.push(']');
+ return retArr;
+ default:
+ throw this.astErrorOutput('Unexpected expression', mNode);
+ }
+
+ if (mNode.computed === false) {
+ switch (type) {
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ case 'Boolean':
+ retArr.push(`${origin}_${utils.sanitizeName(name)}`);
+ return retArr;
+ }
+ }
+
+ 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 'HTMLImageArray':
+ retArr.push(`getImage3D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'ArrayTexture(1)':
+ retArr.push(`getFloatFromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'Array1D(2)':
+ case 'Array2D(2)':
+ case 'Array3D(2)':
+ retArr.push(`getMemoryOptimizedVec2(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'ArrayTexture(2)':
+ retArr.push(`getVec2FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'Array1D(3)':
+ case 'Array2D(3)':
+ case 'Array3D(3)':
+ retArr.push(`getMemoryOptimizedVec3(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'ArrayTexture(3)':
+ retArr.push(`getVec3FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'Array1D(4)':
+ case 'Array2D(4)':
+ case 'Array3D(4)':
+ retArr.push(`getMemoryOptimizedVec4(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'ArrayTexture(4)':
+ case 'HTMLCanvas':
+ case 'OffscreenCanvas':
+ case 'HTMLImage':
+ case 'ImageBitmap':
+ case 'ImageData':
+ case 'HTMLVideo':
+ retArr.push(`getVec4FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'NumberTexture':
+ case 'Array':
+ case 'Array2D':
+ case 'Array3D':
+ case 'Array4D':
+ case 'Input':
+ case 'Number':
+ case 'Float':
+ case 'Integer':
+ if (this.precision === 'single') {
+ retArr.push(`getMemoryOptimized32(${markupName}, ${markupName}Size, ${markupName}Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ } else {
+ const bitRatio = (origin === 'user' ?
+ this.lookupFunctionArgumentBitRatio(this.name, name) :
+ this.constantBitRatios[name]
+ );
+ switch (bitRatio) {
+ case 1:
+ retArr.push(`get8(${markupName}, ${markupName}Size, ${markupName}Dim, `);
+ break;
+ case 2:
+ retArr.push(`get16(${markupName}, ${markupName}Size, ${markupName}Dim, `);
+ break;
+ case 4:
+ case 0:
+ retArr.push(`get32(${markupName}, ${markupName}Size, ${markupName}Dim, `);
+ break;
+ default:
+ throw new Error(`unhandled bit ratio of ${bitRatio}`);
+ }
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ }
+ break;
+ case 'MemoryOptimizedNumberTexture':
+ retArr.push(`getMemoryOptimized32(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'Matrix(2)':
+ case 'Matrix(3)':
+ case 'Matrix(4)':
+ retArr.push(`${markupName}[${this.memberExpressionPropertyMarkup(yProperty)}]`);
+ if (yProperty) {
+ retArr.push(`[${this.memberExpressionPropertyMarkup(xProperty)}]`);
+ }
+ break;
+ default:
+ throw new Error(`unhandled member expression "${ type }"`);
+ }
+ 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);
+ }
+
+ switch (functionName) {
+ case 'pow':
+ functionName = '_pow';
+ break;
+ case 'round':
+ functionName = '_round';
+ break;
+ }
+
+ if (this.calledFunctions.indexOf(functionName) < 0) {
+ this.calledFunctions.push(functionName);
+ }
+
+ if (functionName === 'random' && this.plugins && this.plugins.length > 0) {
+ for (let i = 0; i < this.plugins.length; i++) {
+ const plugin = this.plugins[i];
+ if (plugin.functionMatch === 'Math.random()' && plugin.functionReplace) {
+ retArr.push(plugin.functionReplace);
+ return retArr;
+ }
+ }
+ }
+
+ if (this.onFunctionCall) {
+ this.onFunctionCall(this.name, functionName, ast.arguments);
+ }
+
+ retArr.push(functionName);
+
+ 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;
+ 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('int(');
+ 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('float(');
+ 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 if (argument.type === 'ArrayExpression' || argument.type === 'MemberExpression' || argument.type === 'CallExpression') {
+ this.astGeneric(argument, retArr);
+ } else {
+ throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast);
+ }
+ 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 (targetType === argumentType) {
+ if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast);
+ this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i);
+ const name = utils.sanitizeName(argument.name);
+ retArr.push(`user_${name},user_${name}Size,user_${name}Dim`);
+ continue;
+ }
+ break;
+ }
+ throw this.astErrorOutput(`Unhandled argument combination of ${ argumentType } and ${ targetType } for argument named "${ argument.name }"`, ast);
+ }
+ }
+ retArr.push(')');
+
+ return retArr;
+ }
+
+ astArrayExpression(arrNode, retArr) {
+ const returnType = this.getType(arrNode);
+
+ const arrLen = arrNode.elements.length;
+
+ switch (returnType) {
+ case 'Matrix(2)':
+ case 'Matrix(3)':
+ case 'Matrix(4)':
+ retArr.push(`mat${arrLen}(`);
+ break;
+ default:
+ retArr.push(`vec${arrLen}(`);
+ }
+ for (let i = 0; i < arrLen; ++i) {
+ if (i > 0) {
+ retArr.push(', ');
+ }
+ const subNode = arrNode.elements[i];
+ 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;
+ default:
+ this.astGeneric(property, result);
+ }
+ return result.join('');
+ }
+}
+
+const typeMap = {
+ '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',
+};
+
+const operatorMap = {
+ '===': '==',
+ '!==': '!='
+};
+
+module.exports = {
+ WebGLFunctionNode
+};
+},{"../../utils":114,"../function-node":10}],39:[function(require,module,exports){
+const { WebGLKernelValueBoolean } = require('./kernel-value/boolean');
+const { WebGLKernelValueFloat } = require('./kernel-value/float');
+const { WebGLKernelValueInteger } = require('./kernel-value/integer');
+
+const { WebGLKernelValueHTMLImage } = require('./kernel-value/html-image');
+const { WebGLKernelValueDynamicHTMLImage } = require('./kernel-value/dynamic-html-image');
+
+const { WebGLKernelValueHTMLVideo } = require('./kernel-value/html-video');
+const { WebGLKernelValueDynamicHTMLVideo } = require('./kernel-value/dynamic-html-video');
+
+const { WebGLKernelValueSingleInput } = require('./kernel-value/single-input');
+const { WebGLKernelValueDynamicSingleInput } = require('./kernel-value/dynamic-single-input');
+
+const { WebGLKernelValueUnsignedInput } = require('./kernel-value/unsigned-input');
+const { WebGLKernelValueDynamicUnsignedInput } = require('./kernel-value/dynamic-unsigned-input');
+
+const { WebGLKernelValueMemoryOptimizedNumberTexture } = require('./kernel-value/memory-optimized-number-texture');
+const { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } = require('./kernel-value/dynamic-memory-optimized-number-texture');
+
+const { WebGLKernelValueNumberTexture } = require('./kernel-value/number-texture');
+const { WebGLKernelValueDynamicNumberTexture } = require('./kernel-value/dynamic-number-texture');
+
+const { WebGLKernelValueSingleArray } = require('./kernel-value/single-array');
+const { WebGLKernelValueDynamicSingleArray } = require('./kernel-value/dynamic-single-array');
+
+const { WebGLKernelValueSingleArray1DI } = require('./kernel-value/single-array1d-i');
+const { WebGLKernelValueDynamicSingleArray1DI } = require('./kernel-value/dynamic-single-array1d-i');
+
+const { WebGLKernelValueSingleArray2DI } = require('./kernel-value/single-array2d-i');
+const { WebGLKernelValueDynamicSingleArray2DI } = require('./kernel-value/dynamic-single-array2d-i');
+
+const { WebGLKernelValueSingleArray3DI } = require('./kernel-value/single-array3d-i');
+const { WebGLKernelValueDynamicSingleArray3DI } = require('./kernel-value/dynamic-single-array3d-i');
+
+const { WebGLKernelValueArray2 } = require('./kernel-value/array2');
+const { WebGLKernelValueArray3 } = require('./kernel-value/array3');
+const { WebGLKernelValueArray4 } = require('./kernel-value/array4');
+
+const { WebGLKernelValueUnsignedArray } = require('./kernel-value/unsigned-array');
+const { WebGLKernelValueDynamicUnsignedArray } = require('./kernel-value/dynamic-unsigned-array');
+
+const kernelValueMaps = {
+ unsigned: {
+ dynamic: {
+ 'Boolean': WebGLKernelValueBoolean,
+ 'Integer': WebGLKernelValueInteger,
+ 'Float': WebGLKernelValueFloat,
+ 'Array': WebGLKernelValueDynamicUnsignedArray,
+ 'Array(2)': WebGLKernelValueArray2,
+ 'Array(3)': WebGLKernelValueArray3,
+ 'Array(4)': WebGLKernelValueArray4,
+ 'Array1D(2)': false,
+ 'Array1D(3)': false,
+ 'Array1D(4)': false,
+ 'Array2D(2)': false,
+ 'Array2D(3)': false,
+ 'Array2D(4)': false,
+ 'Array3D(2)': false,
+ 'Array3D(3)': false,
+ 'Array3D(4)': false,
+ 'Input': WebGLKernelValueDynamicUnsignedInput,
+ 'NumberTexture': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGLKernelValueDynamicHTMLImage,
+ 'OffscreenCanvas': WebGLKernelValueDynamicHTMLImage,
+ 'HTMLImage': WebGLKernelValueDynamicHTMLImage,
+ 'ImageBitmap': WebGLKernelValueDynamicHTMLImage,
+ 'ImageData': WebGLKernelValueDynamicHTMLImage,
+ 'HTMLImageArray': false,
+ 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo,
+ },
+ static: {
+ 'Boolean': WebGLKernelValueBoolean,
+ 'Float': WebGLKernelValueFloat,
+ 'Integer': WebGLKernelValueInteger,
+ 'Array': WebGLKernelValueUnsignedArray,
+ 'Array(2)': WebGLKernelValueArray2,
+ 'Array(3)': WebGLKernelValueArray3,
+ 'Array(4)': WebGLKernelValueArray4,
+ 'Array1D(2)': false,
+ 'Array1D(3)': false,
+ 'Array1D(4)': false,
+ 'Array2D(2)': false,
+ 'Array2D(3)': false,
+ 'Array2D(4)': false,
+ 'Array3D(2)': false,
+ 'Array3D(3)': false,
+ 'Array3D(4)': false,
+ 'Input': WebGLKernelValueUnsignedInput,
+ 'NumberTexture': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(1)': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(2)': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(3)': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(4)': WebGLKernelValueNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGLKernelValueHTMLImage,
+ 'OffscreenCanvas': WebGLKernelValueHTMLImage,
+ 'HTMLImage': WebGLKernelValueHTMLImage,
+ 'ImageBitmap': WebGLKernelValueHTMLImage,
+ 'ImageData': WebGLKernelValueHTMLImage,
+ 'HTMLImageArray': false,
+ 'HTMLVideo': WebGLKernelValueHTMLVideo,
+ }
+ },
+ single: {
+ dynamic: {
+ 'Boolean': WebGLKernelValueBoolean,
+ 'Integer': WebGLKernelValueInteger,
+ 'Float': WebGLKernelValueFloat,
+ 'Array': WebGLKernelValueDynamicSingleArray,
+ 'Array(2)': WebGLKernelValueArray2,
+ 'Array(3)': WebGLKernelValueArray3,
+ 'Array(4)': WebGLKernelValueArray4,
+ 'Array1D(2)': WebGLKernelValueDynamicSingleArray1DI,
+ 'Array1D(3)': WebGLKernelValueDynamicSingleArray1DI,
+ 'Array1D(4)': WebGLKernelValueDynamicSingleArray1DI,
+ 'Array2D(2)': WebGLKernelValueDynamicSingleArray2DI,
+ 'Array2D(3)': WebGLKernelValueDynamicSingleArray2DI,
+ 'Array2D(4)': WebGLKernelValueDynamicSingleArray2DI,
+ 'Array3D(2)': WebGLKernelValueDynamicSingleArray3DI,
+ 'Array3D(3)': WebGLKernelValueDynamicSingleArray3DI,
+ 'Array3D(4)': WebGLKernelValueDynamicSingleArray3DI,
+ 'Input': WebGLKernelValueDynamicSingleInput,
+ 'NumberTexture': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGLKernelValueDynamicHTMLImage,
+ 'OffscreenCanvas': WebGLKernelValueDynamicHTMLImage,
+ 'HTMLImage': WebGLKernelValueDynamicHTMLImage,
+ 'ImageBitmap': WebGLKernelValueDynamicHTMLImage,
+ 'ImageData': WebGLKernelValueDynamicHTMLImage,
+ 'HTMLImageArray': false,
+ 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo,
+ },
+ static: {
+ 'Boolean': WebGLKernelValueBoolean,
+ 'Float': WebGLKernelValueFloat,
+ 'Integer': WebGLKernelValueInteger,
+ 'Array': WebGLKernelValueSingleArray,
+ 'Array(2)': WebGLKernelValueArray2,
+ 'Array(3)': WebGLKernelValueArray3,
+ 'Array(4)': WebGLKernelValueArray4,
+ 'Array1D(2)': WebGLKernelValueSingleArray1DI,
+ 'Array1D(3)': WebGLKernelValueSingleArray1DI,
+ 'Array1D(4)': WebGLKernelValueSingleArray1DI,
+ 'Array2D(2)': WebGLKernelValueSingleArray2DI,
+ 'Array2D(3)': WebGLKernelValueSingleArray2DI,
+ 'Array2D(4)': WebGLKernelValueSingleArray2DI,
+ 'Array3D(2)': WebGLKernelValueSingleArray3DI,
+ 'Array3D(3)': WebGLKernelValueSingleArray3DI,
+ 'Array3D(4)': WebGLKernelValueSingleArray3DI,
+ 'Input': WebGLKernelValueSingleInput,
+ 'NumberTexture': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(1)': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(2)': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(3)': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(4)': WebGLKernelValueNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGLKernelValueHTMLImage,
+ 'OffscreenCanvas': WebGLKernelValueHTMLImage,
+ 'HTMLImage': WebGLKernelValueHTMLImage,
+ 'ImageBitmap': WebGLKernelValueHTMLImage,
+ 'ImageData': WebGLKernelValueHTMLImage,
+ 'HTMLImageArray': false,
+ 'HTMLVideo': WebGLKernelValueHTMLVideo,
+ }
+ },
+};
+
+function lookupKernelValueType(type, dynamic, precision, value) {
+ if (!type) {
+ throw new Error('type missing');
+ }
+ if (!dynamic) {
+ throw new Error('dynamic missing');
+ }
+ if (!precision) {
+ throw new Error('precision missing');
+ }
+ if (value.type) {
+ type = value.type;
+ }
+ const types = kernelValueMaps[precision][dynamic];
+ if (types[type] === false) {
+ return null;
+ } else if (types[type] === undefined) {
+ throw new Error(`Could not find a KernelValue for ${ type }`);
+ }
+ return types[type];
+}
+
+module.exports = {
+ lookupKernelValueType,
+ kernelValueMaps,
+};
+},{"./kernel-value/array2":41,"./kernel-value/array3":42,"./kernel-value/array4":43,"./kernel-value/boolean":44,"./kernel-value/dynamic-html-image":45,"./kernel-value/dynamic-html-video":46,"./kernel-value/dynamic-memory-optimized-number-texture":47,"./kernel-value/dynamic-number-texture":48,"./kernel-value/dynamic-single-array":49,"./kernel-value/dynamic-single-array1d-i":50,"./kernel-value/dynamic-single-array2d-i":51,"./kernel-value/dynamic-single-array3d-i":52,"./kernel-value/dynamic-single-input":53,"./kernel-value/dynamic-unsigned-array":54,"./kernel-value/dynamic-unsigned-input":55,"./kernel-value/float":56,"./kernel-value/html-image":57,"./kernel-value/html-video":58,"./kernel-value/integer":60,"./kernel-value/memory-optimized-number-texture":61,"./kernel-value/number-texture":62,"./kernel-value/single-array":63,"./kernel-value/single-array1d-i":64,"./kernel-value/single-array2d-i":65,"./kernel-value/single-array3d-i":66,"./kernel-value/single-input":67,"./kernel-value/unsigned-array":68,"./kernel-value/unsigned-input":69}],40:[function(require,module,exports){
+const { WebGLKernelValue } = require('./index');
+const { Input } = require('../../../input');
+
+class WebGLKernelArray extends WebGLKernelValue {
+ checkSize(width, height) {
+ if (!this.kernel.validate) return;
+ const { maxTextureSize } = this.kernel.constructor.features;
+ if (width > maxTextureSize || height > maxTextureSize) {
+ if (width > height) {
+ throw new Error(`Argument texture width of ${width} larger than maximum size of ${maxTextureSize} for your GPU`);
+ } else if (width < height) {
+ throw new Error(`Argument texture height of ${height} larger than maximum size of ${maxTextureSize} for your GPU`);
+ } else {
+ throw new Error(`Argument texture height and width of ${height} larger than maximum size of ${maxTextureSize} for your GPU`);
+ }
+ }
+ }
+
+ setup() {
+ this.requestTexture();
+ this.setupTexture();
+ this.defineTexture();
+ }
+
+ requestTexture() {
+ this.texture = this.onRequestTexture();
+ }
+
+ defineTexture() {
+ const { context: gl } = this;
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ }
+
+ setupTexture() {
+ this.contextHandle = this.onRequestContextHandle();
+ this.index = this.onRequestIndex();
+ this.dimensionsId = this.id + 'Dim';
+ this.sizeId = this.id + 'Size';
+ }
+
+ getBitRatio(value) {
+ if (Array.isArray(value[0])) {
+ return this.getBitRatio(value[0]);
+ } else if (value.constructor === Input) {
+ return this.getBitRatio(value.value);
+ }
+ switch (value.constructor) {
+ case Uint8ClampedArray:
+ case Uint8Array:
+ case Int8Array:
+ return 1;
+ case Uint16Array:
+ case Int16Array:
+ return 2;
+ case Float32Array:
+ case Int32Array:
+ default:
+ return 4;
+ }
+ }
+
+ destroy() {
+ if (this.prevArg) {
+ this.prevArg.delete();
+ }
+ this.context.deleteTexture(this.texture);
+ }
+}
+
+module.exports = {
+ WebGLKernelArray
+};
+},{"../../../input":110,"./index":59}],41:[function(require,module,exports){
+const { WebGLKernelValue } = require('./index');
+
+class WebGLKernelValueArray2 extends WebGLKernelValue {
+ constructor(value, settings) {
+ super(value, settings);
+ this.uploadValue = value;
+ }
+ getSource(value) {
+ if (this.origin === 'constants') {
+ return `const vec2 ${this.id} = vec2(${value[0]},${value[1]});\n`;
+ }
+ return `uniform vec2 ${this.id};\n`;
+ }
+
+ getStringValueHandler() {
+ if (this.origin === 'constants') return '';
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+
+ updateValue(value) {
+ if (this.origin === 'constants') return;
+ this.kernel.setUniform2fv(this.id, this.uploadValue = value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueArray2
+};
+},{"./index":59}],42:[function(require,module,exports){
+const { WebGLKernelValue } = require('./index');
+
+class WebGLKernelValueArray3 extends WebGLKernelValue {
+ constructor(value, settings) {
+ super(value, settings);
+ this.uploadValue = value;
+ }
+ getSource(value) {
+ if (this.origin === 'constants') {
+ return `const vec3 ${this.id} = vec3(${value[0]},${value[1]},${value[2]});\n`;
+ }
+ return `uniform vec3 ${this.id};\n`;
+ }
+
+ getStringValueHandler() {
+ if (this.origin === 'constants') return '';
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+
+ updateValue(value) {
+ if (this.origin === 'constants') return;
+ this.kernel.setUniform3fv(this.id, this.uploadValue = value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueArray3
+};
+},{"./index":59}],43:[function(require,module,exports){
+const { WebGLKernelValue } = require('./index');
+
+class WebGLKernelValueArray4 extends WebGLKernelValue {
+ constructor(value, settings) {
+ super(value, settings);
+ this.uploadValue = value;
+ }
+ getSource(value) {
+ if (this.origin === 'constants') {
+ return `const vec4 ${this.id} = vec4(${value[0]},${value[1]},${value[2]},${value[3]});\n`;
+ }
+ return `uniform vec4 ${this.id};\n`;
+ }
+
+ getStringValueHandler() {
+ if (this.origin === 'constants') return '';
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+
+ updateValue(value) {
+ if (this.origin === 'constants') return;
+ this.kernel.setUniform4fv(this.id, this.uploadValue = value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueArray4
+};
+},{"./index":59}],44:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValue } = require('./index');
+
+class WebGLKernelValueBoolean extends WebGLKernelValue {
+ constructor(value, settings) {
+ super(value, settings);
+ this.uploadValue = value;
+ }
+ getSource(value) {
+ if (this.origin === 'constants') {
+ return `const bool ${this.id} = ${value};\n`;
+ }
+ return `uniform bool ${this.id};\n`;
+ }
+
+ getStringValueHandler() {
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+
+ updateValue(value) {
+ if (this.origin === 'constants') return;
+ this.kernel.setUniform1i(this.id, this.uploadValue = value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueBoolean
+};
+},{"../../../utils":114,"./index":59}],45:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueHTMLImage } = require('./html-image');
+
+class WebGLKernelValueDynamicHTMLImage extends WebGLKernelValueHTMLImage {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ const { width, height } = value;
+ this.checkSize(width, height);
+ this.dimensions = [width, height, 1];
+ this.textureSize = [width, height];
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicHTMLImage
+};
+},{"../../../utils":114,"./html-image":57}],46:[function(require,module,exports){
+const { WebGLKernelValueDynamicHTMLImage } = require('./dynamic-html-image');
+
+class WebGLKernelValueDynamicHTMLVideo extends WebGLKernelValueDynamicHTMLImage {}
+
+module.exports = {
+ WebGLKernelValueDynamicHTMLVideo
+};
+},{"./dynamic-html-image":45}],47:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueMemoryOptimizedNumberTexture } = require('./memory-optimized-number-texture');
+
+class WebGLKernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(inputTexture) {
+ this.dimensions = inputTexture.dimensions;
+ this.checkSize(inputTexture.size[0], inputTexture.size[1]);
+ this.textureSize = inputTexture.size;
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(inputTexture);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicMemoryOptimizedNumberTexture
+};
+},{"../../../utils":114,"./memory-optimized-number-texture":61}],48:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueNumberTexture } = require('./number-texture');
+
+class WebGLKernelValueDynamicNumberTexture extends WebGLKernelValueNumberTexture {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.dimensions = value.dimensions;
+ this.checkSize(value.size[0], value.size[1]);
+ this.textureSize = value.size;
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicNumberTexture
+};
+},{"../../../utils":114,"./number-texture":62}],49:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray } = require('./single-array');
+
+class WebGLKernelValueDynamicSingleArray extends WebGLKernelValueSingleArray {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.dimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.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(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicSingleArray
+};
+},{"../../../utils":114,"./single-array":63}],50:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray1DI } = require('./single-array1d-i');
+
+class WebGLKernelValueDynamicSingleArray1DI extends WebGLKernelValueSingleArray1DI {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.setShape(value);
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicSingleArray1DI
+};
+},{"../../../utils":114,"./single-array1d-i":64}],51:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray2DI } = require('./single-array2d-i');
+
+class WebGLKernelValueDynamicSingleArray2DI extends WebGLKernelValueSingleArray2DI {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.setShape(value);
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicSingleArray2DI
+};
+},{"../../../utils":114,"./single-array2d-i":65}],52:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray3DI } = require('./single-array3d-i');
+
+class WebGLKernelValueDynamicSingleArray3DI extends WebGLKernelValueSingleArray3DI {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.setShape(value);
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicSingleArray3DI
+};
+},{"../../../utils":114,"./single-array3d-i":66}],53:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleInput } = require('./single-input');
+
+class WebGLKernelValueDynamicSingleInput extends WebGLKernelValueSingleInput {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ let [w, h, d] = value.size;
+ this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);
+ this.textureSize = utils.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(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicSingleInput
+};
+},{"../../../utils":114,"./single-input":67}],54:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueUnsignedArray } = require('./unsigned-array');
+
+class WebGLKernelValueDynamicUnsignedArray extends WebGLKernelValueUnsignedArray {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.dimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.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 Type = this.getTransferArrayType(value);
+ this.preUploadValue = new Type(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(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicUnsignedArray
+};
+},{"../../../utils":114,"./unsigned-array":68}],55:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueUnsignedInput } = require('./unsigned-input');
+
+class WebGLKernelValueDynamicUnsignedInput extends WebGLKernelValueUnsignedInput {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ let [w, h, d] = value.size;
+ this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);
+ this.textureSize = utils.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 Type = this.getTransferArrayType(value.value);
+ this.preUploadValue = new Type(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(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicUnsignedInput
+};
+},{"../../../utils":114,"./unsigned-input":69}],56:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValue } = require('./index');
+
+class WebGLKernelValueFloat extends WebGLKernelValue {
+ constructor(value, settings) {
+ super(value, settings);
+ this.uploadValue = value;
+ }
+ getStringValueHandler() {
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+ getSource(value) {
+ if (this.origin === 'constants') {
+ if (Number.isInteger(value)) {
+ return `const float ${this.id} = ${value}.0;\n`;
+ }
+ return `const float ${this.id} = ${value};\n`;
+ }
+ return `uniform float ${this.id};\n`;
+ }
+
+ updateValue(value) {
+ if (this.origin === 'constants') return;
+ this.kernel.setUniform1f(this.id, this.uploadValue = value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueFloat
+};
+},{"../../../utils":114,"./index":59}],57:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueHTMLImage extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ const { width, height } = value;
+ this.checkSize(width, height);
+ this.dimensions = [width, height, 1];
+ this.textureSize = [width, height];
+ this.uploadValue = value;
+ }
+
+ getStringValueHandler() {
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+
+ getSource() {
+ return utils.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(inputImage) {
+ if (inputImage.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(inputImage.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue = inputImage);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueHTMLImage
+};
+},{"../../../utils":114,"./array":40}],58:[function(require,module,exports){
+const { WebGLKernelValueHTMLImage } = require('./html-image');
+
+class WebGLKernelValueHTMLVideo extends WebGLKernelValueHTMLImage {}
+
+module.exports = {
+ WebGLKernelValueHTMLVideo
+};
+},{"./html-image":57}],59:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { KernelValue } = require('../../kernel-value');
+
+class WebGLKernelValue extends KernelValue {
+ constructor(value, settings) {
+ super(value, settings);
+ this.dimensionsId = null;
+ this.sizeId = null;
+ this.initialValueConstructor = value.constructor;
+ this.onRequestTexture = settings.onRequestTexture;
+ this.onRequestIndex = settings.onRequestIndex;
+ this.uploadValue = null;
+ this.textureSize = null;
+ this.bitRatio = null;
+ this.prevArg = null;
+ }
+
+ get id() {
+ return `${this.origin}_${utils.sanitizeName(this.name)}`;
+ }
+
+ setup() {}
+
+ getTransferArrayType(value) {
+ if (Array.isArray(value[0])) {
+ return this.getTransferArrayType(value[0]);
+ }
+ switch (value.constructor) {
+ case Array:
+ case Int32Array:
+ case Int16Array:
+ case Int8Array:
+ return Float32Array;
+ case Uint8ClampedArray:
+ case Uint8Array:
+ case Uint16Array:
+ case Uint32Array:
+ case Float32Array:
+ case Float64Array:
+ return value.constructor;
+ }
+ console.warn('Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros');
+ return value.constructor;
+ }
+
+ getStringValueHandler() {
+ throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`);
+ }
+
+ getVariablePrecisionString() {
+ return this.kernel.getVariablePrecisionString(this.textureSize || undefined, this.tactic || undefined);
+ }
+
+ destroy() {}
+}
+
+module.exports = {
+ WebGLKernelValue
+};
+},{"../../../utils":114,"../../kernel-value":35}],60:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValue } = require('./index');
+
+class WebGLKernelValueInteger extends WebGLKernelValue {
+ constructor(value, settings) {
+ super(value, settings);
+ this.uploadValue = value;
+ }
+ getStringValueHandler() {
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+ getSource(value) {
+ if (this.origin === 'constants') {
+ return `const int ${this.id} = ${ parseInt(value) };\n`;
+ }
+ return `uniform int ${this.id};\n`;
+ }
+
+ updateValue(value) {
+ if (this.origin === 'constants') return;
+ this.kernel.setUniform1i(this.id, this.uploadValue = value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueInteger
+};
+},{"../../../utils":114,"./index":59}],61:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+const sameError = `Source and destination textures are the same. Use immutable = true and manually cleanup kernel output texture memory with texture.delete()`;
+
+class WebGLKernelValueMemoryOptimizedNumberTexture extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ const [width, height] = value.size;
+ this.checkSize(width, height);
+ this.dimensions = value.dimensions;
+ this.textureSize = value.size;
+ this.uploadValue = value.texture;
+ this.forceUploadEachRun = true;
+ }
+
+ setup() {
+ this.setupTexture();
+ }
+
+ getStringValueHandler() {
+ return `const uploadValue_${this.name} = ${this.varName}.texture;\n`;
+ }
+
+ getSource() {
+ return utils.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(inputTexture) {
+ if (inputTexture.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(inputTexture.constructor);
+ return;
+ }
+ if (this.checkContext && inputTexture.context !== this.context) {
+ throw new Error(`Value ${this.name} (${this.type}) must be from same context`);
+ }
+
+ const { kernel, context: gl } = this;
+ if (kernel.pipeline) {
+ if (kernel.immutable) {
+ kernel.updateTextureArgumentRefs(this, inputTexture);
+ } else {
+ if (kernel.texture && kernel.texture.texture === inputTexture.texture) {
+ throw new Error(sameError);
+ } else if (kernel.mappedTextures) {
+ const { mappedTextures } = kernel;
+ for (let i = 0; i < mappedTextures.length; i++) {
+ if (mappedTextures[i].texture === inputTexture.texture) {
+ throw new Error(sameError);
+ }
+ }
+ }
+ }
+ }
+
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueMemoryOptimizedNumberTexture,
+ sameError
+};
+},{"../../../utils":114,"./array":40}],62:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+const { sameError } = require('./memory-optimized-number-texture');
+
+class WebGLKernelValueNumberTexture extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ const [width, height] = value.size;
+ this.checkSize(width, height);
+ const { size: textureSize, dimensions } = value;
+ this.bitRatio = this.getBitRatio(value);
+ this.dimensions = dimensions;
+ this.textureSize = textureSize;
+ this.uploadValue = value.texture;
+ this.forceUploadEachRun = true;
+ }
+
+ setup() {
+ this.setupTexture();
+ }
+
+ getStringValueHandler() {
+ return `const uploadValue_${this.name} = ${this.varName}.texture;\n`;
+ }
+
+ getSource() {
+ return utils.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(inputTexture) {
+ if (inputTexture.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(inputTexture.constructor);
+ return;
+ }
+ if (this.checkContext && inputTexture.context !== this.context) {
+ throw new Error(`Value ${this.name} (${this.type}) must be from same context`);
+ }
+
+ const { kernel, context: gl } = this;
+ if (kernel.pipeline) {
+ if (kernel.immutable) {
+ kernel.updateTextureArgumentRefs(this, inputTexture);
+ } else {
+ if (kernel.texture && kernel.texture.texture === inputTexture.texture) {
+ throw new Error(sameError);
+ } else if (kernel.mappedTextures) {
+ const { mappedTextures } = kernel;
+ for (let i = 0; i < mappedTextures.length; i++) {
+ if (mappedTextures[i].texture === inputTexture.texture) {
+ throw new Error(sameError);
+ }
+ }
+ }
+ }
+ }
+
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueNumberTexture
+};
+},{"../../../utils":114,"./array":40,"./memory-optimized-number-texture":61}],63:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueSingleArray extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.bitRatio = 4;
+ this.dimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.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 utils.linesToString([
+ `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,
+ `flattenTo(${this.varName}, uploadValue_${this.name})`,
+ ]);
+ }
+
+ getSource() {
+ return utils.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(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueSingleArray
+};
+},{"../../../utils":114,"./array":40}],64:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueSingleArray1DI extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.bitRatio = 4;
+ this.setShape(value);
+ }
+
+ setShape(value) {
+ const valueDimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio);
+ this.dimensions = new Int32Array([valueDimensions[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 utils.linesToString([
+ `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,
+ `flattenTo(${this.varName}, uploadValue_${this.name})`,
+ ]);
+ }
+
+ getSource() {
+ return utils.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(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flatten2dArrayTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueSingleArray1DI
+};
+},{"../../../utils":114,"./array":40}],65:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueSingleArray2DI extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.bitRatio = 4;
+ this.setShape(value);
+ }
+
+ setShape(value) {
+ const valueDimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio);
+ this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[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 utils.linesToString([
+ `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,
+ `flattenTo(${this.varName}, uploadValue_${this.name})`,
+ ]);
+ }
+
+ getSource() {
+ return utils.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(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flatten3dArrayTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueSingleArray2DI
+};
+},{"../../../utils":114,"./array":40}],66:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueSingleArray3DI extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.bitRatio = 4;
+ this.setShape(value);
+ }
+
+ setShape(value) {
+ const valueDimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio);
+ this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], valueDimensions[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 utils.linesToString([
+ `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,
+ `flattenTo(${this.varName}, uploadValue_${this.name})`,
+ ]);
+ }
+
+ getSource() {
+ return utils.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(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flatten4dArrayTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueSingleArray3DI
+};
+},{"../../../utils":114,"./array":40}],67:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueSingleInput extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.bitRatio = 4;
+ let [w, h, d] = value.size;
+ this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);
+ this.textureSize = utils.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 utils.linesToString([
+ `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,
+ `flattenTo(${this.varName}.value, uploadValue_${this.name})`,
+ ]);
+ }
+
+ getSource() {
+ return utils.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(input) {
+ if (input.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(input.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(input.value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueSingleInput
+};
+},{"../../../utils":114,"./array":40}],68:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueUnsignedArray extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.bitRatio = this.getBitRatio(value);
+ this.dimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.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(value);
+ this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength);
+ this.uploadValue = new Uint8Array(this.preUploadValue.buffer);
+ }
+
+ getStringValueHandler() {
+ return utils.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 utils.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(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(value, this.preUploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueUnsignedArray
+};
+},{"../../../utils":114,"./array":40}],69:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueUnsignedInput extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.bitRatio = this.getBitRatio(value);
+ const [w, h, d] = value.size;
+ this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);
+ this.textureSize = utils.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(value.value);
+ this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength);
+ this.uploadValue = new Uint8Array(this.preUploadValue.buffer);
+ }
+
+ getStringValueHandler() {
+ return utils.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 utils.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(input) {
+ if (input.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(input.value, this.preUploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueUnsignedInput
+};
+},{"../../../utils":114,"./array":40}],70:[function(require,module,exports){
+const { GLKernel } = require('../gl/kernel');
+const { FunctionBuilder } = require('../function-builder');
+const { WebGLFunctionNode } = require('./function-node');
+const { utils } = require('../../utils');
+const mrud = require('../../plugins/math-random-uniformly-distributed');
+const { fragmentShader } = require('./fragment-shader');
+const { vertexShader } = require('./vertex-shader');
+const { glKernelString } = require('../gl/kernel-string');
+const { lookupKernelValueType } = require('./kernel-value-maps');
+
+let isSupported = null;
+let testCanvas = null;
+let testContext = null;
+let testExtensions = null;
+let features = null;
+
+const plugins = [mrud];
+const canvases = [];
+const maxTexSizes = {};
+
+
+class WebGLKernel extends GLKernel {
+ static get isSupported() {
+ if (isSupported !== null) {
+ return isSupported;
+ }
+ this.setupFeatureChecks();
+ isSupported = this.isContextMatch(testContext);
+ return isSupported;
+ }
+
+ static setupFeatureChecks() {
+ if (typeof document !== 'undefined') {
+ testCanvas = document.createElement('canvas');
+ } else if (typeof OffscreenCanvas !== 'undefined') {
+ testCanvas = new OffscreenCanvas(0, 0);
+ }
+ if (!testCanvas) return;
+ testContext = testCanvas.getContext('webgl') || testCanvas.getContext('experimental-webgl');
+ if (!testContext || !testContext.getExtension) return;
+ testExtensions = {
+ OES_texture_float: testContext.getExtension('OES_texture_float'),
+ OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'),
+ OES_element_index_uint: testContext.getExtension('OES_element_index_uint'),
+ WEBGL_draw_buffers: testContext.getExtension('WEBGL_draw_buffers'),
+ };
+ features = this.getFeatures();
+ }
+
+ static isContextMatch(context) {
+ if (typeof WebGLRenderingContext !== 'undefined') {
+ return context instanceof WebGLRenderingContext;
+ }
+ return false;
+ }
+
+ static getIsTextureFloat() {
+ return Boolean(testExtensions.OES_texture_float);
+ }
+
+ static getIsDrawBuffers() {
+ return Boolean(testExtensions.WEBGL_draw_buffers);
+ }
+
+ static getChannelCount() {
+ return testExtensions.WEBGL_draw_buffers ?
+ testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) :
+ 1;
+ }
+
+ static getMaxTextureSize() {
+ return testContext.getParameter(testContext.MAX_TEXTURE_SIZE);
+ }
+
+ static lookupKernelValueType(type, dynamic, precision, value) {
+ return lookupKernelValueType(type, dynamic, precision, value);
+ }
+
+ static get testCanvas() {
+ return testCanvas;
+ }
+
+ static get testContext() {
+ return testContext;
+ }
+
+ static get features() {
+ return features;
+ }
+
+ static get fragmentShader() {
+ return fragmentShader;
+ }
+
+ static get vertexShader() {
+ return vertexShader;
+ }
+
+ constructor(source, settings) {
+ super(source, settings);
+ this.program = null;
+ this.pipeline = settings.pipeline;
+ this.endianness = utils.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(source.settings || settings);
+
+ 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 (typeof document !== 'undefined') {
+ const canvas = document.createElement('canvas');
+ canvas.width = 2;
+ canvas.height = 2;
+ return canvas;
+ } else if (typeof OffscreenCanvas !== 'undefined') {
+ return new OffscreenCanvas(0, 0);
+ }
+ }
+
+ initContext() {
+ const settings = {
+ alpha: false,
+ depth: false,
+ antialias: false
+ };
+ return this.canvas.getContext('webgl', settings) || this.canvas.getContext('experimental-webgl', settings);
+ }
+
+ initPlugins(settings) {
+ const pluginsToUse = [];
+ const { source } = this;
+ if (typeof source === 'string') {
+ for (let i = 0; i < plugins.length; i++) {
+ const plugin = plugins[i];
+ if (source.match(plugin.functionMatch)) {
+ pluginsToUse.push(plugin);
+ }
+ }
+ } else if (typeof source === 'object') {
+ if (settings.pluginNames) {
+ for (let i = 0; i < plugins.length; i++) {
+ const plugin = plugins[i];
+ const usePlugin = settings.pluginNames.some(pluginName => pluginName === plugin.name);
+ if (usePlugin) {
+ pluginsToUse.push(plugin);
+ }
+ }
+ }
+ }
+ return pluginsToUse;
+ }
+
+ 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(args) {
+ if (!this.validate) {
+ this.texSize = utils.getKernelTextureSize({
+ optimizeFloatMemory: this.optimizeFloatMemory,
+ precision: this.precision,
+ }, this.output);
+ return;
+ }
+
+ const { features } = this.constructor;
+
+ if (this.optimizeFloatMemory === true && !features.isTextureFloat) {
+ throw new Error('Float textures are not supported');
+ } else if (this.precision === 'single' && !features.isFloatRead) {
+ throw new Error('Single precision not supported');
+ } else if (!this.graphical && this.precision === null && features.isTextureFloat) {
+ this.precision = features.isFloatRead ? 'single' : 'unsigned';
+ }
+
+ if (this.subKernels && this.subKernels.length > 0 && !this.extensions.WEBGL_draw_buffers) {
+ throw new Error('could not instantiate draw buffers extension');
+ }
+
+ if (this.fixIntegerDivisionAccuracy === null) {
+ this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate;
+ } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) {
+ this.fixIntegerDivisionAccuracy = false;
+ }
+
+ this.checkOutput();
+
+ 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);
+ switch (argType) {
+ case 'Array':
+ this.output = utils.getDimensions(argType);
+ break;
+ case 'NumberTexture':
+ case 'MemoryOptimizedNumberTexture':
+ case 'ArrayTexture(1)':
+ case 'ArrayTexture(2)':
+ case 'ArrayTexture(3)':
+ case 'ArrayTexture(4)':
+ this.output = args[0].output;
+ break;
+ default:
+ throw new Error('Auto output not supported for input type: ' + argType);
+ }
+ }
+
+ if (this.graphical) {
+ if (this.output.length !== 2) {
+ throw new Error('Output must have 2 dimensions on graphical mode');
+ }
+
+ if (this.precision === 'precision') {
+ this.precision = 'unsigned';
+ console.warn('Cannot use graphical mode and single precision at the same time');
+ }
+
+ this.texSize = utils.clone(this.output);
+ return;
+ } else if (this.precision === null && features.isTextureFloat) {
+ this.precision = 'single';
+ }
+
+ this.texSize = utils.getKernelTextureSize({
+ optimizeFloatMemory: this.optimizeFloatMemory,
+ precision: this.precision,
+ }, this.output);
+
+ this.checkTextureSize();
+ }
+
+ updateMaxTexSize() {
+ const { texSize, canvas } = this;
+ if (this.maxTexSize === null) {
+ let canvasIndex = canvases.indexOf(canvas);
+ if (canvasIndex === -1) {
+ canvasIndex = canvases.length;
+ canvases.push(canvas);
+ maxTexSizes[canvasIndex] = [texSize[0], texSize[1]];
+ }
+ this.maxTexSize = maxTexSizes[canvasIndex];
+ }
+ if (this.maxTexSize[0] < texSize[0]) {
+ this.maxTexSize[0] = texSize[0];
+ }
+ if (this.maxTexSize[1] < texSize[1]) {
+ this.maxTexSize[1] = texSize[1];
+ }
+ }
+
+ setupArguments(args) {
+ this.kernelArguments = [];
+ this.argumentTextureCount = 0;
+ const needsArgumentTypes = this.argumentTypes === null;
+ if (needsArgumentTypes) {
+ this.argumentTypes = [];
+ }
+ this.argumentSizes = [];
+ this.argumentBitRatios = [];
+
+ if (args.length < this.argumentNames.length) {
+ throw new Error('not enough arguments for kernel');
+ } else if (args.length > this.argumentNames.length) {
+ throw new Error('too many arguments for kernel');
+ }
+
+ const { context: gl } = this;
+ let textureIndexes = 0;
+
+ const onRequestTexture = () => {
+ return this.createTexture();
+ };
+ const onRequestIndex = () => {
+ return this.constantTextureCount + textureIndexes++;
+ };
+ const onUpdateValueMismatch = (constructor) => {
+ this.switchKernels({
+ type: 'argumentMismatch',
+ needed: constructor
+ });
+ };
+ const onRequestContextHandle = () => {
+ return gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount++;
+ };
+
+ for (let index = 0; index < args.length; index++) {
+ const value = args[index];
+ const name = this.argumentNames[index];
+ let type;
+ if (needsArgumentTypes) {
+ type = utils.getVariableType(value, this.strictIntegers);
+ this.argumentTypes.push(type);
+ } else {
+ type = this.argumentTypes[index];
+ }
+ const KernelValue = this.constructor.lookupKernelValueType(type, this.dynamicArguments ? 'dynamic' : 'static', this.precision, args[index]);
+ if (KernelValue === null) {
+ return this.requestFallback(args);
+ }
+ const kernelArgument = new KernelValue(value, {
+ name,
+ type,
+ tactic: this.tactic,
+ origin: 'user',
+ context: gl,
+ checkContext: this.checkContext,
+ kernel: this,
+ strictIntegers: this.strictIntegers,
+ onRequestTexture,
+ onRequestIndex,
+ onUpdateValueMismatch,
+ onRequestContextHandle,
+ });
+ this.kernelArguments.push(kernelArgument);
+ kernelArgument.setup();
+ this.argumentSizes.push(kernelArgument.textureSize);
+ this.argumentBitRatios[index] = kernelArgument.bitRatio;
+ }
+ }
+
+ createTexture() {
+ const texture = this.context.createTexture();
+ this.textureCache.push(texture);
+ return texture;
+ }
+
+ setupConstants(args) {
+ const { context: gl } = this;
+ this.kernelConstants = [];
+ this.forceUploadKernelConstants = [];
+ let needsConstantTypes = this.constantTypes === null;
+ if (needsConstantTypes) {
+ this.constantTypes = {};
+ }
+ this.constantBitRatios = {};
+ let textureIndexes = 0;
+ for (const name in this.constants) {
+ const value = this.constants[name];
+ let type;
+ if (needsConstantTypes) {
+ type = utils.getVariableType(value, this.strictIntegers);
+ this.constantTypes[name] = type;
+ } else {
+ type = this.constantTypes[name];
+ }
+ const KernelValue = this.constructor.lookupKernelValueType(type, 'static', this.precision, value);
+ if (KernelValue === null) {
+ return this.requestFallback(args);
+ }
+ const kernelValue = new KernelValue(value, {
+ name,
+ type,
+ tactic: this.tactic,
+ origin: 'constants',
+ context: this.context,
+ checkContext: this.checkContext,
+ kernel: this,
+ strictIntegers: this.strictIntegers,
+ onRequestTexture: () => {
+ return this.createTexture();
+ },
+ onRequestIndex: () => {
+ return textureIndexes++;
+ },
+ onRequestContextHandle: () => {
+ return gl.TEXTURE0 + this.constantTextureCount++;
+ }
+ });
+ this.constantBitRatios[name] = kernelValue.bitRatio;
+ this.kernelConstants.push(kernelValue);
+ kernelValue.setup();
+ if (kernelValue.forceUploadEachRun) {
+ this.forceUploadKernelConstants.push(kernelValue);
+ }
+ }
+ }
+
+ build() {
+ if (this.built) return;
+ this.initExtensions();
+ this.validateSettings(arguments);
+ this.setupConstants(arguments);
+ if (this.fallbackRequested) return;
+ this.setupArguments(arguments);
+ if (this.fallbackRequested) return;
+ this.updateMaxTexSize();
+ this.translateSource();
+ const failureResult = this.pickRenderStrategy(arguments);
+ if (failureResult) {
+ return failureResult;
+ }
+ const { texSize, context: gl, canvas } = this;
+ gl.enable(gl.SCISSOR_TEST);
+ if (this.pipeline && this.precision === 'single') {
+ gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);
+ canvas.width = this.maxTexSize[0];
+ canvas.height = this.maxTexSize[1];
+ } else {
+ gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);
+ canvas.width = this.maxTexSize[0];
+ canvas.height = this.maxTexSize[1];
+ }
+ const threadDim = this.threadDim = Array.from(this.output);
+ while (threadDim.length < 3) {
+ threadDim.push(1);
+ }
+
+ const compiledVertexShader = this.getVertexShader(arguments);
+ const vertShader = gl.createShader(gl.VERTEX_SHADER);
+ gl.shaderSource(vertShader, compiledVertexShader);
+ gl.compileShader(vertShader);
+ this.vertShader = vertShader;
+
+ const compiledFragmentShader = this.getFragmentShader(arguments);
+ const fragShader = gl.createShader(gl.FRAGMENT_SHADER);
+ gl.shaderSource(fragShader, compiledFragmentShader);
+ gl.compileShader(fragShader);
+ this.fragShader = fragShader;
+
+ if (this.debug) {
+ console.log('GLSL Shader Output:');
+ console.log(compiledFragmentShader);
+ }
+
+ if (!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) {
+ throw new Error('Error compiling vertex shader: ' + gl.getShaderInfoLog(vertShader));
+ }
+ if (!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) {
+ throw new Error('Error compiling fragment shader: ' + gl.getShaderInfoLog(fragShader));
+ }
+
+ const program = this.program = gl.createProgram();
+ gl.attachShader(program, vertShader);
+ gl.attachShader(program, fragShader);
+ gl.linkProgram(program);
+ this.framebuffer = gl.createFramebuffer();
+ this.framebuffer.width = texSize[0];
+ this.framebuffer.height = texSize[1];
+ this.rawValueFramebuffers = {};
+
+ const vertices = new Float32Array([-1, -1,
+ 1, -1, -1, 1,
+ 1, 1
+ ]);
+ const texCoords = new Float32Array([
+ 0, 0,
+ 1, 0,
+ 0, 1,
+ 1, 1
+ ]);
+
+ const texCoordOffset = vertices.byteLength;
+
+ let buffer = this.buffer;
+ if (!buffer) {
+ buffer = this.buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, vertices.byteLength + texCoords.byteLength, gl.STATIC_DRAW);
+ } else {
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ }
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices);
+ gl.bufferSubData(gl.ARRAY_BUFFER, texCoordOffset, texCoords);
+
+ const aPosLoc = gl.getAttribLocation(this.program, 'aPos');
+ gl.enableVertexAttribArray(aPosLoc);
+ gl.vertexAttribPointer(aPosLoc, 2, gl.FLOAT, false, 0, 0);
+ const aTexCoordLoc = gl.getAttribLocation(this.program, 'aTexCoord');
+ gl.enableVertexAttribArray(aTexCoordLoc);
+ gl.vertexAttribPointer(aTexCoordLoc, 2, gl.FLOAT, false, 0, texCoordOffset);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
+
+ let i = 0;
+ gl.useProgram(this.program);
+ for (let p in this.constants) {
+ this.kernelConstants[i++].updateValue(this.constants[p]);
+ }
+
+ this._setupOutputTexture();
+ if (
+ this.subKernels !== null &&
+ this.subKernels.length > 0
+ ) {
+ this._mappedTextureSwitched = {};
+ this._setupSubOutputTextures();
+ }
+ this.buildSignature(arguments);
+ this.built = true;
+ }
+
+ translateSource() {
+ const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, {
+ fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy
+ });
+ this.translatedSource = functionBuilder.getPrototypeString('kernel');
+ this.setupReturnTypes(functionBuilder);
+ }
+
+ setupReturnTypes(functionBuilder) {
+ if (!this.graphical && !this.returnType) {
+ this.returnType = functionBuilder.getKernelResultType();
+ }
+
+ if (this.subKernels && this.subKernels.length > 0) {
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const subKernel = this.subKernels[i];
+ if (!subKernel.returnType) {
+ subKernel.returnType = functionBuilder.getSubKernelResultType(i);
+ }
+ }
+ }
+ }
+
+ run() {
+ const { kernelArguments, texSize, forceUploadKernelConstants, context: gl } = this;
+
+ gl.useProgram(this.program);
+ gl.scissor(0, 0, texSize[0], texSize[1]);
+ if (this.dynamicOutput) {
+ this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim));
+ this.setUniform2iv('uTexSize', texSize);
+ }
+
+ this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]);
+
+ for (let i = 0; i < forceUploadKernelConstants.length; i++) {
+ const constant = forceUploadKernelConstants[i];
+ constant.updateValue(this.constants[constant.name]);
+ if (this.switchingKernels) return;
+ }
+ for (let i = 0; i < kernelArguments.length; i++) {
+ kernelArguments[i].updateValue(arguments[i]);
+ if (this.switchingKernels) return;
+ }
+
+ if (this.plugins) {
+ for (let i = 0; i < this.plugins.length; i++) {
+ const plugin = this.plugins[i];
+ if (plugin.onBeforeRun) {
+ plugin.onBeforeRun(this);
+ }
+ }
+ }
+
+ if (this.graphical) {
+ if (this.pipeline) {
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
+ if (this.immutable) {
+ this._replaceOutputTexture();
+ }
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+ return this.immutable ? this.texture.clone() : this.texture;
+ }
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+ return;
+ }
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
+ if (this.immutable) {
+ this._replaceOutputTexture();
+ }
+
+ if (this.subKernels !== null) {
+ if (this.immutable) {
+ this._replaceSubOutputTextures();
+ }
+ this.drawBuffers();
+ }
+
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+ }
+
+ drawBuffers() {
+ this.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(this.drawBuffersMap);
+ }
+
+ getInternalFormat() {
+ return this.context.RGBA;
+ }
+ getTextureFormat() {
+ const { context: gl } = this;
+ switch (this.getInternalFormat()) {
+ case gl.RGBA:
+ return gl.RGBA;
+ default:
+ throw new Error('Unknown internal format');
+ }
+ }
+
+ _replaceOutputTexture() {
+ if (this.texture.beforeMutate() || this._textureSwitched) {
+ const gl = this.context;
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture.texture, 0);
+ this._textureSwitched = false;
+ }
+ }
+
+ _setupOutputTexture() {
+ const gl = this.context;
+ const texSize = this.texSize;
+ if (this.texture) {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture.texture, 0);
+ return;
+ }
+ const texture = this.createTexture();
+ gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ const format = this.getInternalFormat();
+ if (this.precision === 'single') {
+ gl.texImage2D(gl.TEXTURE_2D, 0, format, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);
+ } else {
+ gl.texImage2D(gl.TEXTURE_2D, 0, format, texSize[0], texSize[1], 0, format, gl.UNSIGNED_BYTE, null);
+ }
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ this.texture = new this.TextureConstructor({
+ texture,
+ size: texSize,
+ dimensions: this.threadDim,
+ output: this.output,
+ context: this.context,
+ internalFormat: this.getInternalFormat(),
+ textureFormat: this.getTextureFormat(),
+ kernel: this,
+ });
+ }
+
+ _replaceSubOutputTextures() {
+ const gl = this.context;
+ for (let i = 0; i < this.mappedTextures.length; i++) {
+ const mappedTexture = this.mappedTextures[i];
+ if (mappedTexture.beforeMutate() || this._mappedTextureSwitched[i]) {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, mappedTexture.texture, 0);
+ this._mappedTextureSwitched[i] = false;
+ }
+ }
+ }
+
+ _setupSubOutputTextures() {
+ const gl = this.context;
+ if (this.mappedTextures) {
+ for (let i = 0; i < this.subKernels.length; i++) {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, this.mappedTextures[i].texture, 0);
+ }
+ return;
+ }
+ const texSize = this.texSize;
+ this.drawBuffersMap = [gl.COLOR_ATTACHMENT0];
+ this.mappedTextures = [];
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const texture = this.createTexture();
+ this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1);
+ gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ if (this.precision === 'single') {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);
+ } else {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ }
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0);
+
+ this.mappedTextures.push(new this.TextureConstructor({
+ texture,
+ size: texSize,
+ dimensions: this.threadDim,
+ output: this.output,
+ context: this.context,
+ internalFormat: this.getInternalFormat(),
+ textureFormat: this.getTextureFormat(),
+ kernel: this,
+ }));
+ }
+ }
+
+ setUniform1f(name, value) {
+ if (this.uniform1fCache.hasOwnProperty(name)) {
+ const cache = this.uniform1fCache[name];
+ if (value === cache) {
+ return;
+ }
+ }
+ this.uniform1fCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform1f(loc, value);
+ }
+
+ setUniform1i(name, value) {
+ if (this.uniform1iCache.hasOwnProperty(name)) {
+ const cache = this.uniform1iCache[name];
+ if (value === cache) {
+ return;
+ }
+ }
+ this.uniform1iCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform1i(loc, value);
+ }
+
+ setUniform2f(name, value1, value2) {
+ if (this.uniform2fCache.hasOwnProperty(name)) {
+ const cache = this.uniform2fCache[name];
+ if (
+ value1 === cache[0] &&
+ value2 === cache[1]
+ ) {
+ return;
+ }
+ }
+ this.uniform2fCache[name] = [value1, value2];
+ const loc = this.getUniformLocation(name);
+ this.context.uniform2f(loc, value1, value2);
+ }
+
+ setUniform2fv(name, value) {
+ if (this.uniform2fvCache.hasOwnProperty(name)) {
+ const cache = this.uniform2fvCache[name];
+ if (
+ value[0] === cache[0] &&
+ value[1] === cache[1]
+ ) {
+ return;
+ }
+ }
+ this.uniform2fvCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform2fv(loc, value);
+ }
+
+ setUniform2iv(name, value) {
+ if (this.uniform2ivCache.hasOwnProperty(name)) {
+ const cache = this.uniform2ivCache[name];
+ if (
+ value[0] === cache[0] &&
+ value[1] === cache[1]
+ ) {
+ return;
+ }
+ }
+ this.uniform2ivCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform2iv(loc, value);
+ }
+
+ setUniform3fv(name, value) {
+ if (this.uniform3fvCache.hasOwnProperty(name)) {
+ const cache = this.uniform3fvCache[name];
+ if (
+ value[0] === cache[0] &&
+ value[1] === cache[1] &&
+ value[2] === cache[2]
+ ) {
+ return;
+ }
+ }
+ this.uniform3fvCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform3fv(loc, value);
+ }
+
+ setUniform3iv(name, value) {
+ if (this.uniform3ivCache.hasOwnProperty(name)) {
+ const cache = this.uniform3ivCache[name];
+ if (
+ value[0] === cache[0] &&
+ value[1] === cache[1] &&
+ value[2] === cache[2]
+ ) {
+ return;
+ }
+ }
+ this.uniform3ivCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform3iv(loc, value);
+ }
+
+ setUniform4fv(name, value) {
+ if (this.uniform4fvCache.hasOwnProperty(name)) {
+ const cache = this.uniform4fvCache[name];
+ if (
+ value[0] === cache[0] &&
+ value[1] === cache[1] &&
+ value[2] === cache[2] &&
+ value[3] === cache[3]
+ ) {
+ return;
+ }
+ }
+ this.uniform4fvCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform4fv(loc, value);
+ }
+
+ setUniform4iv(name, value) {
+ if (this.uniform4ivCache.hasOwnProperty(name)) {
+ const cache = this.uniform4ivCache[name];
+ if (
+ value[0] === cache[0] &&
+ value[1] === cache[1] &&
+ value[2] === cache[2] &&
+ value[3] === cache[3]
+ ) {
+ return;
+ }
+ }
+ this.uniform4ivCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform4iv(loc, value);
+ }
+
+ getUniformLocation(name) {
+ if (this.programUniformLocationCache.hasOwnProperty(name)) {
+ return this.programUniformLocationCache[name];
+ }
+ return this.programUniformLocationCache[name] = this.context.getUniformLocation(this.program, name);
+ }
+
+ _getFragShaderArtifactMap(args) {
+ return {
+ HEADER: this._getHeaderString(),
+ LOOP_MAX: this._getLoopMaxString(),
+ PLUGINS: this._getPluginsString(),
+ CONSTANTS: this._getConstantsString(),
+ DECODE32_ENDIANNESS: this._getDecode32EndiannessString(),
+ ENCODE32_ENDIANNESS: this._getEncode32EndiannessString(),
+ DIVIDE_WITH_INTEGER_CHECK: this._getDivideWithIntegerCheckString(),
+ INJECTED_NATIVE: this._getInjectedNative(),
+ MAIN_CONSTANTS: this._getMainConstantsString(),
+ MAIN_ARGUMENTS: this._getMainArgumentsString(args),
+ KERNEL: this.getKernelString(),
+ MAIN_RESULT: this.getMainResultString(),
+ FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(),
+ INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(),
+ SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(),
+ SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(),
+ };
+ }
+
+ _getVertShaderArtifactMap(args) {
+ return {
+ FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(),
+ INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(),
+ SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(),
+ SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(),
+ };
+ }
+
+ _getHeaderString() {
+ return (
+ this.subKernels !== null ?
+ '#extension GL_EXT_draw_buffers : require\n' :
+ ''
+ );
+ }
+
+ _getLoopMaxString() {
+ return (
+ this.loopMaxIterations ?
+ ` ${parseInt(this.loopMaxIterations)};\n` :
+ ' 1000;\n'
+ );
+ }
+
+ _getPluginsString() {
+ if (!this.plugins) return '\n';
+ return this.plugins.map(plugin => plugin.source && this.source.match(plugin.functionMatch) ? plugin.source : '').join('\n');
+ }
+
+ _getConstantsString() {
+ const result = [];
+ const { threadDim, texSize } = this;
+ if (this.dynamicOutput) {
+ result.push(
+ 'uniform ivec3 uOutputDim',
+ 'uniform ivec2 uTexSize'
+ );
+ } else {
+ result.push(
+ `ivec3 uOutputDim = ivec3(${threadDim[0]}, ${threadDim[1]}, ${threadDim[2]})`,
+ `ivec2 uTexSize = ivec2(${texSize[0]}, ${texSize[1]})`
+ );
+ }
+ return utils.linesToString(result);
+ }
+
+ _getTextureCoordinate() {
+ const subKernels = this.subKernels;
+ if (subKernels === null || subKernels.length < 1) {
+ return 'varying vec2 vTexCoord;\n';
+ } else {
+ return 'out vec2 vTexCoord;\n';
+ }
+ }
+
+ _getDecode32EndiannessString() {
+ return (
+ this.endianness === 'LE' ?
+ '' :
+ ' texel.rgba = texel.abgr;\n'
+ );
+ }
+
+ _getEncode32EndiannessString() {
+ return (
+ this.endianness === 'LE' ?
+ '' :
+ ' texel.rgba = texel.abgr;\n'
+ );
+ }
+
+ _getDivideWithIntegerCheckString() {
+ return this.fixIntegerDivisionAccuracy ?
+ `float divWithIntCheck(float x, float y) {
+ if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) {
+ return float(int(x) / int(y));
+ }
+ return x / y;
+}
+
+float integerCorrectionModulo(float number, float divisor) {
+ if (number < 0.0) {
+ number = abs(number);
+ if (divisor < 0.0) {
+ divisor = abs(divisor);
+ }
+ return -(number - (divisor * floor(divWithIntCheck(number, divisor))));
+ }
+ if (divisor < 0.0) {
+ divisor = abs(divisor);
+ }
+ return number - (divisor * floor(divWithIntCheck(number, divisor)));
+}` :
+ '';
+ }
+
+ _getMainArgumentsString(args) {
+ const results = [];
+ const { argumentNames } = this;
+ for (let i = 0; i < argumentNames.length; i++) {
+ results.push(this.kernelArguments[i].getSource(args[i]));
+ }
+ return results.join('');
+ }
+
+ _getInjectedNative() {
+ return this.injectedNative || '';
+ }
+
+ _getMainConstantsString() {
+ const result = [];
+ const { constants } = this;
+ if (constants) {
+ let i = 0;
+ for (const name in constants) {
+ if (!this.constants.hasOwnProperty(name)) continue;
+ result.push(this.kernelConstants[i++].getSource(this.constants[name]));
+ }
+ }
+ return result.join('');
+ }
+
+ getRawValueFramebuffer(width, height) {
+ if (!this.rawValueFramebuffers[width]) {
+ this.rawValueFramebuffers[width] = {};
+ }
+ if (!this.rawValueFramebuffers[width][height]) {
+ const framebuffer = this.context.createFramebuffer();
+ framebuffer.width = width;
+ framebuffer.height = height;
+ this.rawValueFramebuffers[width][height] = framebuffer;
+ }
+ return this.rawValueFramebuffers[width][height];
+ }
+
+ getKernelResultDeclaration() {
+ switch (this.returnType) {
+ case 'Array(2)':
+ return 'vec2 kernelResult';
+ case 'Array(3)':
+ return 'vec3 kernelResult';
+ case 'Array(4)':
+ return 'vec4 kernelResult';
+ case 'LiteralInteger':
+ case 'Float':
+ case 'Number':
+ case 'Integer':
+ return 'float kernelResult';
+ default:
+ if (this.graphical) {
+ return 'float kernelResult';
+ } else {
+ throw new Error(`unrecognized output type "${ this.returnType }"`);
+ }
+ }
+ }
+ getKernelString() {
+ const result = [this.getKernelResultDeclaration()];
+ const { subKernels } = this;
+ if (subKernels !== null) {
+ switch (this.returnType) {
+ case 'Number':
+ case 'Float':
+ case 'Integer':
+ for (let i = 0; i < subKernels.length; i++) {
+ const subKernel = subKernels[i];
+ result.push(
+ subKernel.returnType === 'Integer' ?
+ `int subKernelResult_${ subKernel.name } = 0` :
+ `float subKernelResult_${ subKernel.name } = 0.0`
+ );
+ }
+ break;
+ case 'Array(2)':
+ for (let i = 0; i < subKernels.length; i++) {
+ result.push(
+ `vec2 subKernelResult_${ subKernels[i].name }`
+ );
+ }
+ break;
+ case 'Array(3)':
+ for (let i = 0; i < subKernels.length; i++) {
+ result.push(
+ `vec3 subKernelResult_${ subKernels[i].name }`
+ );
+ }
+ break;
+ case 'Array(4)':
+ for (let i = 0; i < subKernels.length; i++) {
+ result.push(
+ `vec4 subKernelResult_${ subKernels[i].name }`
+ );
+ }
+ break;
+ }
+ }
+
+ return utils.linesToString(result) + this.translatedSource;
+ }
+
+ getMainResultGraphical() {
+ return utils.linesToString([
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' gl_FragColor = actualColor',
+ ]);
+ }
+
+ getMainResultPackedPixels() {
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ return this.getMainResultKernelPackedPixels() +
+ this.getMainResultSubKernelPackedPixels();
+ default:
+ throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`);
+ }
+ }
+
+ getMainResultKernelPackedPixels() {
+ return utils.linesToString([
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ` gl_FragData[0] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)`
+ ]);
+ }
+
+ getMainResultSubKernelPackedPixels() {
+ const result = [];
+ if (!this.subKernels) return '';
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const subKernel = this.subKernels[i];
+ if (subKernel.returnType === 'Integer') {
+ result.push(
+ ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))`
+ );
+ } else {
+ result.push(
+ ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})`
+ );
+ }
+ }
+ return utils.linesToString(result);
+ }
+
+ getMainResultMemoryOptimizedFloats() {
+ const result = [
+ ' index *= 4',
+ ];
+
+ switch (this.returnType) {
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ const channels = ['r', 'g', 'b', 'a'];
+ for (let i = 0; i < channels.length; i++) {
+ const channel = channels[i];
+ this.getMainResultKernelMemoryOptimizedFloats(result, channel);
+ this.getMainResultSubKernelMemoryOptimizedFloats(result, channel);
+ if (i + 1 < channels.length) {
+ result.push(' index += 1');
+ }
+ }
+ break;
+ default:
+ throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`);
+ }
+
+ return utils.linesToString(result);
+ }
+
+ getMainResultKernelMemoryOptimizedFloats(result, channel) {
+ result.push(
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ` gl_FragData[0].${channel} = kernelResult`
+ );
+ }
+
+ getMainResultSubKernelMemoryOptimizedFloats(result, channel) {
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const subKernel = this.subKernels[i];
+ if (subKernel.returnType === 'Integer') {
+ result.push(
+ ` gl_FragData[${i + 1}].${channel} = float(subKernelResult_${this.subKernels[i].name})`
+ );
+ } else {
+ result.push(
+ ` gl_FragData[${i + 1}].${channel} = subKernelResult_${this.subKernels[i].name}`
+ );
+ }
+ }
+ }
+
+ getMainResultKernelNumberTexture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' gl_FragData[0][0] = kernelResult',
+ ];
+ }
+
+ getMainResultSubKernelNumberTexture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ const subKernel = this.subKernels[i];
+ if (subKernel.returnType === 'Integer') {
+ result.push(
+ ` gl_FragData[${i + 1}][0] = float(subKernelResult_${subKernel.name})`
+ );
+ } else {
+ result.push(
+ ` gl_FragData[${i + 1}][0] = subKernelResult_${subKernel.name}`
+ );
+ }
+ }
+ return result;
+ }
+
+ getMainResultKernelArray2Texture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' gl_FragData[0][0] = kernelResult[0]',
+ ' gl_FragData[0][1] = kernelResult[1]',
+ ];
+ }
+
+ getMainResultSubKernelArray2Texture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ result.push(
+ ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,
+ ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`
+ );
+ }
+ return result;
+ }
+
+ getMainResultKernelArray3Texture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' gl_FragData[0][0] = kernelResult[0]',
+ ' gl_FragData[0][1] = kernelResult[1]',
+ ' gl_FragData[0][2] = kernelResult[2]',
+ ];
+ }
+
+ getMainResultSubKernelArray3Texture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ result.push(
+ ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,
+ ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,
+ ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`
+ );
+ }
+ return result;
+ }
+
+ getMainResultKernelArray4Texture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' gl_FragData[0] = kernelResult',
+ ];
+ }
+
+ getMainResultSubKernelArray4Texture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ switch (this.returnType) {
+ case 'Number':
+ case 'Float':
+ case 'Integer':
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ const subKernel = this.subKernels[i];
+ if (subKernel.returnType === 'Integer') {
+ result.push(
+ ` gl_FragData[${i + 1}] = float(subKernelResult_${this.subKernels[i].name})`
+ );
+ } else {
+ result.push(
+ ` gl_FragData[${i + 1}] = subKernelResult_${this.subKernels[i].name}`
+ );
+ }
+ }
+ break;
+ case 'Array(2)':
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ result.push(
+ ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,
+ ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`
+ );
+ }
+ break;
+ case 'Array(3)':
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ result.push(
+ ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,
+ ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,
+ ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`
+ );
+ }
+ break;
+ case 'Array(4)':
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ result.push(
+ ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,
+ ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,
+ ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`,
+ ` gl_FragData[${i + 1}][3] = subKernelResult_${this.subKernels[i].name}[3]`
+ );
+ }
+ break;
+ }
+
+ return result;
+ }
+
+ replaceArtifacts(src, map) {
+ return src.replace(/[ ]*__([A-Z]+[0-9]*([_]?[A-Z]*[0-9]?)*)__;\n/g, (match, artifact) => {
+ if (map.hasOwnProperty(artifact)) {
+ return map[artifact];
+ }
+ throw `unhandled artifact ${artifact}`;
+ });
+ }
+
+ getFragmentShader(args) {
+ if (this.compiledFragmentShader !== null) {
+ return this.compiledFragmentShader;
+ }
+ return this.compiledFragmentShader = this.replaceArtifacts(this.constructor.fragmentShader, this._getFragShaderArtifactMap(args));
+ }
+
+ getVertexShader(args) {
+ if (this.compiledVertexShader !== null) {
+ return this.compiledVertexShader;
+ }
+ return this.compiledVertexShader = this.replaceArtifacts(this.constructor.vertexShader, this._getVertShaderArtifactMap(args));
+ }
+
+ toString() {
+ const setupContextString = utils.linesToString([
+ `const gl = context`,
+ ]);
+ return glKernelString(this.constructor, arguments, this, setupContextString);
+ }
+
+ destroy(removeCanvasReferences) {
+ if (!this.context) return;
+ if (this.buffer) {
+ this.context.deleteBuffer(this.buffer);
+ }
+ if (this.framebuffer) {
+ this.context.deleteFramebuffer(this.framebuffer);
+ }
+ for (const width in this.rawValueFramebuffers) {
+ for (const height in this.rawValueFramebuffers[width]) {
+ this.context.deleteFramebuffer(this.rawValueFramebuffers[width][height]);
+ delete this.rawValueFramebuffers[width][height];
+ }
+ delete this.rawValueFramebuffers[width];
+ }
+ if (this.vertShader) {
+ this.context.deleteShader(this.vertShader);
+ }
+ if (this.fragShader) {
+ this.context.deleteShader(this.fragShader);
+ }
+ if (this.program) {
+ this.context.deleteProgram(this.program);
+ }
+ if (this.texture) {
+ this.texture.delete();
+ const textureCacheIndex = this.textureCache.indexOf(this.texture.texture);
+ if (textureCacheIndex > -1) {
+ this.textureCache.splice(textureCacheIndex, 1);
+ }
+ this.texture = null;
+ }
+ if (this.mappedTextures && this.mappedTextures.length) {
+ for (let i = 0; i < this.mappedTextures.length; i++) {
+ const mappedTexture = this.mappedTextures[i];
+ mappedTexture.delete();
+ const textureCacheIndex = this.textureCache.indexOf(mappedTexture.texture);
+ if (textureCacheIndex > -1) {
+ this.textureCache.splice(textureCacheIndex, 1);
+ }
+ }
+ this.mappedTextures = null;
+ }
+ if (this.kernelArguments) {
+ for (let i = 0; i < this.kernelArguments.length; i++) {
+ this.kernelArguments[i].destroy();
+ }
+ }
+ if (this.kernelConstants) {
+ for (let i = 0; i < this.kernelConstants.length; i++) {
+ this.kernelConstants[i].destroy();
+ }
+ }
+ while (this.textureCache.length > 0) {
+ const texture = this.textureCache.pop();
+ this.context.deleteTexture(texture);
+ }
+ if (removeCanvasReferences) {
+ const idx = canvases.indexOf(this.canvas);
+ if (idx >= 0) {
+ canvases[idx] = null;
+ maxTexSizes[idx] = null;
+ }
+ }
+ this.destroyExtensions();
+ delete this.context;
+ delete this.canvas;
+ if (!this.gpu) return;
+ const i = this.gpu.kernels.indexOf(this);
+ if (i === -1) return;
+ this.gpu.kernels.splice(i, 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(context) {
+ const extension = context.getExtension('WEBGL_lose_context');
+ if (extension) {
+ extension.loseContext();
+ }
+ }
+
+ toJSON() {
+ const json = super.toJSON();
+ json.functionNodes = FunctionBuilder.fromKernel(this, WebGLFunctionNode).toJSON();
+ json.settings.threadDim = this.threadDim;
+ return json;
+ }
+}
+
+module.exports = {
+ WebGLKernel
+};
+},{"../../plugins/math-random-uniformly-distributed":112,"../../utils":114,"../function-builder":9,"../gl/kernel":13,"../gl/kernel-string":12,"./fragment-shader":37,"./function-node":38,"./kernel-value-maps":39,"./vertex-shader":71}],71:[function(require,module,exports){
+const vertexShader = `__FLOAT_TACTIC_DECLARATION__;
+__INT_TACTIC_DECLARATION__;
+__SAMPLER_2D_TACTIC_DECLARATION__;
+
+attribute vec2 aPos;
+attribute vec2 aTexCoord;
+
+varying vec2 vTexCoord;
+uniform vec2 ratio;
+
+void main(void) {
+ gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);
+ vTexCoord = aTexCoord;
+}`;
+
+module.exports = {
+ vertexShader
+};
+},{}],72:[function(require,module,exports){
+const fragmentShader = `#version 300 es
+__HEADER__;
+__FLOAT_TACTIC_DECLARATION__;
+__INT_TACTIC_DECLARATION__;
+__SAMPLER_2D_TACTIC_DECLARATION__;
+__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__;
+
+const int LOOP_MAX = __LOOP_MAX__;
+
+__PLUGINS__;
+__CONSTANTS__;
+
+in vec2 vTexCoord;
+
+float atan2(float v1, float v2) {
+ if (v1 == 0.0 || v2 == 0.0) return 0.0;
+ return atan(v1 / v2);
+}
+
+float cbrt(float x) {
+ if (x >= 0.0) {
+ return pow(x, 1.0 / 3.0);
+ } else {
+ return -pow(x, 1.0 / 3.0);
+ }
+}
+
+float expm1(float x) {
+ return pow(${Math.E}, x) - 1.0;
+}
+
+float fround(highp float x) {
+ return x;
+}
+
+float imul(float v1, float v2) {
+ return float(int(v1) * int(v2));
+}
+
+float log10(float x) {
+ return log2(x) * (1.0 / log2(10.0));
+}
+
+float log1p(float x) {
+ return log(1.0 + x);
+}
+
+float _pow(float v1, float v2) {
+ if (v2 == 0.0) return 1.0;
+ return pow(v1, v2);
+}
+
+float _round(float x) {
+ return floor(x + 0.5);
+}
+
+
+const int BIT_COUNT = 32;
+int modi(int x, int y) {
+ return x - y * (x / y);
+}
+
+int bitwiseOr(int a, int b) {
+ int result = 0;
+ int n = 1;
+
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {
+ result += n;
+ }
+ a = a / 2;
+ b = b / 2;
+ n = n * 2;
+ if(!(a > 0 || b > 0)) {
+ break;
+ }
+ }
+ return result;
+}
+int bitwiseXOR(int a, int b) {
+ int result = 0;
+ int n = 1;
+
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {
+ result += n;
+ }
+ a = a / 2;
+ b = b / 2;
+ n = n * 2;
+ if(!(a > 0 || b > 0)) {
+ break;
+ }
+ }
+ return result;
+}
+int bitwiseAnd(int a, int b) {
+ int result = 0;
+ int n = 1;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {
+ result += n;
+ }
+ a = a / 2;
+ b = b / 2;
+ n = n * 2;
+ if(!(a > 0 && b > 0)) {
+ break;
+ }
+ }
+ return result;
+}
+int bitwiseNot(int a) {
+ int result = 0;
+ int n = 1;
+
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (modi(a, 2) == 0) {
+ result += n;
+ }
+ a = a / 2;
+ n = n * 2;
+ }
+ return result;
+}
+int bitwiseZeroFillLeftShift(int n, int shift) {
+ int maxBytes = BIT_COUNT;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (maxBytes >= n) {
+ break;
+ }
+ maxBytes *= 2;
+ }
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= shift) {
+ break;
+ }
+ n *= 2;
+ }
+
+ int result = 0;
+ int byteVal = 1;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= maxBytes) break;
+ if (modi(n, 2) > 0) { result += byteVal; }
+ n = int(n / 2);
+ byteVal *= 2;
+ }
+ return result;
+}
+
+int bitwiseSignedRightShift(int num, int shifts) {
+ return int(floor(float(num) / pow(2.0, float(shifts))));
+}
+
+int bitwiseZeroFillRightShift(int n, int shift) {
+ int maxBytes = BIT_COUNT;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (maxBytes >= n) {
+ break;
+ }
+ maxBytes *= 2;
+ }
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= shift) {
+ break;
+ }
+ n /= 2;
+ }
+ int result = 0;
+ int byteVal = 1;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= maxBytes) break;
+ if (modi(n, 2) > 0) { result += byteVal; }
+ n = int(n / 2);
+ byteVal *= 2;
+ }
+ return result;
+}
+
+vec2 integerMod(vec2 x, float y) {
+ vec2 res = floor(mod(x, y));
+ return res * step(1.0 - floor(y), -res);
+}
+
+vec3 integerMod(vec3 x, float y) {
+ vec3 res = floor(mod(x, y));
+ return res * step(1.0 - floor(y), -res);
+}
+
+vec4 integerMod(vec4 x, vec4 y) {
+ vec4 res = floor(mod(x, y));
+ return res * step(1.0 - floor(y), -res);
+}
+
+float integerMod(float x, float y) {
+ float res = floor(mod(x, y));
+ return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);
+}
+
+int integerMod(int x, int y) {
+ return x - (y * int(x/y));
+}
+
+__DIVIDE_WITH_INTEGER_CHECK__;
+
+// Here be dragons!
+// DO NOT OPTIMIZE THIS CODE
+// YOU WILL BREAK SOMETHING ON SOMEBODY\'S MACHINE
+// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME
+const vec2 MAGIC_VEC = vec2(1.0, -256.0);
+const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);
+const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536
+float decode32(vec4 texel) {
+ __DECODE32_ENDIANNESS__;
+ texel *= 255.0;
+ vec2 gte128;
+ gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;
+ gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;
+ float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);
+ float res = exp2(round(exponent));
+ texel.b = texel.b - 128.0 * gte128.x;
+ res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;
+ res *= gte128.y * -2.0 + 1.0;
+ return res;
+}
+
+float decode16(vec4 texel, int index) {
+ int channel = integerMod(index, 2);
+ return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0;
+}
+
+float decode8(vec4 texel, int index) {
+ int channel = integerMod(index, 4);
+ return texel[channel] * 255.0;
+}
+
+vec4 legacyEncode32(float f) {
+ float F = abs(f);
+ float sign = f < 0.0 ? 1.0 : 0.0;
+ float exponent = floor(log2(F));
+ float mantissa = (exp2(-exponent) * F);
+ // exponent += floor(log2(mantissa));
+ vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;
+ texel.rg = integerMod(texel.rg, 256.0);
+ texel.b = integerMod(texel.b, 128.0);
+ texel.a = exponent*0.5 + 63.5;
+ texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;
+ texel = floor(texel);
+ texel *= 0.003921569; // 1/255
+ __ENCODE32_ENDIANNESS__;
+ return texel;
+}
+
+// https://github.com/gpujs/gpu.js/wiki/Encoder-details
+vec4 encode32(float value) {
+ if (value == 0.0) return vec4(0, 0, 0, 0);
+
+ float exponent;
+ float mantissa;
+ vec4 result;
+ float sgn;
+
+ sgn = step(0.0, -value);
+ value = abs(value);
+
+ exponent = floor(log2(value));
+
+ mantissa = value*pow(2.0, -exponent)-1.0;
+ exponent = exponent+127.0;
+ result = vec4(0,0,0,0);
+
+ result.a = floor(exponent/2.0);
+ exponent = exponent - result.a*2.0;
+ result.a = result.a + 128.0*sgn;
+
+ result.b = floor(mantissa * 128.0);
+ mantissa = mantissa - result.b / 128.0;
+ result.b = result.b + exponent*128.0;
+
+ result.g = floor(mantissa*32768.0);
+ mantissa = mantissa - result.g/32768.0;
+
+ result.r = floor(mantissa*8388608.0);
+ return result/255.0;
+}
+// Dragons end here
+
+int index;
+ivec3 threadId;
+
+ivec3 indexTo3D(int idx, ivec3 texDim) {
+ int z = int(idx / (texDim.x * texDim.y));
+ idx -= z * int(texDim.x * texDim.y);
+ int y = int(idx / texDim.x);
+ int x = int(integerMod(idx, texDim.x));
+ return ivec3(x, y, z);
+}
+
+float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture(tex, st / vec2(texSize));
+ return decode32(texel);
+}
+
+float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + (texDim.x * (y + (texDim.y * z)));
+ int w = texSize.x * 2;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y));
+ return decode16(texel, index);
+}
+
+float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + (texDim.x * (y + (texDim.y * z)));
+ int w = texSize.x * 4;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y));
+ return decode8(texel, index);
+}
+
+float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + (texDim.x * (y + (texDim.y * z)));
+ int channel = integerMod(index, 4);
+ index = index / 4;
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ index = index / 4;
+ vec4 texel = texture(tex, st / vec2(texSize));
+ return texel[channel];
+}
+
+vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ return texture(tex, st / vec2(texSize));
+}
+
+vec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ return texture(tex, vec3(st / vec2(texSize), z));
+}
+
+float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
+ return result[0];
+}
+
+vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
+ return vec2(result[0], result[1]);
+}
+
+vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int channel = integerMod(index, 2);
+ index = index / 2;
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture(tex, st / vec2(texSize));
+ if (channel == 0) return vec2(texel.r, texel.g);
+ if (channel == 1) return vec2(texel.b, texel.a);
+ return vec2(0.0, 0.0);
+}
+
+vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
+ return vec3(result[0], result[1], result[2]);
+}
+
+vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));
+ int vectorIndex = fieldIndex / 4;
+ int vectorOffset = fieldIndex - vectorIndex * 4;
+ int readY = vectorIndex / texSize.x;
+ int readX = vectorIndex - readY * texSize.x;
+ vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));
+
+ if (vectorOffset == 0) {
+ return tex1.xyz;
+ } else if (vectorOffset == 1) {
+ return tex1.yzw;
+ } else {
+ readX++;
+ if (readX >= texSize.x) {
+ readX = 0;
+ readY++;
+ }
+ vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize));
+ if (vectorOffset == 2) {
+ return vec3(tex1.z, tex1.w, tex2.x);
+ } else {
+ return vec3(tex1.w, tex2.x, tex2.y);
+ }
+ }
+}
+
+vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ return getImage2D(tex, texSize, texDim, z, y, x);
+}
+
+vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int channel = integerMod(index, 2);
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture(tex, st / vec2(texSize));
+ return vec4(texel.r, texel.g, texel.b, texel.a);
+}
+
+vec4 actualColor;
+void color(float r, float g, float b, float a) {
+ actualColor = vec4(r,g,b,a);
+}
+
+void color(float r, float g, float b) {
+ color(r,g,b,1.0);
+}
+
+float modulo(float number, float divisor) {
+ if (number < 0.0) {
+ number = abs(number);
+ if (divisor < 0.0) {
+ divisor = abs(divisor);
+ }
+ return -mod(number, divisor);
+ }
+ if (divisor < 0.0) {
+ divisor = abs(divisor);
+ }
+ return mod(number, divisor);
+}
+
+__INJECTED_NATIVE__;
+__MAIN_CONSTANTS__;
+__MAIN_ARGUMENTS__;
+__KERNEL__;
+
+void main(void) {
+ index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;
+ __MAIN_RESULT__;
+}`;
+
+module.exports = {
+ fragmentShader
+};
+},{}],73:[function(require,module,exports){
+const { utils } = require('../../utils');
+const { WebGLFunctionNode } = require('../web-gl/function-node');
+
+class WebGL2FunctionNode extends WebGLFunctionNode {
+
+ 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('intBitsToFloat(2139095039)');
+ } else if (type === 'Boolean') {
+ if (this.argumentNames.indexOf(name) > -1) {
+ retArr.push(`bool(user_${name})`);
+ } else {
+ retArr.push(`user_${name}`);
+ }
+ } else {
+ retArr.push(`user_${name}`);
+ }
+
+ return retArr;
+ }
+}
+
+module.exports = {
+ WebGL2FunctionNode
+};
+},{"../../utils":114,"../web-gl/function-node":38}],74:[function(require,module,exports){
+const { WebGL2KernelValueBoolean } = require('./kernel-value/boolean');
+const { WebGL2KernelValueFloat } = require('./kernel-value/float');
+const { WebGL2KernelValueInteger } = require('./kernel-value/integer');
+
+const { WebGL2KernelValueHTMLImage } = require('./kernel-value/html-image');
+const { WebGL2KernelValueDynamicHTMLImage } = require('./kernel-value/dynamic-html-image');
+
+const { WebGL2KernelValueHTMLImageArray } = require('./kernel-value/html-image-array');
+const { WebGL2KernelValueDynamicHTMLImageArray } = require('./kernel-value/dynamic-html-image-array');
+
+const { WebGL2KernelValueHTMLVideo } = require('./kernel-value/html-video');
+const { WebGL2KernelValueDynamicHTMLVideo } = require('./kernel-value/dynamic-html-video');
+
+const { WebGL2KernelValueSingleInput } = require('./kernel-value/single-input');
+const { WebGL2KernelValueDynamicSingleInput } = require('./kernel-value/dynamic-single-input');
+
+const { WebGL2KernelValueUnsignedInput } = require('./kernel-value/unsigned-input');
+const { WebGL2KernelValueDynamicUnsignedInput } = require('./kernel-value/dynamic-unsigned-input');
+
+const { WebGL2KernelValueMemoryOptimizedNumberTexture } = require('./kernel-value/memory-optimized-number-texture');
+const { WebGL2KernelValueDynamicMemoryOptimizedNumberTexture } = require('./kernel-value/dynamic-memory-optimized-number-texture');
+
+const { WebGL2KernelValueNumberTexture } = require('./kernel-value/number-texture');
+const { WebGL2KernelValueDynamicNumberTexture } = require('./kernel-value/dynamic-number-texture');
+
+const { WebGL2KernelValueSingleArray } = require('./kernel-value/single-array');
+const { WebGL2KernelValueDynamicSingleArray } = require('./kernel-value/dynamic-single-array');
+
+const { WebGL2KernelValueSingleArray1DI } = require('./kernel-value/single-array1d-i');
+const { WebGL2KernelValueDynamicSingleArray1DI } = require('./kernel-value/dynamic-single-array1d-i');
+
+const { WebGL2KernelValueSingleArray2DI } = require('./kernel-value/single-array2d-i');
+const { WebGL2KernelValueDynamicSingleArray2DI } = require('./kernel-value/dynamic-single-array2d-i');
+
+const { WebGL2KernelValueSingleArray3DI } = require('./kernel-value/single-array3d-i');
+const { WebGL2KernelValueDynamicSingleArray3DI } = require('./kernel-value/dynamic-single-array3d-i');
+
+const { WebGL2KernelValueArray2 } = require('./kernel-value/array2');
+const { WebGL2KernelValueArray3 } = require('./kernel-value/array3');
+const { WebGL2KernelValueArray4 } = require('./kernel-value/array4');
+
+const { WebGL2KernelValueUnsignedArray } = require('./kernel-value/unsigned-array');
+const { WebGL2KernelValueDynamicUnsignedArray } = require('./kernel-value/dynamic-unsigned-array');
+
+const kernelValueMaps = {
+ unsigned: {
+ dynamic: {
+ 'Boolean': WebGL2KernelValueBoolean,
+ 'Integer': WebGL2KernelValueInteger,
+ 'Float': WebGL2KernelValueFloat,
+ 'Array': WebGL2KernelValueDynamicUnsignedArray,
+ 'Array(2)': WebGL2KernelValueArray2,
+ 'Array(3)': WebGL2KernelValueArray3,
+ 'Array(4)': WebGL2KernelValueArray4,
+ 'Array1D(2)': false,
+ 'Array1D(3)': false,
+ 'Array1D(4)': false,
+ 'Array2D(2)': false,
+ 'Array2D(3)': false,
+ 'Array2D(4)': false,
+ 'Array3D(2)': false,
+ 'Array3D(3)': false,
+ 'Array3D(4)': false,
+ 'Input': WebGL2KernelValueDynamicUnsignedInput,
+ 'NumberTexture': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGL2KernelValueDynamicHTMLImage,
+ 'OffscreenCanvas': WebGL2KernelValueDynamicHTMLImage,
+ 'HTMLImage': WebGL2KernelValueDynamicHTMLImage,
+ 'ImageBitmap': WebGL2KernelValueDynamicHTMLImage,
+ 'ImageData': WebGL2KernelValueDynamicHTMLImage,
+ 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray,
+ 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo,
+ },
+ static: {
+ 'Boolean': WebGL2KernelValueBoolean,
+ 'Float': WebGL2KernelValueFloat,
+ 'Integer': WebGL2KernelValueInteger,
+ 'Array': WebGL2KernelValueUnsignedArray,
+ 'Array(2)': WebGL2KernelValueArray2,
+ 'Array(3)': WebGL2KernelValueArray3,
+ 'Array(4)': WebGL2KernelValueArray4,
+ 'Array1D(2)': false,
+ 'Array1D(3)': false,
+ 'Array1D(4)': false,
+ 'Array2D(2)': false,
+ 'Array2D(3)': false,
+ 'Array2D(4)': false,
+ 'Array3D(2)': false,
+ 'Array3D(3)': false,
+ 'Array3D(4)': false,
+ 'Input': WebGL2KernelValueUnsignedInput,
+ 'NumberTexture': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(1)': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(2)': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(3)': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(4)': WebGL2KernelValueNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGL2KernelValueHTMLImage,
+ 'OffscreenCanvas': WebGL2KernelValueHTMLImage,
+ 'HTMLImage': WebGL2KernelValueHTMLImage,
+ 'ImageBitmap': WebGL2KernelValueHTMLImage,
+ 'ImageData': WebGL2KernelValueHTMLImage,
+ 'HTMLImageArray': WebGL2KernelValueHTMLImageArray,
+ 'HTMLVideo': WebGL2KernelValueHTMLVideo,
+ }
+ },
+ single: {
+ dynamic: {
+ 'Boolean': WebGL2KernelValueBoolean,
+ 'Integer': WebGL2KernelValueInteger,
+ 'Float': WebGL2KernelValueFloat,
+ 'Array': WebGL2KernelValueDynamicSingleArray,
+ 'Array(2)': WebGL2KernelValueArray2,
+ 'Array(3)': WebGL2KernelValueArray3,
+ 'Array(4)': WebGL2KernelValueArray4,
+ 'Array1D(2)': WebGL2KernelValueDynamicSingleArray1DI,
+ 'Array1D(3)': WebGL2KernelValueDynamicSingleArray1DI,
+ 'Array1D(4)': WebGL2KernelValueDynamicSingleArray1DI,
+ 'Array2D(2)': WebGL2KernelValueDynamicSingleArray2DI,
+ 'Array2D(3)': WebGL2KernelValueDynamicSingleArray2DI,
+ 'Array2D(4)': WebGL2KernelValueDynamicSingleArray2DI,
+ 'Array3D(2)': WebGL2KernelValueDynamicSingleArray3DI,
+ 'Array3D(3)': WebGL2KernelValueDynamicSingleArray3DI,
+ 'Array3D(4)': WebGL2KernelValueDynamicSingleArray3DI,
+ 'Input': WebGL2KernelValueDynamicSingleInput,
+ 'NumberTexture': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGL2KernelValueDynamicHTMLImage,
+ 'OffscreenCanvas': WebGL2KernelValueDynamicHTMLImage,
+ 'HTMLImage': WebGL2KernelValueDynamicHTMLImage,
+ 'ImageBitmap': WebGL2KernelValueDynamicHTMLImage,
+ 'ImageData': WebGL2KernelValueDynamicHTMLImage,
+ 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray,
+ 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo,
+ },
+ static: {
+ 'Boolean': WebGL2KernelValueBoolean,
+ 'Float': WebGL2KernelValueFloat,
+ 'Integer': WebGL2KernelValueInteger,
+ 'Array': WebGL2KernelValueSingleArray,
+ 'Array(2)': WebGL2KernelValueArray2,
+ 'Array(3)': WebGL2KernelValueArray3,
+ 'Array(4)': WebGL2KernelValueArray4,
+ 'Array1D(2)': WebGL2KernelValueSingleArray1DI,
+ 'Array1D(3)': WebGL2KernelValueSingleArray1DI,
+ 'Array1D(4)': WebGL2KernelValueSingleArray1DI,
+ 'Array2D(2)': WebGL2KernelValueSingleArray2DI,
+ 'Array2D(3)': WebGL2KernelValueSingleArray2DI,
+ 'Array2D(4)': WebGL2KernelValueSingleArray2DI,
+ 'Array3D(2)': WebGL2KernelValueSingleArray3DI,
+ 'Array3D(3)': WebGL2KernelValueSingleArray3DI,
+ 'Array3D(4)': WebGL2KernelValueSingleArray3DI,
+ 'Input': WebGL2KernelValueSingleInput,
+ 'NumberTexture': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(1)': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(2)': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(3)': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(4)': WebGL2KernelValueNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGL2KernelValueMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGL2KernelValueHTMLImage,
+ 'OffscreenCanvas': WebGL2KernelValueHTMLImage,
+ 'HTMLImage': WebGL2KernelValueHTMLImage,
+ 'ImageBitmap': WebGL2KernelValueHTMLImage,
+ 'ImageData': WebGL2KernelValueHTMLImage,
+ 'HTMLImageArray': WebGL2KernelValueHTMLImageArray,
+ 'HTMLVideo': WebGL2KernelValueHTMLVideo,
+ }
+ },
+};
+
+function lookupKernelValueType(type, dynamic, precision, value) {
+ if (!type) {
+ throw new Error('type missing');
+ }
+ if (!dynamic) {
+ throw new Error('dynamic missing');
+ }
+ if (!precision) {
+ throw new Error('precision missing');
+ }
+ if (value.type) {
+ type = value.type;
+ }
+ const types = kernelValueMaps[precision][dynamic];
+ if (types[type] === false) {
+ return null;
+ } else if (types[type] === undefined) {
+ throw new Error(`Could not find a KernelValue for ${ type }`);
+ }
+ return types[type];
+}
+
+module.exports = {
+ kernelValueMaps,
+ lookupKernelValueType
+};
+},{"./kernel-value/array2":75,"./kernel-value/array3":76,"./kernel-value/array4":77,"./kernel-value/boolean":78,"./kernel-value/dynamic-html-image":80,"./kernel-value/dynamic-html-image-array":79,"./kernel-value/dynamic-html-video":81,"./kernel-value/dynamic-memory-optimized-number-texture":82,"./kernel-value/dynamic-number-texture":83,"./kernel-value/dynamic-single-array":84,"./kernel-value/dynamic-single-array1d-i":85,"./kernel-value/dynamic-single-array2d-i":86,"./kernel-value/dynamic-single-array3d-i":87,"./kernel-value/dynamic-single-input":88,"./kernel-value/dynamic-unsigned-array":89,"./kernel-value/dynamic-unsigned-input":90,"./kernel-value/float":91,"./kernel-value/html-image":93,"./kernel-value/html-image-array":92,"./kernel-value/html-video":94,"./kernel-value/integer":95,"./kernel-value/memory-optimized-number-texture":96,"./kernel-value/number-texture":97,"./kernel-value/single-array":98,"./kernel-value/single-array1d-i":99,"./kernel-value/single-array2d-i":100,"./kernel-value/single-array3d-i":101,"./kernel-value/single-input":102,"./kernel-value/unsigned-array":103,"./kernel-value/unsigned-input":104}],75:[function(require,module,exports){
+const { WebGLKernelValueArray2 } = require('../../web-gl/kernel-value/array2');
+
+class WebGL2KernelValueArray2 extends WebGLKernelValueArray2 {}
+
+module.exports = {
+ WebGL2KernelValueArray2
+};
+},{"../../web-gl/kernel-value/array2":41}],76:[function(require,module,exports){
+const { WebGLKernelValueArray3 } = require('../../web-gl/kernel-value/array3');
+
+class WebGL2KernelValueArray3 extends WebGLKernelValueArray3 {}
+
+module.exports = {
+ WebGL2KernelValueArray3
+};
+},{"../../web-gl/kernel-value/array3":42}],77:[function(require,module,exports){
+const { WebGLKernelValueArray4 } = require('../../web-gl/kernel-value/array4');
+
+class WebGL2KernelValueArray4 extends WebGLKernelValueArray4 {}
+
+module.exports = {
+ WebGL2KernelValueArray4
+};
+},{"../../web-gl/kernel-value/array4":43}],78:[function(require,module,exports){
+const { WebGLKernelValueBoolean } = require('../../web-gl/kernel-value/boolean');
+
+class WebGL2KernelValueBoolean extends WebGLKernelValueBoolean {}
+
+module.exports = {
+ WebGL2KernelValueBoolean
+};
+},{"../../web-gl/kernel-value/boolean":44}],79:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueHTMLImageArray } = require('./html-image-array');
+
+class WebGL2KernelValueDynamicHTMLImageArray extends WebGL2KernelValueHTMLImageArray {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2DArray ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(images) {
+ const { width, height } = images[0];
+ this.checkSize(width, height);
+ this.dimensions = [width, height, images.length];
+ this.textureSize = [width, height];
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(images);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicHTMLImageArray
+};
+},{"../../../utils":114,"./html-image-array":92}],80:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueDynamicHTMLImage } = require('../../web-gl/kernel-value/dynamic-html-image');
+
+class WebGL2KernelValueDynamicHTMLImage extends WebGLKernelValueDynamicHTMLImage {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicHTMLImage
+};
+},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-html-image":45}],81:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueDynamicHTMLImage } = require('./dynamic-html-image');
+
+class WebGL2KernelValueDynamicHTMLVideo extends WebGL2KernelValueDynamicHTMLImage {}
+
+module.exports = {
+ WebGL2KernelValueDynamicHTMLVideo
+};
+},{"../../../utils":114,"./dynamic-html-image":80}],82:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } = require('../../web-gl/kernel-value/dynamic-memory-optimized-number-texture');
+
+class WebGL2KernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueDynamicMemoryOptimizedNumberTexture {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicMemoryOptimizedNumberTexture
+};
+},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-memory-optimized-number-texture":47}],83:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueDynamicNumberTexture } = require('../../web-gl/kernel-value/dynamic-number-texture');
+
+class WebGL2KernelValueDynamicNumberTexture extends WebGLKernelValueDynamicNumberTexture {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicNumberTexture
+};
+},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-number-texture":48}],84:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueSingleArray } = require('../../web-gl2/kernel-value/single-array');
+
+class WebGL2KernelValueDynamicSingleArray extends WebGL2KernelValueSingleArray {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.dimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.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(value);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicSingleArray
+};
+},{"../../../utils":114,"../../web-gl2/kernel-value/single-array":98}],85:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueSingleArray1DI } = require('../../web-gl2/kernel-value/single-array1d-i');
+
+class WebGL2KernelValueDynamicSingleArray1DI extends WebGL2KernelValueSingleArray1DI {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.setShape(value);
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicSingleArray1DI
+};
+},{"../../../utils":114,"../../web-gl2/kernel-value/single-array1d-i":99}],86:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueSingleArray2DI } = require('../../web-gl2/kernel-value/single-array2d-i');
+
+class WebGL2KernelValueDynamicSingleArray2DI extends WebGL2KernelValueSingleArray2DI {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.setShape(value);
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicSingleArray2DI
+};
+},{"../../../utils":114,"../../web-gl2/kernel-value/single-array2d-i":100}],87:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueSingleArray3DI } = require('../../web-gl2/kernel-value/single-array3d-i');
+
+class WebGL2KernelValueDynamicSingleArray3DI extends WebGL2KernelValueSingleArray3DI {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.setShape(value);
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicSingleArray3DI
+};
+},{"../../../utils":114,"../../web-gl2/kernel-value/single-array3d-i":101}],88:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueSingleInput } = require('../../web-gl2/kernel-value/single-input');
+
+class WebGL2KernelValueDynamicSingleInput extends WebGL2KernelValueSingleInput {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ let [w, h, d] = value.size;
+ this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);
+ this.textureSize = utils.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(value);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicSingleInput
+};
+},{"../../../utils":114,"../../web-gl2/kernel-value/single-input":102}],89:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueDynamicUnsignedArray } = require('../../web-gl/kernel-value/dynamic-unsigned-array');
+
+class WebGL2KernelValueDynamicUnsignedArray extends WebGLKernelValueDynamicUnsignedArray {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicUnsignedArray
+};
+},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-unsigned-array":54}],90:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueDynamicUnsignedInput } = require('../../web-gl/kernel-value/dynamic-unsigned-input');
+
+class WebGL2KernelValueDynamicUnsignedInput extends WebGLKernelValueDynamicUnsignedInput {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicUnsignedInput
+};
+},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-unsigned-input":55}],91:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueFloat } = require('../../web-gl/kernel-value/float');
+
+class WebGL2KernelValueFloat extends WebGLKernelValueFloat {}
+
+module.exports = {
+ WebGL2KernelValueFloat
+};
+},{"../../../utils":114,"../../web-gl/kernel-value/float":56}],92:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('../../web-gl/kernel-value/array');
+
+class WebGL2KernelValueHTMLImageArray extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.checkSize(value[0].width, value[0].height);
+ this.dimensions = [value[0].width, value[0].height, value.length];
+ this.textureSize = [value[0].width, value[0].height];
+ }
+ defineTexture() {
+ const { context: gl } = this;
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.texture);
+ gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ }
+
+ getStringValueHandler() {
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2DArray ${this.id}`,
+ `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,
+ ]);
+ }
+
+ updateValue(images) {
+ const { context: gl } = this;
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
+ gl.texImage3D(
+ gl.TEXTURE_2D_ARRAY,
+ 0,
+ gl.RGBA,
+ images[0].width,
+ images[0].height,
+ images.length,
+ 0,
+ gl.RGBA,
+ gl.UNSIGNED_BYTE,
+ null
+ );
+ for (let i = 0; i < images.length; i++) {
+ const xOffset = 0;
+ const yOffset = 0;
+ const imageDepth = 1;
+ gl.texSubImage3D(
+ gl.TEXTURE_2D_ARRAY,
+ 0,
+ xOffset,
+ yOffset,
+ i,
+ images[i].width,
+ images[i].height,
+ imageDepth,
+ gl.RGBA,
+ gl.UNSIGNED_BYTE,
+ this.uploadValue = images[i]
+ );
+ }
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueHTMLImageArray
+};
+},{"../../../utils":114,"../../web-gl/kernel-value/array":40}],93:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueHTMLImage } = require('../../web-gl/kernel-value/html-image');
+
+class WebGL2KernelValueHTMLImage extends WebGLKernelValueHTMLImage {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueHTMLImage
+};
+},{"../../../utils":114,"../../web-gl/kernel-value/html-image":57}],94:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueHTMLImage } = require('./html-image');
+
+class WebGL2KernelValueHTMLVideo extends WebGL2KernelValueHTMLImage {}
+
+module.exports = {
+ WebGL2KernelValueHTMLVideo
+};
+},{"../../../utils":114,"./html-image":93}],95:[function(require,module,exports){
+const { WebGLKernelValueInteger } = require('../../web-gl/kernel-value/integer');
+
+class WebGL2KernelValueInteger extends WebGLKernelValueInteger {
+ getSource(value) {
+ const variablePrecision = this.getVariablePrecisionString();
+ if (this.origin === 'constants') {
+ return `const ${ variablePrecision } int ${this.id} = ${ parseInt(value) };\n`;
+ }
+ return `uniform ${ variablePrecision } int ${this.id};\n`;
+ }
+
+ updateValue(value) {
+ if (this.origin === 'constants') return;
+ this.kernel.setUniform1i(this.id, this.uploadValue = value);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueInteger
+};
+},{"../../web-gl/kernel-value/integer":60}],96:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueMemoryOptimizedNumberTexture } = require('../../web-gl/kernel-value/memory-optimized-number-texture');
+
+class WebGL2KernelValueMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture {
+ getSource() {
+ const { id, sizeId, textureSize, dimensionsId, dimensions } = this;
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform sampler2D ${id}`,
+ `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueMemoryOptimizedNumberTexture
+};
+},{"../../../utils":114,"../../web-gl/kernel-value/memory-optimized-number-texture":61}],97:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueNumberTexture } = require('../../web-gl/kernel-value/number-texture');
+
+class WebGL2KernelValueNumberTexture extends WebGLKernelValueNumberTexture {
+ getSource() {
+ const { id, sizeId, textureSize, dimensionsId, dimensions } = this;
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${id}`,
+ `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueNumberTexture
+};
+},{"../../../utils":114,"../../web-gl/kernel-value/number-texture":62}],98:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray } = require('../../web-gl/kernel-value/single-array');
+
+class WebGL2KernelValueSingleArray extends WebGLKernelValueSingleArray {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,
+ ]);
+ }
+
+ updateValue(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueSingleArray
+};
+},{"../../../utils":114,"../../web-gl/kernel-value/single-array":63}],99:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray1DI } = require('../../web-gl/kernel-value/single-array1d-i');
+
+class WebGL2KernelValueSingleArray1DI extends WebGLKernelValueSingleArray1DI {
+ updateValue(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueSingleArray1DI
+};
+},{"../../../utils":114,"../../web-gl/kernel-value/single-array1d-i":64}],100:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray2DI } = require('../../web-gl/kernel-value/single-array2d-i');
+
+class WebGL2KernelValueSingleArray2DI extends WebGLKernelValueSingleArray2DI {
+ updateValue(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueSingleArray2DI
+};
+},{"../../../utils":114,"../../web-gl/kernel-value/single-array2d-i":65}],101:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray3DI } = require('../../web-gl/kernel-value/single-array3d-i');
+
+class WebGL2KernelValueSingleArray3DI extends WebGLKernelValueSingleArray3DI {
+ updateValue(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueSingleArray3DI
+};
+},{"../../../utils":114,"../../web-gl/kernel-value/single-array3d-i":66}],102:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleInput } = require('../../web-gl/kernel-value/single-input');
+
+class WebGL2KernelValueSingleInput extends WebGLKernelValueSingleInput {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,
+ ]);
+ }
+
+ updateValue(input) {
+ const { context: gl } = this;
+ utils.flattenTo(input.value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueSingleInput
+};
+},{"../../../utils":114,"../../web-gl/kernel-value/single-input":67}],103:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueUnsignedArray } = require('../../web-gl/kernel-value/unsigned-array');
+
+class WebGL2KernelValueUnsignedArray extends WebGLKernelValueUnsignedArray {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueUnsignedArray
+};
+},{"../../../utils":114,"../../web-gl/kernel-value/unsigned-array":68}],104:[function(require,module,exports){
+const { utils } = require('../../../utils');
+const { WebGLKernelValueUnsignedInput } = require('../../web-gl/kernel-value/unsigned-input');
+
+class WebGL2KernelValueUnsignedInput extends WebGLKernelValueUnsignedInput {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueUnsignedInput
+};
+},{"../../../utils":114,"../../web-gl/kernel-value/unsigned-input":69}],105:[function(require,module,exports){
+const { WebGLKernel } = require('../web-gl/kernel');
+const { WebGL2FunctionNode } = require('./function-node');
+const { FunctionBuilder } = require('../function-builder');
+const { utils } = require('../../utils');
+const { fragmentShader } = require('./fragment-shader');
+const { vertexShader } = require('./vertex-shader');
+const { lookupKernelValueType } = require('./kernel-value-maps');
+
+let isSupported = null;
+let testCanvas = null;
+let testContext = null;
+let testExtensions = null;
+
+let features = null;
+
+class WebGL2Kernel extends WebGLKernel {
+ static get isSupported() {
+ if (isSupported !== null) {
+ return isSupported;
+ }
+ this.setupFeatureChecks();
+ isSupported = this.isContextMatch(testContext);
+ return isSupported;
+ }
+
+ static setupFeatureChecks() {
+ if (typeof document !== 'undefined') {
+ testCanvas = document.createElement('canvas');
+ } else if (typeof OffscreenCanvas !== 'undefined') {
+ testCanvas = new OffscreenCanvas(0, 0);
+ }
+ if (!testCanvas) return;
+ testContext = testCanvas.getContext('webgl2');
+ if (!testContext || !testContext.getExtension) return;
+ testExtensions = {
+ EXT_color_buffer_float: testContext.getExtension('EXT_color_buffer_float'),
+ OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'),
+ };
+ features = this.getFeatures();
+ }
+
+ static isContextMatch(context) {
+ if (typeof WebGL2RenderingContext !== 'undefined') {
+ return context instanceof WebGL2RenderingContext;
+ }
+ return false;
+ }
+
+ static getFeatures() {
+ const gl = this.testContext;
+ return Object.freeze({
+ isFloatRead: this.getIsFloatRead(),
+ isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(),
+ isSpeedTacticSupported: this.getIsSpeedTacticSupported(),
+ kernelMap: true,
+ isTextureFloat: true,
+ isDrawBuffers: true,
+ channelCount: this.getChannelCount(),
+ maxTextureSize: this.getMaxTextureSize(),
+ lowIntPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_INT),
+ lowFloatPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_FLOAT),
+ mediumIntPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_INT),
+ mediumFloatPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT),
+ highIntPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_INT),
+ highFloatPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT),
+ });
+ }
+
+ static getIsTextureFloat() {
+ return true;
+ }
+
+ static getChannelCount() {
+ return testContext.getParameter(testContext.MAX_DRAW_BUFFERS);
+ }
+
+ static getMaxTextureSize() {
+ return testContext.getParameter(testContext.MAX_TEXTURE_SIZE);
+ }
+
+ static lookupKernelValueType(type, dynamic, precision, value) {
+ return lookupKernelValueType(type, dynamic, precision, value);
+ }
+
+ static get testCanvas() {
+ return testCanvas;
+ }
+
+ static get testContext() {
+ return testContext;
+ }
+
+ static get features() {
+ return features;
+ }
+
+ static get fragmentShader() {
+ return fragmentShader;
+ }
+ static get vertexShader() {
+ return vertexShader;
+ }
+
+ initContext() {
+ const settings = {
+ alpha: false,
+ depth: false,
+ antialias: false
+ };
+ return this.canvas.getContext('webgl2', settings);
+ }
+
+ 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(args) {
+ if (!this.validate) {
+ this.texSize = utils.getKernelTextureSize({
+ optimizeFloatMemory: this.optimizeFloatMemory,
+ precision: this.precision,
+ }, this.output);
+ return;
+ }
+
+ const { features } = this.constructor;
+ if (this.precision === 'single' && !features.isFloatRead) {
+ throw new Error('Float texture outputs are not supported');
+ } else if (!this.graphical && this.precision === null) {
+ this.precision = features.isFloatRead ? 'single' : 'unsigned';
+ }
+
+ if (this.fixIntegerDivisionAccuracy === null) {
+ this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate;
+ } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) {
+ this.fixIntegerDivisionAccuracy = false;
+ }
+
+ this.checkOutput();
+
+ 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);
+ switch (argType) {
+ case 'Array':
+ this.output = utils.getDimensions(argType);
+ break;
+ case 'NumberTexture':
+ case 'MemoryOptimizedNumberTexture':
+ case 'ArrayTexture(1)':
+ case 'ArrayTexture(2)':
+ case 'ArrayTexture(3)':
+ case 'ArrayTexture(4)':
+ this.output = args[0].output;
+ break;
+ default:
+ throw new Error('Auto output not supported for input type: ' + argType);
+ }
+ }
+
+ if (this.graphical) {
+ if (this.output.length !== 2) {
+ throw new Error('Output must have 2 dimensions on graphical mode');
+ }
+
+ if (this.precision === 'single') {
+ console.warn('Cannot use graphical mode and single precision at the same time');
+ this.precision = 'unsigned';
+ }
+
+ this.texSize = utils.clone(this.output);
+ return;
+ } else if (!this.graphical && this.precision === null && features.isTextureFloat) {
+ this.precision = 'single';
+ }
+
+ this.texSize = utils.getKernelTextureSize({
+ optimizeFloatMemory: this.optimizeFloatMemory,
+ precision: this.precision,
+ }, this.output);
+
+ this.checkTextureSize();
+ }
+
+ translateSource() {
+ const functionBuilder = FunctionBuilder.fromKernel(this, WebGL2FunctionNode, {
+ fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy
+ });
+ this.translatedSource = functionBuilder.getPrototypeString('kernel');
+ this.setupReturnTypes(functionBuilder);
+ }
+
+ drawBuffers() {
+ this.context.drawBuffers(this.drawBuffersMap);
+ }
+
+ getTextureFormat() {
+ const { context: gl } = this;
+ switch (this.getInternalFormat()) {
+ case gl.R32F:
+ return gl.RED;
+ case gl.RG32F:
+ return gl.RG;
+ case gl.RGBA32F:
+ return gl.RGBA;
+ case gl.RGBA:
+ return gl.RGBA;
+ default:
+ throw new Error('Unknown internal format');
+ }
+ }
+ getInternalFormat() {
+ const { context: gl } = this;
+
+ if (this.precision === 'single') {
+ if (this.pipeline) {
+ switch (this.returnType) {
+ case 'Number':
+ case 'Float':
+ case 'Integer':
+ if (this.optimizeFloatMemory) {
+ return gl.RGBA32F;
+ } else {
+ return gl.R32F;
+ }
+ case 'Array(2)':
+ return gl.RG32F;
+ case 'Array(3)':
+ case 'Array(4)':
+ return gl.RGBA32F;
+ default:
+ throw new Error('Unhandled return type');
+ }
+ }
+ return gl.RGBA32F;
+ }
+ return gl.RGBA;
+ }
+
+ _setupOutputTexture() {
+ const gl = this.context;
+ if (this.texture) {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture.texture, 0);
+ return;
+ }
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
+ const texture = gl.createTexture();
+ const texSize = this.texSize;
+ gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ const format = this.getInternalFormat();
+ if (this.precision === 'single') {
+ gl.texStorage2D(gl.TEXTURE_2D, 1, format, texSize[0], texSize[1]);
+ } else {
+ gl.texImage2D(gl.TEXTURE_2D, 0, format, texSize[0], texSize[1], 0, format, gl.UNSIGNED_BYTE, null);
+ }
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ this.texture = new this.TextureConstructor({
+ texture,
+ size: texSize,
+ dimensions: this.threadDim,
+ output: this.output,
+ context: this.context,
+ internalFormat: this.getInternalFormat(),
+ textureFormat: this.getTextureFormat(),
+ kernel: this,
+ });
+ }
+
+ _setupSubOutputTextures() {
+ const gl = this.context;
+ if (this.mappedTextures) {
+ for (let i = 0; i < this.subKernels.length; i++) {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, this.mappedTextures[i].texture, 0);
+ }
+ return;
+ }
+ const texSize = this.texSize;
+ this.drawBuffersMap = [gl.COLOR_ATTACHMENT0];
+ this.mappedTextures = [];
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const texture = this.createTexture();
+ this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1);
+ gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ const format = this.getInternalFormat();
+ if (this.precision === 'single') {
+ gl.texStorage2D(gl.TEXTURE_2D, 1, format, texSize[0], texSize[1]);
+ } else {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ }
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0);
+
+ this.mappedTextures.push(new this.TextureConstructor({
+ texture,
+ size: texSize,
+ dimensions: this.threadDim,
+ output: this.output,
+ context: this.context,
+ internalFormat: this.getInternalFormat(),
+ textureFormat: this.getTextureFormat(),
+ kernel: this,
+ }));
+ }
+ }
+
+ _getHeaderString() {
+ return '';
+ }
+
+ _getTextureCoordinate() {
+ const subKernels = this.subKernels;
+ const variablePrecision = this.getVariablePrecisionString(this.texSize, this.tactic);
+ if (subKernels === null || subKernels.length < 1) {
+ return `in ${ variablePrecision } vec2 vTexCoord;\n`;
+ } else {
+ return `out ${ variablePrecision } vec2 vTexCoord;\n`;
+ }
+ }
+
+ _getMainArgumentsString(args) {
+ const result = [];
+ const argumentNames = this.argumentNames;
+ for (let i = 0; i < argumentNames.length; i++) {
+ result.push(this.kernelArguments[i].getSource(args[i]));
+ }
+ return result.join('');
+ }
+
+ getKernelString() {
+ const result = [this.getKernelResultDeclaration()];
+ const subKernels = this.subKernels;
+ if (subKernels !== null) {
+ result.push(
+ 'layout(location = 0) out vec4 data0'
+ );
+ switch (this.returnType) {
+ case 'Number':
+ case 'Float':
+ case 'Integer':
+ for (let i = 0; i < subKernels.length; i++) {
+ const subKernel = subKernels[i];
+ result.push(
+ subKernel.returnType === 'Integer' ?
+ `int subKernelResult_${ subKernel.name } = 0` :
+ `float subKernelResult_${ subKernel.name } = 0.0`,
+ `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }`
+ );
+ }
+ break;
+ case 'Array(2)':
+ for (let i = 0; i < subKernels.length; i++) {
+ result.push(
+ `vec2 subKernelResult_${ subKernels[i].name }`,
+ `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }`
+ );
+ }
+ break;
+ case 'Array(3)':
+ for (let i = 0; i < subKernels.length; i++) {
+ result.push(
+ `vec3 subKernelResult_${ subKernels[i].name }`,
+ `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }`
+ );
+ }
+ break;
+ case 'Array(4)':
+ for (let i = 0; i < subKernels.length; i++) {
+ result.push(
+ `vec4 subKernelResult_${ subKernels[i].name }`,
+ `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }`
+ );
+ }
+ break;
+ }
+ } else {
+ result.push(
+ 'out vec4 data0'
+ );
+ }
+
+ return utils.linesToString(result) + this.translatedSource;
+ }
+
+ getMainResultGraphical() {
+ return utils.linesToString([
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' data0 = actualColor',
+ ]);
+ }
+
+ getMainResultPackedPixels() {
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ return this.getMainResultKernelPackedPixels() +
+ this.getMainResultSubKernelPackedPixels();
+ default:
+ throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`);
+ }
+ }
+
+ getMainResultKernelPackedPixels() {
+ return utils.linesToString([
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ` data0 = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)`
+ ]);
+ }
+
+ getMainResultSubKernelPackedPixels() {
+ const result = [];
+ if (!this.subKernels) return '';
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const subKernel = this.subKernels[i];
+ if (subKernel.returnType === 'Integer') {
+ result.push(
+ ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))`
+ );
+ } else {
+ result.push(
+ ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})`
+ );
+ }
+ }
+ return utils.linesToString(result);
+ }
+
+ getMainResultKernelMemoryOptimizedFloats(result, channel) {
+ result.push(
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ` data0.${channel} = kernelResult`
+ );
+ }
+
+ getMainResultSubKernelMemoryOptimizedFloats(result, channel) {
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const subKernel = this.subKernels[i];
+ if (subKernel.returnType === 'Integer') {
+ result.push(
+ ` data${i + 1}.${channel} = float(subKernelResult_${subKernel.name})`
+ );
+ } else {
+ result.push(
+ ` data${i + 1}.${channel} = subKernelResult_${subKernel.name}`
+ );
+ }
+ }
+ }
+
+ getMainResultKernelNumberTexture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' data0[0] = kernelResult',
+ ];
+ }
+
+ getMainResultSubKernelNumberTexture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ const subKernel = this.subKernels[i];
+ if (subKernel.returnType === 'Integer') {
+ result.push(
+ ` data${i + 1}[0] = float(subKernelResult_${subKernel.name})`
+ );
+ } else {
+ result.push(
+ ` data${i + 1}[0] = subKernelResult_${subKernel.name}`
+ );
+ }
+ }
+ return result;
+ }
+
+ getMainResultKernelArray2Texture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' data0[0] = kernelResult[0]',
+ ' data0[1] = kernelResult[1]',
+ ];
+ }
+
+ getMainResultSubKernelArray2Texture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ const subKernel = this.subKernels[i];
+ result.push(
+ ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`,
+ ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`
+ );
+ }
+ return result;
+ }
+
+ getMainResultKernelArray3Texture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' data0[0] = kernelResult[0]',
+ ' data0[1] = kernelResult[1]',
+ ' data0[2] = kernelResult[2]',
+ ];
+ }
+
+ getMainResultSubKernelArray3Texture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ const subKernel = this.subKernels[i];
+ result.push(
+ ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`,
+ ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`,
+ ` data${i + 1}[2] = subKernelResult_${subKernel.name}[2]`
+ );
+ }
+ return result;
+ }
+
+ getMainResultKernelArray4Texture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' data0 = kernelResult',
+ ];
+ }
+
+ getMainResultSubKernelArray4Texture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ result.push(
+ ` data${i + 1} = subKernelResult_${this.subKernels[i].name}`
+ );
+ }
+ return result;
+ }
+
+ destroyExtensions() {
+ this.extensions.EXT_color_buffer_float = null;
+ this.extensions.OES_texture_float_linear = null;
+ }
+
+ toJSON() {
+ const json = super.toJSON();
+ json.functionNodes = FunctionBuilder.fromKernel(this, WebGL2FunctionNode).toJSON();
+ json.settings.threadDim = this.threadDim;
+ return json;
+ }
+}
+
+module.exports = {
+ WebGL2Kernel
+};
+},{"../../utils":114,"../function-builder":9,"../web-gl/kernel":70,"./fragment-shader":72,"./function-node":73,"./kernel-value-maps":74,"./vertex-shader":106}],106:[function(require,module,exports){
+const vertexShader = `#version 300 es
+__FLOAT_TACTIC_DECLARATION__;
+__INT_TACTIC_DECLARATION__;
+__SAMPLER_2D_TACTIC_DECLARATION__;
+
+in vec2 aPos;
+in vec2 aTexCoord;
+
+out vec2 vTexCoord;
+uniform vec2 ratio;
+
+void main(void) {
+ gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);
+ vTexCoord = aTexCoord;
+}`;
+
+module.exports = {
+ vertexShader
+};
+},{}],107:[function(require,module,exports){
+const lib = require('./index');
+const GPU = lib.GPU;
+for (const p in lib) {
+ if (!lib.hasOwnProperty(p)) continue;
+ if (p === 'GPU') continue;
+ GPU[p] = lib[p];
+}
+
+if (typeof window !== 'undefined') {
+ bindTo(window);
+}
+if (typeof self !== 'undefined') {
+ bindTo(self);
+}
+
+function bindTo(target) {
+ if (target.GPU) return;
+ Object.defineProperty(target, 'GPU', {
+ get() {
+ return GPU;
+ }
+ });
+}
+
+module.exports = lib;
+},{"./index":109}],108:[function(require,module,exports){
+const { gpuMock } = require('gpu-mock.js');
+const { utils } = require('./utils');
+const { Kernel } = require('./backend/kernel');
+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 { 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;
+
+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 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, 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 === '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 = {};
+ const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings) || {};
+ if (settings && typeof settings.argumentTypes === 'object') {
+ settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]);
+ }
+
+ function onRequestFallback(args) {
+ console.warn('Falling back to CPU');
+ const fallbackKernel = new CPUKernel(source, {
+ argumentTypes: kernelRun.argumentTypes,
+ constantTypes: kernelRun.constantTypes,
+ graphical: kernelRun.graphical,
+ loopMaxIterations: kernelRun.loopMaxIterations,
+ constants: kernelRun.constants,
+ dynamicOutput: kernelRun.dynamicOutput,
+ dynamicArgument: kernelRun.dynamicArguments,
+ output: kernelRun.output,
+ precision: kernelRun.precision,
+ pipeline: kernelRun.pipeline,
+ immutable: kernelRun.immutable,
+ optimizeFloatMemory: kernelRun.optimizeFloatMemory,
+ fixIntegerDivisionAccuracy: kernelRun.fixIntegerDivisionAccuracy,
+ functions: kernelRun.functions,
+ nativeFunctions: kernelRun.nativeFunctions,
+ injectedNative: kernelRun.injectedNative,
+ subKernels: kernelRun.subKernels,
+ strictIntegers: kernelRun.strictIntegers,
+ debug: kernelRun.debug,
+ });
+ fallbackKernel.build.apply(fallbackKernel, args);
+ const result = fallbackKernel.run.apply(fallbackKernel, args);
+ kernelRun.replaceKernel(fallbackKernel);
+ return result;
+ }
+
+ function onRequestSwitchKernel(reasons, args, _kernel) {
+ if (_kernel.debug) {
+ console.warn('Switching kernels');
+ }
+ let newOutput = null;
+ if (_kernel.signature && !switchableKernels[_kernel.signature]) {
+ switchableKernels[_kernel.signature] = _kernel;
+ }
+ if (_kernel.dynamicOutput) {
+ for (let i = reasons.length - 1; i >= 0; i--) {
+ const reason = reasons[i];
+ if (reason.type === 'outputPrecisionMismatch') {
+ newOutput = reason.needed;
+ }
+ }
+ }
+
+ const Constructor = _kernel.constructor;
+ const argumentTypes = Constructor.getArgumentTypes(_kernel, args);
+ const signature = Constructor.getSignature(_kernel, argumentTypes);
+ const existingKernel = switchableKernels[signature];
+ if (existingKernel) {
+ existingKernel.onActivate(_kernel);
+ return existingKernel;
+ }
+
+ const newKernel = switchableKernels[signature] = new Constructor(source, {
+ argumentTypes,
+ constantTypes: _kernel.constantTypes,
+ graphical: _kernel.graphical,
+ loopMaxIterations: _kernel.loopMaxIterations,
+ constants: _kernel.constants,
+ dynamicOutput: _kernel.dynamicOutput,
+ dynamicArgument: _kernel.dynamicArguments,
+ context: _kernel.context,
+ canvas: _kernel.canvas,
+ output: newOutput || _kernel.output,
+ precision: _kernel.precision,
+ pipeline: _kernel.pipeline,
+ immutable: _kernel.immutable,
+ optimizeFloatMemory: _kernel.optimizeFloatMemory,
+ fixIntegerDivisionAccuracy: _kernel.fixIntegerDivisionAccuracy,
+ functions: _kernel.functions,
+ nativeFunctions: _kernel.nativeFunctions,
+ injectedNative: _kernel.injectedNative,
+ subKernels: _kernel.subKernels,
+ strictIntegers: _kernel.strictIntegers,
+ debug: _kernel.debug,
+ gpu: _kernel.gpu,
+ validate,
+ returnType: _kernel.returnType,
+ tactic: _kernel.tactic,
+ onRequestFallback,
+ onRequestSwitchKernel,
+ texture: _kernel.texture,
+ mappedTextures: _kernel.mappedTextures,
+ drawBuffersMap: _kernel.drawBuffersMap,
+ });
+ newKernel.build.apply(newKernel, args);
+ kernelRun.replaceKernel(newKernel);
+ kernels.push(newKernel);
+ return newKernel;
+ }
+ const mergedSettings = Object.assign({
+ context: this.context,
+ canvas: this.canvas,
+ functions: this.functions,
+ nativeFunctions: this.nativeFunctions,
+ injectedNative: this.injectedNative,
+ gpu: this,
+ validate,
+ onRequestFallback,
+ onRequestSwitchKernel
+ }, settingsCopy);
+
+ const kernel = new this.Kernel(source, mergedSettings);
+ const kernelRun = kernelRunShortcut(kernel);
+
+ if (!this.canvas) {
+ this.canvas = kernel.canvas;
+ }
+
+ if (!this.context) {
+ this.context = kernel.context;
+ }
+
+ kernels.push(kernel);
+
+ return kernelRun;
+ }
+
+ createKernelMap() {
+ let fn;
+ let settings;
+ const argument2Type = typeof arguments[arguments.length - 2];
+ if (argument2Type === 'function' || argument2Type === 'string') {
+ fn = arguments[arguments.length - 2];
+ settings = arguments[arguments.length - 1];
+ } else {
+ fn = arguments[arguments.length - 1];
+ }
+
+ if (this.mode !== 'dev') {
+ if (!this.Kernel.isSupported || !this.Kernel.features.kernelMap) {
+ if (this.mode && kernelTypes.indexOf(this.mode) < 0) {
+ throw new Error(`kernelMap not supported on ${this.Kernel.name}`);
+ }
+ }
+ }
+
+ const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings);
+ if (settings && typeof settings.argumentTypes === 'object') {
+ settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]);
+ }
+
+ if (Array.isArray(arguments[0])) {
+ settingsCopy.subKernels = [];
+ const functions = arguments[0];
+ for (let i = 0; i < functions.length; i++) {
+ const source = functions[i].toString();
+ const name = utils.getFunctionNameFromString(source);
+ settingsCopy.subKernels.push({
+ name,
+ source,
+ property: i,
+ });
+ }
+ } else {
+ settingsCopy.subKernels = [];
+ const functions = arguments[0];
+ for (let p in functions) {
+ if (!functions.hasOwnProperty(p)) continue;
+ const source = functions[p].toString();
+ const name = utils.getFunctionNameFromString(source);
+ settingsCopy.subKernels.push({
+ name: name || p,
+ source,
+ property: p,
+ });
+ }
+ }
+ return this.createKernel(fn, settingsCopy);
+ }
+
+ combineKernels() {
+ const firstKernel = arguments[0];
+ const combinedKernel = arguments[arguments.length - 1];
+ if (firstKernel.kernel.constructor.mode === 'cpu') return combinedKernel;
+ const canvas = arguments[0].canvas;
+ const context = arguments[0].context;
+ const max = arguments.length - 1;
+ for (let i = 0; i < max; i++) {
+ arguments[i]
+ .setCanvas(canvas)
+ .setContext(context)
+ .setPipeline(true);
+ }
+
+ return function() {
+ const texture = combinedKernel.apply(this, arguments);
+ if (texture.toArray) {
+ return texture.toArray();
+ }
+ return texture;
+ };
+ }
+
+ setFunctions(functions) {
+ this.functions = functions;
+ return this;
+ }
+
+ setNativeFunctions(nativeFunctions) {
+ this.nativeFunctions = nativeFunctions;
+ return this;
+ }
+
+ addFunction(source, settings) {
+ this.functions.push({ source, settings });
+ return this;
+ }
+
+ addNativeFunction(name, source, settings) {
+ if (this.kernels.length > 0) {
+ throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.');
+ }
+ this.nativeFunctions.push(Object.assign({ name, source }, settings));
+ return this;
+ }
+
+ injectNative(source) {
+ this.injectedNative = source;
+ return this;
+ }
+
+ destroy() {
+ return new Promise((resolve, reject) => {
+ if (!this.kernels) {
+ resolve();
+ }
+ setTimeout(() => {
+ try {
+ for (let i = 0; i < this.kernels.length; i++) {
+ this.kernels[i].destroy(true);
+ }
+ let firstKernel = this.kernels[0];
+ if (firstKernel) {
+ if (firstKernel.kernel) {
+ firstKernel = firstKernel.kernel;
+ }
+ if (firstKernel.constructor.destroyContext) {
+ firstKernel.constructor.destroyContext(this.context);
+ }
+ }
+ } catch (e) {
+ reject(e);
+ }
+ resolve();
+ }, 0);
+ });
+ }
+}
+
+
+function upgradeDeprecatedCreateKernelSettings(settings) {
+ if (!settings) {
+ return {};
+ }
+ const upgradedSettings = Object.assign({}, settings);
+
+ if (settings.hasOwnProperty('floatOutput')) {
+ utils.warnDeprecated('setting', 'floatOutput', 'precision');
+ upgradedSettings.precision = settings.floatOutput ? 'single' : 'unsigned';
+ }
+ if (settings.hasOwnProperty('outputToTexture')) {
+ utils.warnDeprecated('setting', 'outputToTexture', 'pipeline');
+ upgradedSettings.pipeline = Boolean(settings.outputToTexture);
+ }
+ if (settings.hasOwnProperty('outputImmutable')) {
+ utils.warnDeprecated('setting', 'outputImmutable', 'immutable');
+ upgradedSettings.immutable = Boolean(settings.outputImmutable);
+ }
+ if (settings.hasOwnProperty('floatTextures')) {
+ utils.warnDeprecated('setting', 'floatTextures', 'optimizeFloatMemory');
+ upgradedSettings.optimizeFloatMemory = Boolean(settings.floatTextures);
+ }
+ return upgradedSettings;
+}
+
+module.exports = {
+ GPU,
+ kernelOrder,
+ kernelTypes
+};
+},{"./backend/cpu/kernel":8,"./backend/headless-gl/kernel":34,"./backend/kernel":36,"./backend/web-gl/kernel":70,"./backend/web-gl2/kernel":105,"./kernel-run-shortcut":111,"./utils":114,"gpu-mock.js":4}],109:[function(require,module,exports){
+const { GPU } = require('./gpu');
+const { alias } = require('./alias');
+const { utils } = require('./utils');
+const { Input, input } = require('./input');
+const { Texture } = require('./texture');
+const { FunctionBuilder } = require('./backend/function-builder');
+const { FunctionNode } = require('./backend/function-node');
+const { CPUFunctionNode } = require('./backend/cpu/function-node');
+const { CPUKernel } = require('./backend/cpu/kernel');
+
+const { HeadlessGLKernel } = require('./backend/headless-gl/kernel');
+
+const { WebGLFunctionNode } = require('./backend/web-gl/function-node');
+const { WebGLKernel } = require('./backend/web-gl/kernel');
+const { kernelValueMaps: webGLKernelValueMaps } = require('./backend/web-gl/kernel-value-maps');
+
+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 { GLKernel } = require('./backend/gl/kernel');
+
+const { Kernel } = require('./backend/kernel');
+
+const { FunctionTracer } = require('./backend/function-tracer');
+
+const mathRandom = require('./plugins/math-random-uniformly-distributed');
+
+module.exports = {
+ alias,
+ CPUFunctionNode,
+ CPUKernel,
+ GPU,
+ FunctionBuilder,
+ FunctionNode,
+ HeadlessGLKernel,
+ Input,
+ input,
+ Texture,
+ utils,
+
+ WebGL2FunctionNode,
+ WebGL2Kernel,
+ webGL2KernelValueMaps,
+
+ WebGLFunctionNode,
+ WebGLKernel,
+ webGLKernelValueMaps,
+
+ GLKernel,
+ Kernel,
+ FunctionTracer,
+
+ plugins: {
+ mathRandom
+ }
+};
+},{"./alias":5,"./backend/cpu/function-node":6,"./backend/cpu/kernel":8,"./backend/function-builder":9,"./backend/function-node":10,"./backend/function-tracer":11,"./backend/gl/kernel":13,"./backend/headless-gl/kernel":34,"./backend/kernel":36,"./backend/web-gl/function-node":38,"./backend/web-gl/kernel":70,"./backend/web-gl/kernel-value-maps":39,"./backend/web-gl2/function-node":73,"./backend/web-gl2/kernel":105,"./backend/web-gl2/kernel-value-maps":74,"./gpu":108,"./input":110,"./plugins/math-random-uniformly-distributed":112,"./texture":113,"./utils":114}],110:[function(require,module,exports){
+class Input {
+ constructor(value, size) {
+ this.value = value;
+ if (Array.isArray(size)) {
+ this.size = size;
+ } else {
+ this.size = new Int32Array(3);
+ if (size.z) {
+ this.size = new Int32Array([size.x, size.y, size.z]);
+ } else if (size.y) {
+ this.size = new Int32Array([size.x, size.y]);
+ } else {
+ this.size = new Int32Array([size.x]);
+ }
+ }
+
+ const [w, h, d] = this.size;
+ if (d) {
+ if (this.value.length !== (w * h * d)) {
+ throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} * ${d} = ${(h * w * d)}`);
+ }
+ } else if (h) {
+ if (this.value.length !== (w * h)) {
+ throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} = ${(h * w)}`);
+ }
+ } else {
+ if (this.value.length !== w) {
+ throw new Error(`Input size ${this.value.length} does not match ${w}`);
+ }
+ }
+
+ }
+
+ toArray() {
+ const { utils } = require('./utils');
+ const [w, h, d] = this.size;
+ if (d) {
+ return utils.erectMemoryOptimized3DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h, d);
+ } else if (h) {
+ return utils.erectMemoryOptimized2DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h);
+ } else {
+ return this.value;
+ }
+ }
+}
+
+function input(value, size) {
+ return new Input(value, size);
+}
+
+module.exports = {
+ Input,
+ input
+};
+},{"./utils":114}],111:[function(require,module,exports){
+const { 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
+};
+},{"./utils":114}],112:[function(require,module,exports){
+const source = `// https://www.shadertoy.com/view/4t2SDh
+//note: uniformly distributed, normalized rand, [0,1]
+highp float randomSeedShift = 1.0;
+highp float slide = 1.0;
+uniform highp float randomSeed1;
+uniform highp float randomSeed2;
+
+highp float nrand(highp vec2 n) {
+ highp float result = fract(sin(dot((n.xy + 1.0) * vec2(randomSeed1 * slide, randomSeed2 * randomSeedShift), vec2(12.9898, 78.233))) * 43758.5453);
+ randomSeedShift = result;
+ if (randomSeedShift > 0.5) {
+ slide += 0.00009;
+ } else {
+ slide += 0.0009;
+ }
+ return result;
+}`;
+
+const name = 'math-random-uniformly-distributed';
+
+const functionMatch = `Math.random()`;
+
+const functionReplace = `nrand(vTexCoord)`;
+
+const functionReturnType = 'Number';
+const onBeforeRun = (kernel) => {
+ kernel.setUniform1f('randomSeed1', Math.random());
+ kernel.setUniform1f('randomSeed2', Math.random());
+};
+
+const plugin = {
+ name,
+ onBeforeRun,
+ functionMatch,
+ functionReplace,
+ functionReturnType,
+ source
+};
+
+module.exports = plugin;
+},{}],113:[function(require,module,exports){
+class Texture {
+ constructor(settings) {
+ const {
+ texture,
+ size,
+ dimensions,
+ output,
+ context,
+ type = 'NumberTexture',
+ kernel,
+ internalFormat,
+ textureFormat
+ } = settings;
+ if (!output) throw new Error('settings property "output" required.');
+ if (!context) throw new Error('settings property "context" required.');
+ if (!texture) throw new Error('settings property "texture" required.');
+ if (!kernel) throw new Error('settings property "kernel" required.');
+ this.texture = texture;
+ if (texture._refs) {
+ texture._refs++;
+ } else {
+ texture._refs = 1;
+ }
+ this.size = size;
+ this.dimensions = dimensions;
+ this.output = output;
+ this.context = context;
+ this.kernel = kernel;
+ this.type = type;
+ this._deleted = false;
+ this.internalFormat = internalFormat;
+ this.textureFormat = textureFormat;
+ }
+
+ 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}`);
+ }
+}
+
+module.exports = {
+ Texture
+};
+},{}],114:[function(require,module,exports){
+const acorn = require('acorn');
+const { Input } = require('./input');
+const { Texture } = require('./texture');
+
+const FUNCTION_NAME = /function ([^(]*)/;
+const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
+const ARGUMENT_NAMES = /([^\s,]+)/g;
+
+const utils = {
+ systemEndianness() {
+ return _systemEndianness;
+ },
+ getSystemEndianness() {
+ const b = new ArrayBuffer(4);
+ const a = new Uint32Array(b);
+ const c = new Uint8Array(b);
+ a[0] = 0xdeadbeef;
+ if (c[0] === 0xef) return 'LE';
+ if (c[0] === 0xde) return 'BE';
+ throw new Error('unknown endianness');
+ },
+
+ isFunction(funcObj) {
+ return typeof(funcObj) === 'function';
+ },
+
+ isFunctionString(fn) {
+ if (typeof fn === 'string') {
+ return (fn
+ .slice(0, 'function'.length)
+ .toLowerCase() === 'function');
+ }
+ return false;
+ },
+
+ getFunctionNameFromString(funcStr) {
+ const result = FUNCTION_NAME.exec(funcStr);
+ if (!result || result.length === 0) return null;
+ return result[1].trim();
+ },
+
+ getFunctionBodyFromString(funcStr) {
+ return funcStr.substring(funcStr.indexOf('{') + 1, funcStr.lastIndexOf('}'));
+ },
+
+ getArgumentNamesFromString(fn) {
+ const fnStr = fn.replace(STRIP_COMMENTS, '');
+ let result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
+ if (result === null) {
+ result = [];
+ }
+ return result;
+ },
+
+ clone(obj) {
+ if (obj === null || typeof obj !== 'object' || obj.hasOwnProperty('isActiveClone')) return obj;
+
+ const temp = obj.constructor();
+
+ for (let key in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
+ obj.isActiveClone = null;
+ temp[key] = utils.clone(obj[key]);
+ delete obj.isActiveClone;
+ }
+ }
+
+ return temp;
+ },
+
+ isArray(array) {
+ return !isNaN(array.length);
+ },
+
+ getVariableType(value, strictIntegers) {
+ if (utils.isArray(value)) {
+ if (value.length > 0 && value[0].nodeName === 'IMG') {
+ return 'HTMLImageArray';
+ }
+ return 'Array';
+ }
+
+ switch (value.constructor) {
+ case Boolean:
+ return 'Boolean';
+ case Number:
+ if (strictIntegers && Number.isInteger(value)) {
+ return 'Integer';
+ }
+ return 'Float';
+ case Texture:
+ return value.type;
+ case Input:
+ return 'Input';
+ }
+ if ('nodeName' in value) {
+ switch (value.nodeName) {
+ case 'IMG':
+ return 'HTMLImage';
+ case 'CANVAS':
+ return 'HTMLImage';
+ case 'VIDEO':
+ return 'HTMLVideo';
+ }
+ } else if (value.hasOwnProperty('type')) {
+ return value.type;
+ } else if (typeof OffscreenCanvas !== 'undefined' && value instanceof OffscreenCanvas) {
+ return 'OffscreenCanvas';
+ } else if (typeof ImageBitmap !== 'undefined' && value instanceof ImageBitmap) {
+ return 'ImageBitmap';
+ } else if (typeof ImageData !== 'undefined' && value instanceof ImageData) {
+ return 'ImageData';
+ }
+ return 'Unknown';
+ },
+
+ getKernelTextureSize(settings, dimensions) {
+ let [w, h, d] = dimensions;
+ let texelCount = (w || 1) * (h || 1) * (d || 1);
+
+ if (settings.optimizeFloatMemory && settings.precision === 'single') {
+ w = texelCount = Math.ceil(texelCount / 4);
+ }
+ if (h > 1 && w * h === texelCount) {
+ return new Int32Array([w, h]);
+ }
+ return utils.closestSquareDimensions(texelCount);
+ },
+
+ closestSquareDimensions(length) {
+ const sqrt = Math.sqrt(length);
+ let high = Math.ceil(sqrt);
+ let low = Math.floor(sqrt);
+ while (high * low < length) {
+ high--;
+ low = Math.ceil(length / high);
+ }
+ return new Int32Array([low, Math.ceil(length / low)]);
+ },
+
+ getMemoryOptimizedFloatTextureSize(dimensions, bitRatio) {
+ const totalArea = utils.roundTo((dimensions[0] || 1) * (dimensions[1] || 1) * (dimensions[2] || 1) * (dimensions[3] || 1), 4);
+ const texelCount = totalArea / bitRatio;
+ return utils.closestSquareDimensions(texelCount);
+ },
+
+ getMemoryOptimizedPackedTextureSize(dimensions, bitRatio) {
+ const [w, h, d] = dimensions;
+ const totalArea = utils.roundTo((w || 1) * (h || 1) * (d || 1), 4);
+ const texelCount = totalArea / (4 / bitRatio);
+ return utils.closestSquareDimensions(texelCount);
+ },
+
+ roundTo(n, d) {
+ return Math.floor((n + d - 1) / d) * d;
+ },
+ getDimensions(x, pad) {
+ let ret;
+ if (utils.isArray(x)) {
+ const dim = [];
+ let temp = x;
+ while (utils.isArray(temp)) {
+ dim.push(temp.length);
+ temp = temp[0];
+ }
+ ret = dim.reverse();
+ } else if (x instanceof Texture) {
+ ret = x.output;
+ } else if (x instanceof Input) {
+ ret = x.size;
+ } else {
+ throw new Error(`Unknown dimensions of ${x}`);
+ }
+
+ if (pad) {
+ ret = Array.from(ret);
+ while (ret.length < 3) {
+ ret.push(1);
+ }
+ }
+
+ return new Int32Array(ret);
+ },
+
+ flatten2dArrayTo(array, target) {
+ let offset = 0;
+ for (let y = 0; y < array.length; y++) {
+ target.set(array[y], offset);
+ offset += array[y].length;
+ }
+ },
+
+ flatten3dArrayTo(array, target) {
+ let offset = 0;
+ for (let z = 0; z < array.length; z++) {
+ for (let y = 0; y < array[z].length; y++) {
+ target.set(array[z][y], offset);
+ offset += array[z][y].length;
+ }
+ }
+ },
+
+ flatten4dArrayTo(array, target) {
+ let offset = 0;
+ for (let l = 0; l < array.length; l++) {
+ for (let z = 0; z < array[l].length; z++) {
+ for (let y = 0; y < array[l][z].length; y++) {
+ target.set(array[l][z][y], offset);
+ offset += array[l][z][y].length;
+ }
+ }
+ }
+ },
+
+ flattenTo(array, target) {
+ if (utils.isArray(array[0])) {
+ if (utils.isArray(array[0][0])) {
+ if (utils.isArray(array[0][0][0])) {
+ utils.flatten4dArrayTo(array, target);
+ } else {
+ utils.flatten3dArrayTo(array, target);
+ }
+ } else {
+ utils.flatten2dArrayTo(array, target);
+ }
+ } else {
+ target.set(array);
+ }
+ },
+
+ splitArray(array, part) {
+ const result = [];
+ for (let i = 0; i < array.length; i += part) {
+ result.push(new array.constructor(array.buffer, i * 4 + array.byteOffset, part));
+ }
+ return result;
+ },
+
+ getAstString(source, ast) {
+ const lines = Array.isArray(source) ? source : source.split(/\r?\n/g);
+ const start = ast.loc.start;
+ const end = ast.loc.end;
+ const result = [];
+ if (start.line === end.line) {
+ result.push(lines[start.line - 1].substring(start.column, end.column));
+ } else {
+ result.push(lines[start.line - 1].slice(start.column));
+ for (let i = start.line; i < end.line; i++) {
+ result.push(lines[i]);
+ }
+ result.push(lines[end.line - 1].slice(0, end.column));
+ }
+ return result.join('\n');
+ },
+
+ allPropertiesOf(obj) {
+ const props = [];
+
+ do {
+ props.push.apply(props, Object.getOwnPropertyNames(obj));
+ } while (obj = Object.getPrototypeOf(obj));
+
+ return props;
+ },
+
+ linesToString(lines) {
+ if (lines.length > 0) {
+ return lines.join(';\n') + ';\n';
+ } else {
+ return '\n';
+ }
+ },
+ warnDeprecated(type, oldName, newName) {
+ if (newName) {
+ console.warn(`You are using a deprecated ${ type } "${ oldName }". It has been replaced with "${ newName }". Fixing, but please upgrade as it will soon be removed.`);
+ } else {
+ console.warn(`You are using a deprecated ${ type } "${ oldName }". It has been removed. Fixing, but please upgrade as it will soon be removed.`);
+ }
+ },
+ flipPixels: (pixels, width, height) => {
+ const halfHeight = height / 2 | 0;
+ const bytesPerRow = width * 4;
+ const temp = new Uint8ClampedArray(width * 4);
+ const result = pixels.slice(0);
+ for (let y = 0; y < halfHeight; ++y) {
+ const topOffset = y * bytesPerRow;
+ const bottomOffset = (height - y - 1) * bytesPerRow;
+
+ temp.set(result.subarray(topOffset, topOffset + bytesPerRow));
+
+ result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow);
+
+ result.set(temp, bottomOffset);
+ }
+ return result;
+ },
+ erectPackedFloat: (array, width) => {
+ return array.subarray(0, width);
+ },
+ erect2DPackedFloat: (array, width, height) => {
+ const yResults = new Array(height);
+ for (let y = 0; y < height; y++) {
+ const xStart = y * width;
+ const xEnd = xStart + width;
+ yResults[y] = array.subarray(xStart, xEnd);
+ }
+ return yResults;
+ },
+ erect3DPackedFloat: (array, width, height, depth) => {
+ const zResults = new Array(depth);
+ for (let z = 0; z < depth; z++) {
+ const yResults = new Array(height);
+ for (let y = 0; y < height; y++) {
+ const xStart = (z * height * width) + y * width;
+ const xEnd = xStart + width;
+ yResults[y] = array.subarray(xStart, xEnd);
+ }
+ zResults[z] = yResults;
+ }
+ return zResults;
+ },
+ erectMemoryOptimizedFloat: (array, width) => {
+ return array.subarray(0, width);
+ },
+ erectMemoryOptimized2DFloat: (array, width, height) => {
+ const yResults = new Array(height);
+ for (let y = 0; y < height; y++) {
+ const offset = y * width;
+ yResults[y] = array.subarray(offset, offset + width);
+ }
+ return yResults;
+ },
+ erectMemoryOptimized3DFloat: (array, width, height, depth) => {
+ const zResults = new Array(depth);
+ for (let z = 0; z < depth; z++) {
+ const yResults = new Array(height);
+ for (let y = 0; y < height; y++) {
+ const offset = (z * height * width) + (y * width);
+ yResults[y] = array.subarray(offset, offset + width);
+ }
+ zResults[z] = yResults;
+ }
+ return zResults;
+ },
+ erectFloat: (array, width) => {
+ const xResults = new Float32Array(width);
+ let i = 0;
+ for (let x = 0; x < width; x++) {
+ xResults[x] = array[i];
+ i += 4;
+ }
+ return xResults;
+ },
+ erect2DFloat: (array, width, height) => {
+ const yResults = new Array(height);
+ let i = 0;
+ for (let y = 0; y < height; y++) {
+ const xResults = new Float32Array(width);
+ for (let x = 0; x < width; x++) {
+ xResults[x] = array[i];
+ i += 4;
+ }
+ yResults[y] = xResults;
+ }
+ return yResults;
+ },
+ erect3DFloat: (array, width, height, depth) => {
+ const zResults = new Array(depth);
+ let i = 0;
+ for (let z = 0; z < depth; z++) {
+ const yResults = new Array(height);
+ for (let y = 0; y < height; y++) {
+ const xResults = new Float32Array(width);
+ for (let x = 0; x < width; x++) {
+ xResults[x] = array[i];
+ i += 4;
+ }
+ yResults[y] = xResults;
+ }
+ zResults[z] = yResults;
+ }
+ return zResults;
+ },
+ erectArray2: (array, width) => {
+ const xResults = new Array(width);
+ const xResultsMax = width * 4;
+ let i = 0;
+ for (let x = 0; x < xResultsMax; x += 4) {
+ xResults[i++] = array.subarray(x, x + 2);
+ }
+ return xResults;
+ },
+ erect2DArray2: (array, width, height) => {
+ const yResults = new Array(height);
+ const XResultsMax = width * 4;
+ for (let y = 0; y < height; y++) {
+ const xResults = new Array(width);
+ const offset = y * XResultsMax;
+ let i = 0;
+ for (let x = 0; x < XResultsMax; x += 4) {
+ xResults[i++] = array.subarray(x + offset, x + offset + 2);
+ }
+ yResults[y] = xResults;
+ }
+ return yResults;
+ },
+ erect3DArray2: (array, width, height, depth) => {
+ const xResultsMax = width * 4;
+ const zResults = new Array(depth);
+ for (let z = 0; z < depth; z++) {
+ const yResults = new Array(height);
+ for (let y = 0; y < height; y++) {
+ const xResults = new Array(width);
+ const offset = (z * xResultsMax * height) + (y * xResultsMax);
+ let i = 0;
+ for (let x = 0; x < xResultsMax; x += 4) {
+ xResults[i++] = array.subarray(x + offset, x + offset + 2);
+ }
+ yResults[y] = xResults;
+ }
+ zResults[z] = yResults;
+ }
+ return zResults;
+ },
+ erectArray3: (array, width) => {
+ const xResults = new Array(width);
+ const xResultsMax = width * 4;
+ let i = 0;
+ for (let x = 0; x < xResultsMax; x += 4) {
+ xResults[i++] = array.subarray(x, x + 3);
+ }
+ return xResults;
+ },
+ erect2DArray3: (array, width, height) => {
+ const xResultsMax = width * 4;
+ const yResults = new Array(height);
+ for (let y = 0; y < height; y++) {
+ const xResults = new Array(width);
+ const offset = y * xResultsMax;
+ let i = 0;
+ for (let x = 0; x < xResultsMax; x += 4) {
+ xResults[i++] = array.subarray(x + offset, x + offset + 3);
+ }
+ yResults[y] = xResults;
+ }
+ return yResults;
+ },
+ erect3DArray3: (array, width, height, depth) => {
+ const xResultsMax = width * 4;
+ const zResults = new Array(depth);
+ for (let z = 0; z < depth; z++) {
+ const yResults = new Array(height);
+ for (let y = 0; y < height; y++) {
+ const xResults = new Array(width);
+ const offset = (z * xResultsMax * height) + (y * xResultsMax);
+ let i = 0;
+ for (let x = 0; x < xResultsMax; x += 4) {
+ xResults[i++] = array.subarray(x + offset, x + offset + 3);
+ }
+ yResults[y] = xResults;
+ }
+ zResults[z] = yResults;
+ }
+ return zResults;
+ },
+ erectArray4: (array, width) => {
+ const xResults = new Array(array);
+ const xResultsMax = width * 4;
+ let i = 0;
+ for (let x = 0; x < xResultsMax; x += 4) {
+ xResults[i++] = array.subarray(x, x + 4);
+ }
+ return xResults;
+ },
+ erect2DArray4: (array, width, height) => {
+ const xResultsMax = width * 4;
+ const yResults = new Array(height);
+ for (let y = 0; y < height; y++) {
+ const xResults = new Array(width);
+ const offset = y * xResultsMax;
+ let i = 0;
+ for (let x = 0; x < xResultsMax; x += 4) {
+ xResults[i++] = array.subarray(x + offset, x + offset + 4);
+ }
+ yResults[y] = xResults;
+ }
+ return yResults;
+ },
+ erect3DArray4: (array, width, height, depth) => {
+ const xResultsMax = width * 4;
+ const zResults = new Array(depth);
+ for (let z = 0; z < depth; z++) {
+ const yResults = new Array(height);
+ for (let y = 0; y < height; y++) {
+ const xResults = new Array(width);
+ const offset = (z * xResultsMax * height) + (y * xResultsMax);
+ let i = 0;
+ for (let x = 0; x < xResultsMax; x += 4) {
+ xResults[i++] = array.subarray(x + offset, x + offset + 4);
+ }
+ yResults[y] = xResults;
+ }
+ zResults[z] = yResults;
+ }
+ return zResults;
+ },
+
+ flattenFunctionToString: (source, settings) => {
+ const { findDependency, thisLookup, doNotDefine } = settings;
+ let flattened = settings.flattened;
+ if (!flattened) {
+ flattened = settings.flattened = {};
+ }
+ const ast = acorn.parse(source);
+ const functionDependencies = [];
+ let indent = 0;
+
+ function flatten(ast) {
+ if (Array.isArray(ast)) {
+ const results = [];
+ for (let i = 0; i < ast.length; i++) {
+ results.push(flatten(ast[i]));
+ }
+ return results.join('');
+ }
+ switch (ast.type) {
+ case 'Program':
+ return flatten(ast.body) + (ast.body[0].type === 'VariableDeclaration' ? ';' : '');
+ case 'FunctionDeclaration':
+ return `function ${ast.id.name}(${ast.params.map(flatten).join(', ')}) ${ flatten(ast.body) }`;
+ case 'BlockStatement': {
+ const result = [];
+ indent += 2;
+ for (let i = 0; i < ast.body.length; i++) {
+ const flat = flatten(ast.body[i]);
+ if (flat) {
+ result.push(' '.repeat(indent) + flat, ';\n');
+ }
+ }
+ indent -= 2;
+ return `{\n${result.join('')}}`;
+ }
+ case 'VariableDeclaration':
+ const declarations = utils.normalizeDeclarations(ast)
+ .map(flatten)
+ .filter(r => r !== null);
+ if (declarations.length < 1) {
+ return '';
+ } else {
+ return `${ast.kind} ${declarations.join(',')}`;
+ }
+ case 'VariableDeclarator':
+ if (ast.init.object && ast.init.object.type === 'ThisExpression') {
+ const lookup = thisLookup(ast.init.property.name, true);
+ if (lookup) {
+ return `${ast.id.name} = ${flatten(ast.init)}`;
+ } else {
+ return null;
+ }
+ } else {
+ return `${ast.id.name} = ${flatten(ast.init)}`;
+ }
+ case 'CallExpression': {
+ if (ast.callee.property.name === 'subarray') {
+ return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`;
+ }
+ if (ast.callee.object.name === 'gl' || ast.callee.object.name === 'context') {
+ return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`;
+ }
+ if (ast.callee.object.type === 'ThisExpression') {
+ functionDependencies.push(findDependency('this', ast.callee.property.name));
+ return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;
+ } else if (ast.callee.object.name) {
+ const foundSource = findDependency(ast.callee.object.name, ast.callee.property.name);
+ if (foundSource === null) {
+ return `${ast.callee.object.name}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;
+ } else {
+ functionDependencies.push(foundSource);
+ return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;
+ }
+ } else if (ast.callee.object.type === 'MemberExpression') {
+ return `${flatten(ast.callee.object)}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;
+ } else {
+ throw new Error('unknown ast.callee');
+ }
+ }
+ case 'ReturnStatement':
+ return `return ${flatten(ast.argument)}`;
+ case 'BinaryExpression':
+ return `(${flatten(ast.left)}${ast.operator}${flatten(ast.right)})`;
+ case 'UnaryExpression':
+ if (ast.prefix) {
+ return `${ast.operator} ${flatten(ast.argument)}`;
+ } else {
+ return `${flatten(ast.argument)} ${ast.operator}`;
+ }
+ case 'ExpressionStatement':
+ return `${flatten(ast.expression)}`;
+ case 'SequenceExpression':
+ return `(${flatten(ast.expressions)})`;
+ case 'ArrowFunctionExpression':
+ return `(${ast.params.map(flatten).join(', ')}) => ${flatten(ast.body)}`;
+ case 'Literal':
+ return ast.raw;
+ case 'Identifier':
+ return ast.name;
+ case 'MemberExpression':
+ if (ast.object.type === 'ThisExpression') {
+ return thisLookup(ast.property.name);
+ }
+ if (ast.computed) {
+ return `${flatten(ast.object)}[${flatten(ast.property)}]`;
+ }
+ return flatten(ast.object) + '.' + flatten(ast.property);
+ case 'ThisExpression':
+ return 'this';
+ case 'NewExpression':
+ return `new ${flatten(ast.callee)}(${ast.arguments.map(value => flatten(value)).join(', ')})`;
+ case 'ForStatement':
+ return `for (${flatten(ast.init)};${flatten(ast.test)};${flatten(ast.update)}) ${flatten(ast.body)}`;
+ case 'AssignmentExpression':
+ return `${flatten(ast.left)}${ast.operator}${flatten(ast.right)}`;
+ case 'UpdateExpression':
+ return `${flatten(ast.argument)}${ast.operator}`;
+ case 'IfStatement':
+ return `if (${flatten(ast.test)}) ${flatten(ast.consequent)}`;
+ case 'ThrowStatement':
+ return `throw ${flatten(ast.argument)}`;
+ case 'ObjectPattern':
+ return ast.properties.map(flatten).join(', ');
+ case 'ArrayPattern':
+ return ast.elements.map(flatten).join(', ');
+ case 'DebuggerStatement':
+ return 'debugger;';
+ case 'ConditionalExpression':
+ return `${flatten(ast.test)}?${flatten(ast.consequent)}:${flatten(ast.alternate)}`;
+ case 'Property':
+ if (ast.kind === 'init') {
+ return flatten(ast.key);
+ }
+ }
+ throw new Error(`unhandled ast.type of ${ ast.type }`);
+ }
+ const result = flatten(ast);
+ if (functionDependencies.length > 0) {
+ const flattenedFunctionDependencies = [];
+ for (let i = 0; i < functionDependencies.length; i++) {
+ const functionDependency = functionDependencies[i];
+ if (!flattened[functionDependency]) {
+ flattened[functionDependency] = true;
+ }
+ functionDependency ? flattenedFunctionDependencies.push(utils.flattenFunctionToString(functionDependency, settings) + '\n') : '';
+ }
+ return flattenedFunctionDependencies.join('') + result;
+ }
+ return result;
+ },
+
+ normalizeDeclarations: (ast) => {
+ if (ast.type !== 'VariableDeclaration') throw new Error('Ast is not of type "VariableDeclaration"');
+ const normalizedDeclarations = [];
+ for (let declarationIndex = 0; declarationIndex < ast.declarations.length; declarationIndex++) {
+ const declaration = ast.declarations[declarationIndex];
+ if (declaration.id && declaration.id.type === 'ObjectPattern' && declaration.id.properties) {
+ const { properties } = declaration.id;
+ for (let propertyIndex = 0; propertyIndex < properties.length; propertyIndex++) {
+ const property = properties[propertyIndex];
+ if (property.value.type === 'ObjectPattern' && property.value.properties) {
+ for (let subPropertyIndex = 0; subPropertyIndex < property.value.properties.length; subPropertyIndex++) {
+ const subProperty = property.value.properties[subPropertyIndex];
+ if (subProperty.type === 'Property') {
+ normalizedDeclarations.push({
+ type: 'VariableDeclarator',
+ id: {
+ type: 'Identifier',
+ name: subProperty.key.name
+ },
+ init: {
+ type: 'MemberExpression',
+ object: {
+ type: 'MemberExpression',
+ object: declaration.init,
+ property: {
+ type: 'Identifier',
+ name: property.key.name
+ },
+ computed: false
+ },
+ property: {
+ type: 'Identifier',
+ name: subProperty.key.name
+ },
+ computed: false
+ }
+ });
+ } else {
+ throw new Error('unexpected state');
+ }
+ }
+ } else if (property.value.type === 'Identifier') {
+ normalizedDeclarations.push({
+ type: 'VariableDeclarator',
+ id: {
+ type: 'Identifier',
+ name: property.value && property.value.name ? property.value.name : property.key.name
+ },
+ init: {
+ type: 'MemberExpression',
+ object: declaration.init,
+ property: {
+ type: 'Identifier',
+ name: property.key.name
+ },
+ computed: false
+ }
+ });
+ } else {
+ throw new Error('unexpected state');
+ }
+ }
+ } else if (declaration.id && declaration.id.type === 'ArrayPattern' && declaration.id.elements) {
+ const { elements } = declaration.id;
+ for (let elementIndex = 0; elementIndex < elements.length; elementIndex++) {
+ const element = elements[elementIndex];
+ if (element.type === 'Identifier') {
+ normalizedDeclarations.push({
+ type: 'VariableDeclarator',
+ id: {
+ type: 'Identifier',
+ name: element.name
+ },
+ init: {
+ type: 'MemberExpression',
+ object: declaration.init,
+ property: {
+ type: 'Literal',
+ value: elementIndex,
+ raw: elementIndex.toString(),
+ start: element.start,
+ end: element.end
+ },
+ computed: true
+ }
+ });
+ } else {
+ throw new Error('unexpected state');
+ }
+ }
+ } else {
+ normalizedDeclarations.push(declaration);
+ }
+ }
+ return normalizedDeclarations;
+ },
+
+ splitHTMLImageToRGB: (gpu, image) => {
+ const rKernel = gpu.createKernel(function(a) {
+ const pixel = a[this.thread.y][this.thread.x];
+ return pixel.r * 255;
+ }, {
+ output: [image.width, image.height],
+ precision: 'unsigned',
+ argumentTypes: { a: 'HTMLImage' },
+ });
+ const gKernel = gpu.createKernel(function(a) {
+ const pixel = a[this.thread.y][this.thread.x];
+ return pixel.g * 255;
+ }, {
+ output: [image.width, image.height],
+ precision: 'unsigned',
+ argumentTypes: { a: 'HTMLImage' },
+ });
+ const bKernel = gpu.createKernel(function(a) {
+ const pixel = a[this.thread.y][this.thread.x];
+ return pixel.b * 255;
+ }, {
+ output: [image.width, image.height],
+ precision: 'unsigned',
+ argumentTypes: { a: 'HTMLImage' },
+ });
+ const aKernel = gpu.createKernel(function(a) {
+ const pixel = a[this.thread.y][this.thread.x];
+ return pixel.a * 255;
+ }, {
+ output: [image.width, image.height],
+ precision: 'unsigned',
+ argumentTypes: { a: 'HTMLImage' },
+ });
+ const result = [
+ rKernel(image),
+ gKernel(image),
+ bKernel(image),
+ aKernel(image),
+ ];
+ result.rKernel = rKernel;
+ result.gKernel = gKernel;
+ result.bKernel = bKernel;
+ result.aKernel = aKernel;
+ result.gpu = gpu;
+ return result;
+ },
+
+ splitRGBAToCanvases: (gpu, rgba, width, height) => {
+ const visualKernelR = gpu.createKernel(function(v) {
+ const pixel = v[this.thread.y][this.thread.x];
+ this.color(pixel.r / 255, 0, 0, 255);
+ }, {
+ output: [width, height],
+ graphical: true,
+ argumentTypes: { v: 'Array2D(4)' }
+ });
+ visualKernelR(rgba);
+
+ const visualKernelG = gpu.createKernel(function(v) {
+ const pixel = v[this.thread.y][this.thread.x];
+ this.color(0, pixel.g / 255, 0, 255);
+ }, {
+ output: [width, height],
+ graphical: true,
+ argumentTypes: { v: 'Array2D(4)' }
+ });
+ visualKernelG(rgba);
+
+ const visualKernelB = gpu.createKernel(function(v) {
+ const pixel = v[this.thread.y][this.thread.x];
+ this.color(0, 0, pixel.b / 255, 255);
+ }, {
+ output: [width, height],
+ graphical: true,
+ argumentTypes: { v: 'Array2D(4)' }
+ });
+ visualKernelB(rgba);
+
+ const visualKernelA = gpu.createKernel(function(v) {
+ const pixel = v[this.thread.y][this.thread.x];
+ this.color(255, 255, 255, pixel.a / 255);
+ }, {
+ output: [width, height],
+ graphical: true,
+ argumentTypes: { v: 'Array2D(4)' }
+ });
+ visualKernelA(rgba);
+ return [
+ visualKernelR.canvas,
+ visualKernelG.canvas,
+ visualKernelB.canvas,
+ visualKernelA.canvas,
+ ];
+ },
+
+ getMinifySafeName: (fn) => {
+ try {
+ const ast = acorn.parse(`const value = ${fn.toString()}`);
+ const { init } = ast.body[0].declarations[0];
+ return init.body.name || init.body.body[0].argument.name;
+ } catch (e) {
+ throw new Error('Unrecognized function type. Please use `() => yourFunctionVariableHere` or function() { return yourFunctionVariableHere; }');
+ }
+ },
+ sanitizeName: function(name) {
+ if (dollarSign.test(name)) {
+ name = name.replace(dollarSign, 'S_S');
+ }
+ if (doubleUnderscore.test(name)) {
+ name = name.replace(doubleUnderscore, 'U_U');
+ } else if (singleUnderscore.test(name)) {
+ name = name.replace(singleUnderscore, 'u_u');
+ }
+ return name;
+ }
+};
+
+const dollarSign = /\$/;
+const doubleUnderscore = /__/;
+const singleUnderscore = /_/;
+
+const _systemEndianness = utils.getSystemEndianness();
+
+module.exports = {
+ utils
+};
+},{"./input":110,"./texture":113,"acorn":1}]},{},[107])(107)
+});
diff --git a/dist/gpu-browser.min.js b/dist/gpu-browser.min.js
new file mode 100644
index 00000000..024b06f9
--- /dev/null
+++ b/dist/gpu-browser.min.js
@@ -0,0 +1,28 @@
+/**
+ * gpu.js
+ * http://gpu.rocks/
+ *
+ * GPU Accelerated JavaScript
+ *
+ * @version 2.16.0
+ * @date Thu Feb 13 2025 11:46:50 GMT-0800 (Pacific Standard Time)
+ *
+ * @license MIT
+ * The MIT License
+ *
+ * Copyright (c) 2025 gpu.js Team
+ *//**
+ * gpu.js
+ * http://gpu.rocks/
+ *
+ * GPU Accelerated JavaScript
+ *
+ * @version 2.16.0
+ * @date Thu Feb 13 2025 11:46:48 GMT-0800 (Pacific Standard Time)
+ *
+ * @license MIT
+ * The MIT License
+ *
+ * Copyright (c) 2025 gpu.js Team
+ */
+!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).GPU=e()}}((function(){return function e(t,r,n){function i(a,o){if(!r[a]){if(!t[a]){var u="function"==typeof require&&require;if(!o&&u)return u(a,!0);if(s)return s(a,!0);var l=new Error("Cannot find module '"+a+"'");throw l.code="MODULE_NOT_FOUND",l}var h=r[a]={exports:{}};t[a][0].call(h.exports,(function(e){return i(t[a][1][e]||e)}),h,h.exports,e,t,r,n)}return r[a].exports}for(var s="function"==typeof require&&require,a=0;ae)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&&h(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&&l.test(String.fromCharCode(e)):!1!==n&&(h(e,r)||h(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/,v=new RegExp(T.source,"g");function S(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 i=A(e,n,t);if(i<0)return new N(r,t-n);++r,n=i}}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&&D(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),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,i,s,a,o){var u={type:r?"Block":"Line",value:n,start:i,end:s};e.locations&&(u.loc=new V(this,a,o)),e.ranges&&(u.range=[i,s]),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=i[e.ecmaVersion>=6?6:5===e.ecmaVersion?5:3],"module"===e.sourceType&&(n+=" await")),this.reservedWords=L(n);var s=(n?n+" ":"")+i.strict;this.reservedWordsStrict=L(s),this.reservedWordsStrictBind=L(s+" "+i.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(i)||"!"===i&&"="===this.input.charAt(n+1))}e+=t[0].length,E.lastIndex=e,e+=E.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 i=r+1;p(n=this.input.charCodeAt(i),!0);)++i;if(92===n||n>55295&&n<56320)return!0;var s=this.input.slice(r,i);if(!o.test(s))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,i=this.type,s=this.startNode();switch(this.isLet(e)&&(i=b._var,n="let"),i){case b._break:case b._continue:return this.parseBreakContinueStatement(s,i.keyword);case b._debugger:return this.parseDebuggerStatement(s);case b._do:return this.parseDoStatement(s);case b._for:return this.parseForStatement(s);case b._function:return e&&(this.strict||"if"!==e&&"label"!==e)&&this.options.ecmaVersion>=6&&this.unexpected(),this.parseFunctionStatement(s,!1,!e);case b._class:return e&&this.unexpected(),this.parseClass(s,!0);case b._if:return this.parseIfStatement(s);case b._return:return this.parseReturnStatement(s);case b._switch:return this.parseSwitchStatement(s);case b._throw:return this.parseThrowStatement(s);case b._try:return this.parseTryStatement(s);case b._const:case b._var:return n=n||this.value,e&&"var"!==n&&this.unexpected(),this.parseVarStatement(s,n);case b._while:return this.parseWhileStatement(s);case b._with:return this.parseWithStatement(s);case b.braceL:return this.parseBlock(!0,s);case b.semi:return this.parseEmptyStatement(s);case b._export:case b._import:if(this.options.ecmaVersion>10&&i===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(s,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'")),i===b._import?this.parseImport(s):this.parseExport(s,r);default:if(this.isAsyncFunction())return e&&this.unexpected(),this.next(),this.parseFunctionStatement(s,!0,!e);var l=this.value,h=this.parseExpression();return i===b.name&&"Identifier"===h.type&&this.eat(b.colon)?this.parseLabeledStatement(s,l,h,e):this.parseExpressionStatement(s,h)}},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(),i=r?"let":this.value;return this.next(),this.parseVar(n,!0,i),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 s=this.isContextual("let"),a=!1,o=this.containsEsc,u=new H,l=this.start,h=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&&(h.start!==l||o||"Identifier"!==h.type||"async"!==h.name?this.options.ecmaVersion>=9&&(e.await=!1):this.unexpected()),s&&a&&this.raise(h.start,"The left-hand side of a for-of loop may not start with 'let'."),this.toAssignable(h,!1,u),this.checkLValPattern(h),this.parseForIn(e,h)):(this.checkExpressionErrors(u,!0),t>-1&&this.unexpected(t),this.parseFor(e,h))},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 i=0,s=this.labels;i=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 i=this.startNode();if(this.parseVarId(i,r),this.eat(b.eq)?i.init=this.parseMaybeAssign(t):n||"const"!==r||this.type===b._in||this.options.ecmaVersion>=6&&this.isContextual("of")?n||"Identifier"===i.id.type||t&&(this.type===b._in||this.isContextual("of"))?i.init=null:this.raise(this.lastTokEnd,"Complex binding patterns require an initialization value"):this.unexpected(),e.declarations.push(this.finishNode(i,"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],i="true";return"MethodDefinition"!==t.type||"get"!==t.kind&&"set"!==t.kind||(i=(t.static?"s":"i")+t.kind),"iget"===n&&"iset"===i||"iset"===n&&"iget"===i||"sget"===n&&"sset"===i||"sset"===n&&"sget"===i?(e[r]="true",!1):!!n||(e[r]=i,!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,i){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 s=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,i),this.yieldPos=s,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(),i=this.startNode(),s=!1;for(i.body=[],this.expect(b.braceL);this.type!==b.braceR;){var a=this.parseClassElement(null!==e.superClass);a&&(i.body.push(a),"MethodDefinition"===a.type&&"constructor"===a.kind?(s&&this.raiseRecoverable(a.start,"Duplicate constructor in the same class"),s=!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(i,"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="",i=!1,s=!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":s=!0),!n&&(t>=9||!s)&&this.eat(b.star)&&(i=!0),!n&&!s&&!i){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||i||s){var l=!r.static&&te(r,"constructor"),h=l&&e;l&&"method"!==a&&this.raise(r.key.start,"Constructor can't have get/set modifier"),r.kind=l?"constructor":a,this.parseClassMethod(r,i,s,h)}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 i=e.key;"constructor"===e.kind?(t&&this.raise(i.start,"Constructor can't be a generator"),r&&this.raise(i.start,"Constructor can't be an async method")):e.static&&te(e,"prototype")&&this.raise(i.start,"Classes may not have a static property named prototype");var s=e.value=this.parseMethod(t,r,n);return"get"===e.kind&&0!==s.params.length&&this.raiseRecoverable(s.start,"getter should have no params"),"set"===e.kind&&1!==s.params.length&&this.raiseRecoverable(s.start,"setter should have exactly one param"),"set"===e.kind&&"RestElement"===s.params[0].type&&this.raiseRecoverable(s.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,i=0===n?null:this.privateNameStack[n-1],s=0;s=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(),i="Identifier"===n.key.type?n.key.name:n.key.value;D(t,i)&&this.raiseRecoverable(n.key.start,"Duplicate attribute key '"+i+"'"),t[i]=!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,i=e.properties;n=6)switch(this.type){case b.bracketL:var e=this.startNode();return this.next(),e.elements=this.parseBindingList(b.bracketR,!0,!0),this.finishNode(e,"ArrayPattern");case b.braceL:return this.parseObj(!0)}return this.parseIdent()},re.parseBindingList=function(e,t,r,n){for(var i=[],s=!0;!this.eat(e);)if(s?s=!1:this.expect(b.comma),t&&this.type===b.comma)i.push(null);else{if(r&&this.afterTrailingComma(e))break;if(this.type===b.ellipsis){var a=this.parseRestBinding();this.parseBindingListItem(a),i.push(a),this.type===b.comma&&this.raiseRecoverable(this.start,"Comma is not permitted after the rest element"),this.expect(e);break}i.push(this.parseAssignableListItem(n))}return i},re.parseAssignableListItem=function(e){var t=this.parseMaybeDefault(this.start,this.startLoc);return this.parseBindingListItem(t),t},re.parseBindingListItem=function(e){return e},re.parseMaybeDefault=function(e,t,r){if(r=r||this.parseBindingAtom(),this.options.ecmaVersion<6||!this.eat(b.eq))return r;var n=this.startNodeAt(e,t);return n.left=r,n.right=this.parseMaybeAssign(),this.finishNode(n,"AssignmentPattern")},re.checkLValSimple=function(e,t,r){void 0===t&&(t=0);var n=0!==t;switch(e.type){case"Identifier":this.strict&&this.reservedWordsStrictBind.test(e.name)&&this.raiseRecoverable(e.start,(n?"Binding ":"Assigning to ")+e.name+" in strict mode"),n&&(2===t&&"let"===e.name&&this.raiseRecoverable(e.start,"let is disallowed as a lexically bound name"),r&&(D(r,e.name)&&this.raiseRecoverable(e.start,"Argument name clash"),r[e.name]=!0),5!==t&&this.declareName(e.name,t,e.start));break;case"ChainExpression":this.raiseRecoverable(e.start,"Optional chaining cannot appear in left-hand side");break;case"MemberExpression":n&&this.raiseRecoverable(e.start,"Binding member expression");break;case"ParenthesizedExpression":return n&&this.raiseRecoverable(e.start,"Binding parenthesized expression"),this.checkLValSimple(e.expression,t,r);default:this.raise(e.start,(n?"Binding":"Assigning to")+" rvalue")}},re.checkLValPattern=function(e,t,r){switch(void 0===t&&(t=0),e.type){case"ObjectPattern":for(var n=0,i=e.properties;n=1;e--){var t=this.context[e];if("function"===t.token)return t.generator}return!1},se.updateContext=function(e){var t,r=this.type;r.keyword&&e===b.dot?this.exprAllowed=!1:(t=r.updateContext)?t.call(this,e):this.exprAllowed=r.beforeExpr},se.overrideContext=function(e){this.curContext()!==e&&(this.context[this.context.length-1]=e)},b.parenR.updateContext=b.braceR.updateContext=function(){if(1!==this.context.length){var e=this.context.pop();e===ie.b_stat&&"function"===this.curContext().token&&(e=this.context.pop()),this.exprAllowed=!e.isExpr}else this.exprAllowed=!0},b.braceL.updateContext=function(e){this.context.push(this.braceIsBlock(e)?ie.b_stat:ie.b_expr),this.exprAllowed=!0},b.dollarBraceL.updateContext=function(){this.context.push(ie.b_tmpl),this.exprAllowed=!0},b.parenL.updateContext=function(e){var t=e===b._if||e===b._for||e===b._with||e===b._while;this.context.push(t?ie.p_stat:ie.p_expr),this.exprAllowed=!0},b.incDec.updateContext=function(){},b._function.updateContext=b._class.updateContext=function(e){!e.beforeExpr||e===b._else||e===b.semi&&this.curContext()!==ie.p_stat||e===b._return&&T.test(this.input.slice(this.lastTokEnd,this.start))||(e===b.colon||e===b.braceL)&&this.curContext()===ie.b_stat?this.context.push(ie.f_stat):this.context.push(ie.f_expr),this.exprAllowed=!1},b.colon.updateContext=function(){"function"===this.curContext().token&&this.context.pop(),this.exprAllowed=!0},b.backQuote.updateContext=function(){this.curContext()===ie.q_tmpl?this.context.pop():this.context.push(ie.q_tmpl),this.exprAllowed=!1},b.star.updateContext=function(e){if(e===b._function){var t=this.context.length-1;this.context[t]===ie.f_expr?this.context[t]=ie.f_expr_gen:this.context[t]=ie.f_gen}this.exprAllowed=!0},b.name.updateContext=function(e){var t=!1;this.options.ecmaVersion>=6&&e!==b.dot&&("of"===this.value&&!this.exprAllowed||"yield"===this.value&&this.inGeneratorContext())&&(t=!0),this.exprAllowed=t};var ae=U.prototype;function oe(e){return"Identifier"===e.type||"ParenthesizedExpression"===e.type&&oe(e.expression)}function ue(e){return"MemberExpression"===e.type&&"PrivateIdentifier"===e.property.type||"ChainExpression"===e.type&&ue(e.expression)||"ParenthesizedExpression"===e.type&&ue(e.expression)}ae.checkPropClash=function(e,t,r){if(!(this.options.ecmaVersion>=9&&"SpreadElement"===e.type||this.options.ecmaVersion>=6&&(e.computed||e.method||e.shorthand))){var n,i=e.key;switch(i.type){case"Identifier":n=i.name;break;case"Literal":n=String(i.value);break;default:return}var s=e.kind;if(this.options.ecmaVersion>=6)"__proto__"===n&&"init"===s&&(t.proto&&(r?r.doubleProto<0&&(r.doubleProto=i.start):this.raiseRecoverable(i.start,"Redefinition of __proto__ property")),t.proto=!0);else{var a=t[n="$"+n];if(a)("init"===s?this.strict&&a.init||a.get||a.set:a.init||a[s])&&this.raiseRecoverable(i.start,"Redefinition of property");else a=t[n]={init:!1,get:!1,set:!1};a[s]=!0}}},ae.parseExpression=function(e,t){var r=this.start,n=this.startLoc,i=this.parseMaybeAssign(e,t);if(this.type===b.comma){var s=this.startNodeAt(r,n);for(s.expressions=[i];this.eat(b.comma);)s.expressions.push(this.parseMaybeAssign(e,t));return this.finishNode(s,"SequenceExpression")}return i},ae.parseMaybeAssign=function(e,t,r){if(this.isContextual("yield")){if(this.inGenerator)return this.parseYield(e);this.exprAllowed=!1}var n=!1,i=-1,s=-1,a=-1;t?(i=t.parenthesizedAssign,s=t.trailingComma,a=t.doubleProto,t.parenthesizedAssign=t.trailingComma=-1):(t=new H,n=!0);var o=this.start,u=this.startLoc;this.type!==b.parenL&&this.type!==b.name||(this.potentialArrowAt=this.start,this.potentialArrowInForAwait="await"===e);var l=this.parseMaybeConditional(e,t);if(r&&(l=r.call(this,l,o,u)),this.type.isAssign){var h=this.startNodeAt(o,u);return h.operator=this.value,this.type===b.eq&&(l=this.toAssignable(l,!1,t)),n||(t.parenthesizedAssign=t.trailingComma=t.doubleProto=-1),t.shorthandAssign>=l.start&&(t.shorthandAssign=-1),this.type===b.eq?this.checkLValPattern(l):this.checkLValSimple(l),h.left=l,this.next(),h.right=this.parseMaybeAssign(e),a>-1&&(t.doubleProto=a),this.finishNode(h,"AssignmentExpression")}return n&&this.checkExpressionErrors(t,!0),i>-1&&(t.parenthesizedAssign=i),s>-1&&(t.trailingComma=s),l},ae.parseMaybeConditional=function(e,t){var r=this.start,n=this.startLoc,i=this.parseExprOps(e,t);if(this.checkExpressionErrors(t))return i;if(this.eat(b.question)){var s=this.startNodeAt(r,n);return s.test=i,s.consequent=this.parseMaybeAssign(),this.expect(b.colon),s.alternate=this.parseMaybeAssign(e),this.finishNode(s,"ConditionalExpression")}return i},ae.parseExprOps=function(e,t){var r=this.start,n=this.startLoc,i=this.parseMaybeUnary(t,!1,!1,e);return this.checkExpressionErrors(t)||i.start===r&&"ArrowFunctionExpression"===i.type?i:this.parseExprOp(i,r,n,-1,e)},ae.parseExprOp=function(e,t,r,n,i){var s=this.type.binop;if(null!=s&&(!i||this.type!==b._in)&&s>n){var a=this.type===b.logicalOR||this.type===b.logicalAND,o=this.type===b.coalesce;o&&(s=b.logicalAND.binop);var u=this.value;this.next();var l=this.start,h=this.startLoc,c=this.parseExprOp(this.parseMaybeUnary(null,!1,!1,i),l,h,s,i),p=this.buildBinary(t,r,e,c,u,a||o);return(a&&this.type===b.coalesce||o&&(this.type===b.logicalOR||this.type===b.logicalAND))&&this.raiseRecoverable(this.start,"Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses"),this.parseExprOp(p,t,r,n,i)}return e},ae.buildBinary=function(e,t,r,n,i,s){"PrivateIdentifier"===n.type&&this.raise(n.start,"Private identifier can only be left side of binary expression");var a=this.startNodeAt(e,t);return a.left=r,a.operator=i,a.right=n,this.finishNode(a,s?"LogicalExpression":"BinaryExpression")},ae.parseMaybeUnary=function(e,t,r,n){var i,s=this.start,a=this.startLoc;if(this.isContextual("await")&&this.canAwait)i=this.parseAwait(n),t=!0;else if(this.type.prefix){var o=this.startNode(),u=this.type===b.incDec;o.operator=this.value,o.prefix=!0,this.next(),o.argument=this.parseMaybeUnary(null,!0,u,n),this.checkExpressionErrors(e,!0),u?this.checkLValSimple(o.argument):this.strict&&"delete"===o.operator&&oe(o.argument)?this.raiseRecoverable(o.start,"Deleting local variable in strict mode"):"delete"===o.operator&&ue(o.argument)?this.raiseRecoverable(o.start,"Private fields can not be deleted"):t=!0,i=this.finishNode(o,u?"UpdateExpression":"UnaryExpression")}else if(t||this.type!==b.privateId){if(i=this.parseExprSubscripts(e,n),this.checkExpressionErrors(e))return i;for(;this.type.postfix&&!this.canInsertSemicolon();){var l=this.startNodeAt(s,a);l.operator=this.value,l.prefix=!1,l.argument=i,this.checkLValSimple(i),this.next(),i=this.finishNode(l,"UpdateExpression")}}else(n||0===this.privateNameStack.length)&&this.options.checkPrivateFields&&this.unexpected(),i=this.parsePrivateIdent(),this.type!==b._in&&this.unexpected();return r||!this.eat(b.starstar)?i:t?void this.unexpected(this.lastTokStart):this.buildBinary(s,a,i,this.parseMaybeUnary(null,!1,!1,n),"**",!1)},ae.parseExprSubscripts=function(e,t){var r=this.start,n=this.startLoc,i=this.parseExprAtom(e,t);if("ArrowFunctionExpression"===i.type&&")"!==this.input.slice(this.lastTokStart,this.lastTokEnd))return i;var s=this.parseSubscripts(i,r,n,!1,t);return e&&"MemberExpression"===s.type&&(e.parenthesizedAssign>=s.start&&(e.parenthesizedAssign=-1),e.parenthesizedBind>=s.start&&(e.parenthesizedBind=-1),e.trailingComma>=s.start&&(e.trailingComma=-1)),s},ae.parseSubscripts=function(e,t,r,n,i){for(var s=this.options.ecmaVersion>=8&&"Identifier"===e.type&&"async"===e.name&&this.lastTokEnd===e.end&&!this.canInsertSemicolon()&&e.end-e.start==5&&this.potentialArrowAt===e.start,a=!1;;){var o=this.parseSubscript(e,t,r,n,s,a,i);if(o.optional&&(a=!0),o===e||"ArrowFunctionExpression"===o.type){if(a){var u=this.startNodeAt(t,r);u.expression=o,o=this.finishNode(u,"ChainExpression")}return o}e=o}},ae.shouldParseAsyncArrow=function(){return!this.canInsertSemicolon()&&this.eat(b.arrow)},ae.parseSubscriptAsyncArrow=function(e,t,r,n){return this.parseArrowExpression(this.startNodeAt(e,t),r,!0,n)},ae.parseSubscript=function(e,t,r,n,i,s,a){var o=this.options.ecmaVersion>=11,u=o&&this.eat(b.questionDot);n&&u&&this.raise(this.lastTokStart,"Optional chaining cannot appear in the callee of new expressions");var l=this.eat(b.bracketL);if(l||u&&this.type!==b.parenL&&this.type!==b.backQuote||this.eat(b.dot)){var h=this.startNodeAt(t,r);h.object=e,l?(h.property=this.parseExpression(),this.expect(b.bracketR)):this.type===b.privateId&&"Super"!==e.type?h.property=this.parsePrivateIdent():h.property=this.parseIdent("never"!==this.options.allowReserved),h.computed=!!l,o&&(h.optional=u),e=this.finishNode(h,"MemberExpression")}else if(!n&&this.eat(b.parenL)){var c=new H,p=this.yieldPos,d=this.awaitPos,m=this.awaitIdentPos;this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0;var f=this.parseExprList(b.parenR,this.options.ecmaVersion>=8,!1,c);if(i&&!u&&this.shouldParseAsyncArrow())return this.checkPatternErrors(c,!1),this.checkYieldAwaitInDefaultParams(),this.awaitIdentPos>0&&this.raise(this.awaitIdentPos,"Cannot use 'await' as identifier inside an async function"),this.yieldPos=p,this.awaitPos=d,this.awaitIdentPos=m,this.parseSubscriptAsyncArrow(t,r,f,a);this.checkExpressionErrors(c,!0),this.yieldPos=p||this.yieldPos,this.awaitPos=d||this.awaitPos,this.awaitIdentPos=m||this.awaitIdentPos;var g=this.startNodeAt(t,r);g.callee=e,g.arguments=f,o&&(g.optional=u),e=this.finishNode(g,"CallExpression")}else if(this.type===b.backQuote){(u||s)&&this.raise(this.start,"Optional chaining cannot appear in the tag of tagged template expressions");var x=this.startNodeAt(t,r);x.tag=e,x.quasi=this.parseTemplate({isTagged:!0}),e=this.finishNode(x,"TaggedTemplateExpression")}return e},ae.parseExprAtom=function(e,t,r){this.type===b.slash&&this.readRegexp();var n,i=this.potentialArrowAt===this.start;switch(this.type){case b._super:return this.allowSuper||this.raise(this.start,"'super' keyword outside a method"),n=this.startNode(),this.next(),this.type!==b.parenL||this.allowDirectSuper||this.raise(n.start,"super() call outside constructor of a subclass"),this.type!==b.dot&&this.type!==b.bracketL&&this.type!==b.parenL&&this.unexpected(),this.finishNode(n,"Super");case b._this:return n=this.startNode(),this.next(),this.finishNode(n,"ThisExpression");case b.name:var s=this.start,a=this.startLoc,o=this.containsEsc,u=this.parseIdent(!1);if(this.options.ecmaVersion>=8&&!o&&"async"===u.name&&!this.canInsertSemicolon()&&this.eat(b._function))return this.overrideContext(ie.f_expr),this.parseFunction(this.startNodeAt(s,a),0,!1,!0,t);if(i&&!this.canInsertSemicolon()){if(this.eat(b.arrow))return this.parseArrowExpression(this.startNodeAt(s,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(s,a),[u],!0,t)}return u;case b.regexp:var l=this.value;return(n=this.parseLiteral(l.value)).regex={pattern:l.pattern,flags:l.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 h=this.start,c=this.parseParenAndDistinguishExpression(i,t);return e&&(e.parenthesizedAssign<0&&!this.isSimpleAssignTarget(c)&&(e.parenthesizedAssign=h),e.parenthesizedBind<0&&(e.parenthesizedBind=h)),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(ie.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,i=this.startLoc,s=this.options.ecmaVersion>=8;if(this.options.ecmaVersion>=6){this.next();var a,o=this.start,u=this.startLoc,l=[],h=!0,c=!1,p=new H,d=this.yieldPos,m=this.awaitPos;for(this.yieldPos=0,this.awaitPos=0;this.type!==b.parenR;){if(h?h=!1:this.expect(b.comma),s&&this.afterTrailingComma(b.parenR,!0)){c=!0;break}if(this.type===b.ellipsis){a=this.start,l.push(this.parseParenItem(this.parseRestBinding())),this.type===b.comma&&this.raiseRecoverable(this.start,"Comma is not permitted after the rest element");break}l.push(this.parseMaybeAssign(!1,p,this.parseParenItem))}var f=this.lastTokEnd,g=this.lastTokEndLoc;if(this.expect(b.parenR),e&&this.shouldParseArrow(l)&&this.eat(b.arrow))return this.checkPatternErrors(p,!1),this.checkYieldAwaitInDefaultParams(),this.yieldPos=d,this.awaitPos=m,this.parseParenArrowList(n,i,l,t);l.length&&!c||this.unexpected(this.lastTokStart),a&&this.unexpected(a),this.checkExpressionErrors(p,!0),this.yieldPos=d||this.yieldPos,this.awaitPos=m||this.awaitPos,l.length>1?((r=this.startNodeAt(o,u)).expressions=l,this.finishNodeAt(r,"SequenceExpression",f,g)):r=l[0]}else r=this.parseParenExpression();if(this.options.preserveParens){var x=this.startNodeAt(n,i);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 le=[];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,i=this.startLoc;return e.callee=this.parseSubscripts(this.parseExprAtom(null,!1,!0),n,i,!0,!1),this.eat(b.parenL)?e.arguments=this.parseExprList(b.parenR,this.options.ecmaVersion>=8,!1):e.arguments=le,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,i={};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 s=this.parseProperty(e,t);e||this.checkPropClash(s,i,t),r.properties.push(s)}return this.finishNode(r,e?"ObjectPattern":"ObjectExpression")},ae.parseProperty=function(e,t){var r,n,i,s,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)&&(i=this.start,s=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,i,s,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,i,s,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=i),e.kind="init",t?e.value=this.parseMaybeDefault(i,s,this.copyNode(e.key)):this.type===b.eq&&a?(a.shorthandAssign<0&&(a.shorthandAssign=this.start),e.value=this.parseMaybeDefault(i,s,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(),i=this.yieldPos,s=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=i,this.awaitPos=s,this.awaitIdentPos=a,this.finishNode(n,"FunctionExpression")},ae.parseArrowExpression=function(e,t,r,n){var i=this.yieldPos,s=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=i,this.awaitPos=s,this.awaitIdentPos=a,this.finishNode(e,"ArrowFunctionExpression")},ae.parseFunctionBody=function(e,t,r,n){var i=t&&this.type!==b.braceL,s=this.strict,a=!1;if(i)e.body=this.parseMaybeAssign(n),e.expression=!0,this.checkParams(e,!1);else{var o=this.options.ecmaVersion>=7&&!this.isSimpleParamList(e.params);s&&!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,!s&&!a&&!t&&!r&&this.isSimpleParamList(e.params)),this.strict&&e.id&&this.checkLValSimple(e.id,5),e.body=this.parseBlock(!1,void 0,a&&!s),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||i.functions.indexOf(e)>-1||i.var.indexOf(e)>-1,i.lexical.push(e),this.inModule&&1&i.flags&&delete this.undefinedExports[e]}else if(4===t){this.currentScope().lexical.push(e)}else if(3===t){var s=this.currentScope();n=this.treatFunctionsAsVar?s.lexical.indexOf(e)>-1:s.lexical.indexOf(e)>-1||s.var.indexOf(e)>-1,s.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"},ve="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",Se="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=Se+" 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",ke={9:Se,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"},Ie={};function De(e){var t=Ie[e]={binary:L(be[e]+" "+ve),binaryOfStrings:L(Te[e]),nonBinary:{General_Category:L(ve),Script:L(ke[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,$e=[9,10,11,12,13,14];Ce<$e.length;Ce+=1){De($e[Ce])}var Le=U.prototype,Re=function(e,t){this.parent=e,this.base=t||this};Re.prototype.separatedFrom=function(e){for(var t=this;t;t=t.parent)for(var r=e;r;r=r.parent)if(t.base===r.base&&t!==r)return!0;return!1},Re.prototype.sibling=function(){return new Re(this.parent,this.base)};var Fe=function(e){this.parser=e,this.validFlags="gim"+(e.options.ecmaVersion>=6?"uy":"")+(e.options.ecmaVersion>=9?"s":"")+(e.options.ecmaVersion>=13?"d":"")+(e.options.ecmaVersion>=15?"v":""),this.unicodeProperties=Ie[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}Fe.prototype.reset=function(e,t,r){var n=-1!==r.indexOf("v"),i=-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=i&&this.parser.options.ecmaVersion>=6,this.switchV=!1,this.switchN=i&&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 i=r.charCodeAt(e);if(!t&&!this.switchU||i<=55295||i>=57344||e+1>=n)return i;var s=r.charCodeAt(e+1);return s>=56320&&s<=57343?(i<<10)+s-56613888:i},Fe.prototype.nextIndex=function(e,t){void 0===t&&(t=!1);var r=this.source,n=r.length;if(e>=n)return n;var i,s=r.charCodeAt(e);return!t&&!this.switchU||s<=55295||s>=57344||e+1>=n||(i=r.charCodeAt(e+1))<56320||i>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,i=e;n-1&&this.raise(e.start,"Duplicate regular expression flag"),"u"===a&&(n=!0),"v"===a&&(i=!0)}this.options.ecmaVersion>=15&&n&&i&&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 Re(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,i=-1;if(this.regexp_eatDecimalDigits(e)&&(n=e.lastIntValue,e.eat(44)&&this.regexp_eatDecimalDigits(e)&&(i=e.lastIntValue),e.eat(125)))return-1!==i&&i=16){var r=this.regexp_eatModifiers(e),n=e.eat(45);if(r||n){for(var i=0;i-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(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,i=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,i=t||e.switchU;if(e.eat(117)){if(this.regexp_eatFixedHexDigits(e,4)){var s=e.lastIntValue;if(i&&s>=55296&&s<=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*(s-55296)+(o-56320)+65536,!0}e.pos=a,e.lastIntValue=s}return!0}if(i&&e.eat(123)&&this.regexp_eatHexDigits(e)&&e.eat(125)&&((r=e.lastIntValue)>=0&&r<=1114111))return!0;i&&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};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}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 i=e.lastStringValue;return this.regexp_validateUnicodePropertyNameOrValue(e,i)}return 0},Le.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")},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+=R(t),e.advance();return""!==e.lastStringValue},Le.regexp_eatUnicodePropertyValue=function(e){var t=0;for(e.lastStringValue="";ze(t=e.current());)e.lastStringValue+=R(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 i=this.regexp_eatCharacterClassEscape(e);if(i)return i;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())},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,i=t;(n=A(this.input,i,this.pos))>-1;)++this.curLine,i=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);if(t===e){if(this.options.ecmaVersion>=12)if(61===this.input.charCodeAt(this.pos+2))return this.finishOp(b.assign,3);return this.finishOp(124===e?b.logicalOR:b.logicalAND,2)}return 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){if(e>=12)if(61===this.input.charCodeAt(this.pos+2))return this.finishOp(b.assign,3);return 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 '"+R(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 '"+R(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 i=this.input.slice(r,this.pos);++this.pos;var s=this.pos,a=this.readWord1();this.containsEsc&&this.unexpected(s);var o=this.regexpState||(this.regexpState=new Fe(this));o.reset(r,i,a),this.validateRegExpFlags(o),this.validateRegExpPattern(o);var u=null;try{u=new RegExp(i,a)}catch(e){}return this.finishToken(b.regexp,{pattern:i,flags:a,value:u})},We.readInt=function(e,t,r){for(var n=this.options.ecmaVersion>=12&&void 0===t,i=r&&48===this.input.charCodeAt(this.pos),s=this.pos,a=0,o=0,u=0,l=null==t?1/0:t;u=97?h-97+10:h>=65?h-65+10:h>=48&&h<=57?h-48:1/0)>=e)break;o=h,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===s||null!=t&&this.pos-s!==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 i=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,i)}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 s,a=(s=this.input.slice(t,this.pos),r?parseInt(s,8):parseFloat(s.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)):(S(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(S(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],i=parseInt(n,8);return i>255&&(n=n.slice(0,-1),i=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(i)}return S(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.pos0;)l.pop()}function v(e,t){h[e]=t}function S(e){const t=f[e];return t?r+"."+t:e}function A(e){y=" ".repeat(e)}function _(e,t){const n=`${r}Variable${m.length}`;return l.push(`${y}const ${n} = ${t};`),m.push(e),n}function E(e){l.push(`${y}// ${e}`)}function w(){l.push(`${y}(() => {\n${y}const error = ${r}.getError();\n${y}if (error !== ${r}.NONE) {\n${y} const names = Object.getOwnPropertyNames(gl);\n${y} for (let i = 0; i < names.length; i++) {\n${y} const name = names[i];\n${y} if (${r}[name] === error) {\n${y} throw new Error('${r} threw ' + name);\n${y} }\n${y} }\n${y}}\n${y}})();`)}function k(e,t){return`${r}.${e}(${s(t,{contextName:r,contextVariables:m,getEntity:S,addVariable:_,variables:h,onUnrecognizedArgumentLookup:p})})`}function I(e){const t=m.indexOf(e);return-1!==t?`${r}Variable${t}`:null}}function i(e,t){const r=new Proxy(e,{get:function(t,r){if("function"==typeof t[r])return function(){if("drawBuffersWEBGL"===r)return h.push(`${p}${i}.drawBuffersWEBGL([${s(arguments[0],{contextName:i,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(a(t))?(h.push(`${p}const ${i}Variable${o.length} = ${f(r,arguments)};`),o.push(t=a(t))):(h.push(`${p}const ${i}Variable${o.length} = ${f(r,arguments)};`),o.push(t));break;default:null===t?h.push(`${f(r,arguments)};`):h.push(`${p}const ${i}Variable${o.length} = ${f(r,arguments)};`),o.push(t)}return t};return n[e[r]]=r,e[r]}}),n={},{contextName:i,contextVariables:o,getEntity:u,useTrackablePrimitives:l,recording:h,variables:c,indent:p,onUnrecognizedArgumentLookup:d}=t;return r;function m(e){return n.hasOwnProperty(e)?`${i}.${n[e]}`:u(e)}function f(e,t){return`${i}.${e}(${s(t,{contextName:i,contextVariables:o,getEntity:m,addVariable:g,variables:c,onUnrecognizedArgumentLookup:d})})`}function g(e,t){const r=`${i}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 i=function(e){if(r)for(const t in r)if(r.hasOwnProperty(t)&&r[t]===e)return t;if(n)return n(e);return null}(e);return i||function(e,t){const{contextName:r,contextVariables:n,getEntity:i,addVariable:s,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 i(e);case"Array":return s(e,`new ${e.constructor.name}([${Array.from(e).join(",")}])`);case"Float32Array":case"Uint8Array":case"Uint16Array":case"Int32Array":return s(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 a(e){return new e.constructor(e)}void 0!==t&&(t.exports={glWiretap:n,glExtensionWiretap:i}),"undefined"!=typeof window&&(n.glExtensionWiretap=i,window.glWiretap=n)},{}],4:[function(e,t,r){function n(e){const t=new Array(e.length);for(let r=0;r{e.output=h(t),e.graphical&&l(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&&l(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,i=4*t,s=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;n0&&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(s.join("")),t.push(`\n${i.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);return this.astGeneric(e.left,t),t.push(e.operator),this.astGeneric(e.right,t),t}astBlockStatement(e,t){if(this.isState("loop-body")){this.pushState("block-body");for(let r=0;r0&&t.push(",");const n=r[e],i=this.getDeclaration(n.id);i.valueType||(i.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:i,xProperty:s,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(i){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(s,t),t.push("]")):(t.push("["),this.astGeneric(o,t),t.push("]"),t.push("["),this.astGeneric(a,t),t.push("]"),t.push("["),this.astGeneric(s,t),t.push("]")):a?r?(t.push("[("),this.astGeneric(a,t),t.push(`*${this.dynamicArguments?"outputX":e[0]})+`),this.astGeneric(s,t),t.push("]")):(t.push("["),this.astGeneric(a,t),t.push("]"),t.push("["),this.astGeneric(s,t),t.push("]")):void 0!==s&&(t.push("["),this.astGeneric(s,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 i=0;i0&&t.push(", "),this.astGeneric(s,t)}return t.push(")"),t}astArrayExpression(e,t){const r=this.getType(e),n=e.elements.length,i=[];for(let t=0;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});i.push(" _imageData,"," _colorData,",` color: ${t},`),s.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"}}});s.push(t),i.push(" _mediaTo2DArray,"),i.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")}});s.push(t),i.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({ ${i.join("\n")} });\n ${s.join("\n")}\n return kernel;\n}`}}},{"../../utils":114}],8:[function(e,t,r){const{Kernel:n}=e("../kernel"),{FunctionBuilder:i}=e("../function-builder"),{CPUFunctionNode:s}=e("./function-node"),{utils:a}=e("../../utils"),{cpuKernelString:o}=e("./kernel-string");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"):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=a.getVariableType(e[0],this.strictIntegers);if("Array"===t)this.output=a.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=i.fromKernel(this,s);this.translatedSources=e.getPrototypes("kernel"),this.graphical||this.returnType||(this.returnType=e.getKernelResultType())}build(){if(this.built)return;if(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 i=this.output[0],s=this.output[1],a=this.thread.x+(s-this.thread.y-1)*i;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 o(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${i?` || ${i}`:""}`)}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=i.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}}}},{"../../utils":114,"../function-builder":9,"../kernel":36,"./function-node":6,"./kernel-string":7}],9:[function(e,t,r){class n{static fromKernel(e,t,r){const{kernelArguments:i,kernelConstants:s,argumentNames:a,argumentSizes:o,argumentBitRatios:u,constants:l,constantBitRatios:h,debug:c,loopMaxIterations:p,nativeFunctions:d,output:m,optimizeFloatMemory:f,precision:g,plugins:x,source:y,subKernels:b,functions:T,leadingReturnStatement:v,followingReturnStatement:S,dynamicArguments:A,dynamicOutput:_}=e,E=new Array(i.length),w={};for(let e=0;eG.needsArgumentType(e,t),I=(e,t,r)=>{G.assignArgumentType(e,t,r)},D=(e,t,r)=>G.lookupReturnType(e,t,r),C=e=>G.lookupFunctionArgumentTypes(e),$=(e,t)=>G.lookupFunctionArgumentName(e,t),L=(e,t)=>G.lookupFunctionArgumentBitRatio(e,t),R=(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,r)=>{const n=[];for(let t=0;tnew t(e.source,{returnType:e.returnType,argumentTypes:e.argumentTypes,output:m,plugins:x,constants:l,constantTypes:w,constantBitRatios:h,optimizeFloatMemory:f,precision:g,lookupReturnType:D,lookupFunctionArgumentTypes:C,lookupFunctionArgumentName:$,lookupFunctionArgumentBitRatio:L,needsArgumentType:k,assignArgumentType:I,triggerImplyArgumentType:R,triggerImplyArgumentBitRatio:F,onFunctionCall:N,onNestedFunction:V}))));let K=null;b&&(K=b.map((e=>{const{name:r,source:n}=e;return new t(n,Object.assign({},M,{name:r,isSubKernel:!0,isRootKernel:!1}))})));const G=new n({kernel:e,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[i].source);continue}const s=this.functionMap[n];s&&t.push(s.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 i=t.arguments;for(let t=0;t0&&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})),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:i,functionCalls:a}=new s(e);this.contexts=t,this.identifiers=i,this.functionCalls=a,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 a[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;e-1}isAstMathFunction(e){return"CallExpression"===e.type&&e.callee&&"MemberExpression"===e.callee.type&&e.callee.object&&"Identifier"===e.callee.object.type&&"Math"===e.callee.object.name&&e.callee.property&&"Identifier"===e.callee.property.type&&["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"].indexOf(e.callee.property.name)>-1}isAstVariable(e){return"Identifier"===e.type||"MemberExpression"===e.type}isSafe(e){return this.isSafeDependencies(this.getDependencies(e))}isSafeDependencies(e){return!e||!e.every||e.every((e=>e.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 i=this.getMemberExpressionDetails(e);switch(i.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:i.name,origin:"output",isSafe:!1})}if(i)return i.property&&this.getDependencies(i.property,t,r),i.xProperty&&this.getDependencies(i.xProperty,t,r),i.yProperty&&this.getDependencies(i.yProperty,t,r),i.zProperty&&this.getDependencies(i.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("");if(t)return n;return["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()[][][]","[][]"].indexOf(n)>-1?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 ${s.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;r0?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 i(this.functionContexts)}get currentContext(){return i(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=i(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,i=t[e]||r[e]||null;if(!i&&t===r&&n.length>0){const t=n[n.length-2];if(t[e])return t[e]}return i}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,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}"`)}}}}},{"../utils":114}],12:[function(e,t,r){const{glWiretap:n}=e("gl-wiretap"),{utils:i}=e("../../utils");function s(e){return e.toString().replace("=>","").replace(/^function /,"").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,r){const n=e.toArray.toString(),s=!/^function/.test(n);return`() => {\n function framebuffer() { return ${r}; };\n ${i.flattenFunctionToString(`${s?"function ":""}${n}`,{findDependency:(t,r)=>{if("utils"===t)return`const ${r} = ${i[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,i){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 i=0;i{switch(typeof e){case"boolean":return new Boolean(e);case"number":return new Number(e);default:return e}})):null;const c=[],p=[],d=n(r.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,S?Object.keys(S).map((e=>S[e])):[],d,c);return r||null}});let m=!1,f=0;const{source:g,canvas:x,output:y,pipeline:b,graphical:T,loopMaxIterations:v,constants:S,optimizeFloatMemory:A,precision:_,fixIntegerDivisionAccuracy:E,functions:w,nativeFunctions:k,subKernels:I,immutable:D,argumentTypes:C,constantTypes:$,kernelArguments:L,kernelConstants:R,tactic:F}=r,N=new e(g,{canvas:x,context:d,checkContext:!1,output:y,pipeline:b,graphical:T,loopMaxIterations:v,constants:S,optimizeFloatMemory:A,precision:_,fixIntegerDivisionAccuracy:E,functions:w,nativeFunctions:k,subKernels:I,immutable:D,argumentTypes:C,constantTypes:$,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){d.reset();const e=d.getContextVariableName(N.framebuffer);if(N.renderKernels){const t=N.renderKernels(),r=d.getContextVariableName(N.texture.texture);V.push(` return {\n result: {\n texture: ${r},\n type: '${t.result.type}',\n toArray: ${o(t.result,r,e)}\n },`);const{subKernels:n,mappedTextures:i}=N;for(let r=0;r"utils"===e?`const ${t} = ${i[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 R.forEach((e=>{M.push(`${e.getStringValueHandler()}`)})),`function kernel(settings) {\n const { context, constants } = settings;\n ${M.join("")}\n ${l||""}\n${V.join("\n")}\n}`}}},{"../../utils":114,"gl-wiretap":3}],13:[function(e,t,r){const{Kernel:n}=e("../kernel"),{utils:i}=e("../../utils"),{GLTextureArray2Float:s}=e("./texture/array-2-float"),{GLTextureArray2Float2D:a}=e("./texture/array-2-float-2d"),{GLTextureArray2Float3D:o}=e("./texture/array-2-float-3d"),{GLTextureArray3Float:u}=e("./texture/array-3-float"),{GLTextureArray3Float2D:l}=e("./texture/array-3-float-2d"),{GLTextureArray3Float3D:h}=e("./texture/array-3-float-3d"),{GLTextureArray4Float:c}=e("./texture/array-4-float"),{GLTextureArray4Float2D:p}=e("./texture/array-4-float-2d"),{GLTextureArray4Float3D:d}=e("./texture/array-4-float-3d"),{GLTextureFloat:m}=e("./texture/float"),{GLTextureFloat2D:f}=e("./texture/float-2d"),{GLTextureFloat3D:g}=e("./texture/float-3d"),{GLTextureMemoryOptimized:x}=e("./texture/memory-optimized"),{GLTextureMemoryOptimized2D:y}=e("./texture/memory-optimized-2d"),{GLTextureMemoryOptimized3D:b}=e("./texture/memory-optimized-3d"),{GLTextureUnsigned:T}=e("./texture/unsigned"),{GLTextureUnsigned2D:v}=e("./texture/unsigned-2d"),{GLTextureUnsigned3D:S}=e("./texture/unsigned-3d"),{GLTextureGraphical:A}=e("./texture/graphical");const _={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 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 i.warnDeprecated("method","setFloatTextures","setOptimizeFloatMemory"),this.floatTextures=e,this}static nativeFunctionArguments(e){const t=[],r=[],n=[],i=/^[a-zA-Z_]/,s=/[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(!i.test(l))throw new Error("variable name is not expected string")}o+=l,s.test(h)||(n.pop(),r.push(o),t.push(_[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 _[e.match(/int|float|vec[2-4]/)[0]]}static combineKernels(e,t){e.apply(null,arguments);const{texSize:r,context:n,threadDim:s}=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),n.readPixels(0,0,e,4*t,n.RGBA,n.FLOAT,a)}else{const e=new Uint8Array(r[0]*r[1]*4);n.readPixels(0,0,r[0],r[1],n.RGBA,n.UNSIGNED_BYTE,e),a=new Float32Array(e.buffer)}if(a=a.subarray(0,s[0]*s[1]*s[2]),1===t.output.length)return a;if(2===t.output.length)return i.splitArray(a,t.output[0]);if(3===t.output.length){return i.splitArray(a,t.output[0]*t.output[1]).map((function(e){return i.splitArray(e,t.output[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=A,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=S,null):this.output[1]>0?(this.TextureConstructor=v,null):(this.TextureConstructor=T,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=S,this.formatValues=i.erect3DPackedFloat,null):this.output[1]>0?(this.TextureConstructor=v,this.formatValues=i.erect2DPackedFloat,null):(this.TextureConstructor=T,this.formatValues=i.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=b,null):this.output[1]>0?(this.TextureConstructor=y,null):(this.TextureConstructor=x,null):this.output[2]>0?(this.TextureConstructor=g,null):this.output[1]>0?(this.TextureConstructor=f,null):(this.TextureConstructor=m,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=o,null):this.output[1]>0?(this.TextureConstructor=a,null):(this.TextureConstructor=s,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=h,null):this.output[1]>0?(this.TextureConstructor=l,null):(this.TextureConstructor=u,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=d,null):this.output[1]>0?(this.TextureConstructor=p,null):(this.TextureConstructor=c,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=b,this.formatValues=i.erectMemoryOptimized3DFloat,null):this.output[1]>0?(this.TextureConstructor=y,this.formatValues=i.erectMemoryOptimized2DFloat,null):(this.TextureConstructor=x,this.formatValues=i.erectMemoryOptimizedFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=o,this.formatValues=i.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=a,this.formatValues=i.erect2DArray2,null):(this.TextureConstructor=s,this.formatValues=i.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=h,this.formatValues=i.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=l,this.formatValues=i.erect2DArray3,null):(this.TextureConstructor=u,this.formatValues=i.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=d,this.formatValues=i.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=p,this.formatValues=i.erect2DArray4,null):(this.TextureConstructor=c,this.formatValues=i.erectArray4,null)}else switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=g,this.formatValues=i.erect3DFloat,null):this.output[1]>0?(this.TextureConstructor=f,this.formatValues=i.erect2DFloat,null):(this.TextureConstructor=m,this.formatValues=i.erectFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=o,this.formatValues=i.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=a,this.formatValues=i.erect2DArray2,null):(this.TextureConstructor=s,this.formatValues=i.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=h,this.formatValues=i.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=l,this.formatValues=i.erect2DArray3,null):(this.TextureConstructor=u,this.formatValues=i.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=d,this.formatValues=i.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=p,this.formatValues=i.erect2DArray4,null):(this.TextureConstructor=c,this.formatValues=i.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 i.linesToString(this.getMainResultKernelNumberTexture())+i.linesToString(this.getMainResultSubKernelNumberTexture())}getMainResultArray2Texture(){return i.linesToString(this.getMainResultKernelArray2Texture())+i.linesToString(this.getMainResultSubKernelArray2Texture())}getMainResultArray3Texture(){return i.linesToString(this.getMainResultKernelArray3Texture())+i.linesToString(this.getMainResultSubKernelArray3Texture())}getMainResultArray4Texture(){return i.linesToString(this.getMainResultKernelArray4Texture())+i.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],i=new Float32Array(r*n*4);return t.readPixels(0,0,r,n,t.RGBA,t.FLOAT,i),i}getPixels(e){const{context:t,output:r}=this,[n,s]=r,a=new Uint8Array(n*s*4);return t.readPixels(0,0,n,s,t.RGBA,t.UNSIGNED_BYTE,a),new Uint8ClampedArray((e?a:i.flipPixels(a,n,s)).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;n1&&(this.newTexture(),!0)}cloneTexture(){this.texture._refs--;const{context:e,size:t,texture:r,kernel:n}=this;n.debug&&console.warn("cloning internal texture"),e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),i(e,r),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,r,0);const s=e.createTexture();i(e,s),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]),s._refs=1,this.texture=s}newTexture(){this.texture._refs--;const e=this.context,t=this.size;this.kernel.debug&&console.warn("new internal texture");const r=e.createTexture();i(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();i(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),i(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.context.deleteTexture(this.texture))}framebuffer(){return this._framebuffer||(this._framebuffer=this.kernel.getRawValueFramebuffer(this.size[0],this.size[1])),this._framebuffer}}}},{"../../../texture":113}],28:[function(e,t,r){const{utils:n}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureMemoryOptimized2D:class extends i{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return n.erectMemoryOptimized2DFloat(this.renderValues(),this.output[0],this.output[1])}}}},{"../../../utils":114,"./float":25}],29:[function(e,t,r){const{utils:n}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureMemoryOptimized3D:class extends i{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return n.erectMemoryOptimized3DFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}},{"../../../utils":114,"./float":25}],30:[function(e,t,r){const{utils:n}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureMemoryOptimized:class extends i{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return n.erectMemoryOptimizedFloat(this.renderValues(),this.output[0])}}}},{"../../../utils":114,"./float":25}],31:[function(e,t,r){const{utils:n}=e("../../../utils"),{GLTextureUnsigned:i}=e("./unsigned");t.exports={GLTextureUnsigned2D:class extends i{constructor(e){super(e),this.type="NumberTexture"}toArray(){return n.erect2DPackedFloat(this.renderValues(),this.output[0],this.output[1])}}}},{"../../../utils":114,"./unsigned":33}],32:[function(e,t,r){const{utils:n}=e("../../../utils"),{GLTextureUnsigned:i}=e("./unsigned");t.exports={GLTextureUnsigned3D:class extends i{constructor(e){super(e),this.type="NumberTexture"}toArray(){return n.erect3DPackedFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}},{"../../../utils":114,"./unsigned":33}],33:[function(e,t,r){const{utils:n}=e("../../../utils"),{GLTexture:i}=e("./index");t.exports={GLTextureUnsigned:class extends i{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])}}}},{"../../../utils":114,"./index":27}],34:[function(e,t,r){const n=e("gl"),{WebGLKernel:i}=e("../web-gl/kernel"),{glKernelString:s}=e("../gl/kernel-string");let a=null,o=null,u=null,l=null,h=null;t.exports={HeadlessGLKernel:class extends i{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 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}}}},{"../gl/kernel-string":12,"../web-gl/kernel":70,gl:2}],35:[function(e,t,r){t.exports={KernelValue:class{constructor(e,t){const{name:r,kernel:n,context:i,checkContext:s,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=i,this.checkContext=null==s||s,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}`)}}}},{}],36:[function(e,t,r){const{utils:n}=e("../utils"),{Input:i}=e("../input");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.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 i=0;it.argumentTypes[e]))||[]:t.argumentTypes||[],{name:n.getFunctionNameFromString(r)||null,source:r,argumentTypes:i,returnType:t.returnType||null}}onActivate(e){}}}},{"../input":110,"../utils":114}],37:[function(e,t,r){const n=`__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 (v1 == 0.0 || v2 == 0.0) return 0.0;\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 int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if (modi(a, 2) == 0) {\n result += n; \n }\n a = a / 2;\n n = n * 2;\n }\n return result;\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\nint bitwiseSignedRightShift(int num, int shifts) {\n return int(floor(float(num) / pow(2.0, 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__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\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 = exp2(_round(exponent));\n texel.b = texel.b - 128.0 * gte128.x;\n res = dot(texel, SCALE_FACTOR) * exp2(_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\n mantissa = value*pow(2.0, -exponent)-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}`;t.exports={fragmentShader:n}},{}],38:[function(e,t,r){const{utils:n}=e("../../utils"),{FunctionNode:i}=e("../function-node");const s={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"},a={"===":"==","!==":"!="};t.exports={WebGLFunctionNode:class extends i{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{if(!this.returnType){this.findLastReturn()&&(this.returnType=this.getType(e.body),"LiteralInteger"===this.returnType&&(this.returnType="Number"))}const{returnType:r}=this;if(r){const e=s[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 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[r]=a="Number");const o=s[a];if(!o)throw this.astErrorOutput("Unexpected expression",e);const u=n.sanitizeName(i);"sampler2D"===o||"sampler2DArray"===o?t.push(`${o} user_${u},ivec2 user_${u}Size,ivec3 user_${u}Dim`):t.push(`${o} user_${u}`)}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=[];this.astGeneric(e.right,r);if("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(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.astGeneric(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 ${i}`,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;t.push(r),t.push("(");switch(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)}t.push(",");switch(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 r=this.getType(e),i=n.sanitizeName(e.name);return"Infinity"===e.name?t.push("3.402823466e+38"):"Boolean"===r&&this.argumentNames.indexOf(i)>-1?t.push(`bool(user_${i})`):t.push(`user_${i}`),t}astForStatement(e,t){if("ForStatement"!==e.type)throw this.astErrorOutput("Invalid for statement",e);const r=[],n=[],i=[],s=[];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(s.join("")),t.push(`\n${i.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}0&&o.push(u.join(",")),i.push(o.join(";")),t.push(i.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}astSwitchStatement(e,t){if("SwitchStatement"!==e.type)throw this.astErrorOutput("Invalid switch statement",e);const{discriminant:r,cases:n}=e,i=this.getType(r),s=`switchDiscriminant${this.astKey(e,"_")}`;switch(i){case"Float":case"Number":t.push(`float ${s} = `),this.astGeneric(r,t),t.push(";\n");break;case"Integer":t.push(`int ${s} = `),this.astGeneric(r,t),t.push(";\n")}if(1===n.length&&!n[0].test)return this.astGeneric(n[0].consequent,t),t;let a=!1,o=[],u=!1,l=!1;for(let e=0;ee+1){u=!0,this.astGeneric(n[e].consequent,o);continue}t.push(" else {\n")}this.astGeneric(n[e].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:i,signature:s,origin:a,type:o,xProperty:u,yProperty:l,zProperty:h}=this.getMemberExpressionDetails(e);switch(s){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(`threadId.${i}`),t;case"this.output.value":if(this.dynamicOutput)switch(i){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(i){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[i]),t;const s=n.sanitizeName(i);switch(r){case"r":return t.push(`user_${s}.r`),t;case"g":return t.push(`user_${s}.g`),t;case"b":return t.push(`user_${s}.b`),t;case"a":return t.push(`user_${s}.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(i)}`),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()[][]":return this.astCallExpression(e.object.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(e.object.property)),t.push("]"),t.push("["),t.push(this.memberExpressionPropertyMarkup(e.property)),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(i)}`),t}const c=`${a}_${n.sanitizeName(i)}`;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(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"ArrayTexture(1)":t.push(`getFloatFromSampler2D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"Array1D(2)":case"Array2D(2)":case"Array3D(2)":t.push(`getMemoryOptimizedVec2(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"ArrayTexture(2)":t.push(`getVec2FromSampler2D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"Array1D(3)":case"Array2D(3)":case"Array3D(3)":t.push(`getMemoryOptimizedVec3(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"ArrayTexture(3)":t.push(`getVec3FromSampler2D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"Array1D(4)":case"Array2D(4)":case"Array3D(4)":t.push(`getMemoryOptimizedVec4(${c}, ${c}Size, ${c}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(${c}, ${c}Size, ${c}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(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");else{const e="user"===a?this.lookupFunctionArgumentBitRatio(this.name,i):this.constantBitRatios[i];switch(e){case 1:t.push(`get8(${c}, ${c}Size, ${c}Dim, `);break;case 2:t.push(`get16(${c}, ${c}Size, ${c}Dim, `);break;case 4:case 0:t.push(`get32(${c}, ${c}Size, ${c}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(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":t.push(`${c}[${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 i=this.isAstMathFunction(e);if(r=i||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"===i)this.castValueToFloat(n,t);else this.astGeneric(n,t)}else{const i=this.lookupFunctionArgumentTypes(r)||[];for(let s=0;s0&&t.push(", ");const u=this.getType(a);switch(o||(this.triggerImplyArgumentType(r,s,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,s);const i=n.sanitizeName(a.name);t.push(`user_${i},user_${i}Size,user_${i}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)}return t.join("")}}}},{"../../utils":114,"../function-node":10}],39:[function(e,t,r){const{WebGLKernelValueBoolean:n}=e("./kernel-value/boolean"),{WebGLKernelValueFloat:i}=e("./kernel-value/float"),{WebGLKernelValueInteger:s}=e("./kernel-value/integer"),{WebGLKernelValueHTMLImage:a}=e("./kernel-value/html-image"),{WebGLKernelValueDynamicHTMLImage:o}=e("./kernel-value/dynamic-html-image"),{WebGLKernelValueHTMLVideo:u}=e("./kernel-value/html-video"),{WebGLKernelValueDynamicHTMLVideo:l}=e("./kernel-value/dynamic-html-video"),{WebGLKernelValueSingleInput:h}=e("./kernel-value/single-input"),{WebGLKernelValueDynamicSingleInput:c}=e("./kernel-value/dynamic-single-input"),{WebGLKernelValueUnsignedInput:p}=e("./kernel-value/unsigned-input"),{WebGLKernelValueDynamicUnsignedInput:d}=e("./kernel-value/dynamic-unsigned-input"),{WebGLKernelValueMemoryOptimizedNumberTexture:m}=e("./kernel-value/memory-optimized-number-texture"),{WebGLKernelValueDynamicMemoryOptimizedNumberTexture:f}=e("./kernel-value/dynamic-memory-optimized-number-texture"),{WebGLKernelValueNumberTexture:g}=e("./kernel-value/number-texture"),{WebGLKernelValueDynamicNumberTexture:x}=e("./kernel-value/dynamic-number-texture"),{WebGLKernelValueSingleArray:y}=e("./kernel-value/single-array"),{WebGLKernelValueDynamicSingleArray:b}=e("./kernel-value/dynamic-single-array"),{WebGLKernelValueSingleArray1DI:T}=e("./kernel-value/single-array1d-i"),{WebGLKernelValueDynamicSingleArray1DI:v}=e("./kernel-value/dynamic-single-array1d-i"),{WebGLKernelValueSingleArray2DI:S}=e("./kernel-value/single-array2d-i"),{WebGLKernelValueDynamicSingleArray2DI:A}=e("./kernel-value/dynamic-single-array2d-i"),{WebGLKernelValueSingleArray3DI:_}=e("./kernel-value/single-array3d-i"),{WebGLKernelValueDynamicSingleArray3DI:E}=e("./kernel-value/dynamic-single-array3d-i"),{WebGLKernelValueArray2:w}=e("./kernel-value/array2"),{WebGLKernelValueArray3:k}=e("./kernel-value/array3"),{WebGLKernelValueArray4:I}=e("./kernel-value/array4"),{WebGLKernelValueUnsignedArray:D}=e("./kernel-value/unsigned-array"),{WebGLKernelValueDynamicUnsignedArray:C}=e("./kernel-value/dynamic-unsigned-array"),$={unsigned:{dynamic:{Boolean:n,Integer:s,Float:i,Array:C,"Array(2)":w,"Array(3)":k,"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:d,NumberTexture:x,"ArrayTexture(1)":x,"ArrayTexture(2)":x,"ArrayTexture(3)":x,"ArrayTexture(4)":x,MemoryOptimizedNumberTexture:f,HTMLCanvas:o,OffscreenCanvas:o,HTMLImage:o,ImageBitmap:o,ImageData:o,HTMLImageArray:!1,HTMLVideo:l},static:{Boolean:n,Float:i,Integer:s,Array:D,"Array(2)":w,"Array(3)":k,"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}},single:{dynamic:{Boolean:n,Integer:s,Float:i,Array:b,"Array(2)":w,"Array(3)":k,"Array(4)":I,"Array1D(2)":v,"Array1D(3)":v,"Array1D(4)":v,"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:o,OffscreenCanvas:o,HTMLImage:o,ImageBitmap:o,ImageData:o,HTMLImageArray:!1,HTMLVideo:l},static:{Boolean:n,Float:i,Integer:s,Array:y,"Array(2)":w,"Array(3)":k,"Array(4)":I,"Array1D(2)":T,"Array1D(3)":T,"Array1D(4)":T,"Array2D(2)":S,"Array2D(3)":S,"Array2D(4)":S,"Array3D(2)":_,"Array3D(3)":_,"Array3D(4)":_,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}}};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 i=$[r][t];if(!1===i[e])return null;if(void 0===i[e])throw new Error(`Could not find a KernelValue for ${e}`);return i[e]},kernelValueMaps:$}},{"./kernel-value/array2":41,"./kernel-value/array3":42,"./kernel-value/array4":43,"./kernel-value/boolean":44,"./kernel-value/dynamic-html-image":45,"./kernel-value/dynamic-html-video":46,"./kernel-value/dynamic-memory-optimized-number-texture":47,"./kernel-value/dynamic-number-texture":48,"./kernel-value/dynamic-single-array":49,"./kernel-value/dynamic-single-array1d-i":50,"./kernel-value/dynamic-single-array2d-i":51,"./kernel-value/dynamic-single-array3d-i":52,"./kernel-value/dynamic-single-input":53,"./kernel-value/dynamic-unsigned-array":54,"./kernel-value/dynamic-unsigned-input":55,"./kernel-value/float":56,"./kernel-value/html-image":57,"./kernel-value/html-video":58,"./kernel-value/integer":60,"./kernel-value/memory-optimized-number-texture":61,"./kernel-value/number-texture":62,"./kernel-value/single-array":63,"./kernel-value/single-array1d-i":64,"./kernel-value/single-array2d-i":65,"./kernel-value/single-array3d-i":66,"./kernel-value/single-input":67,"./kernel-value/unsigned-array":68,"./kernel-value/unsigned-input":69}],40:[function(e,t,r){const{WebGLKernelValue:n}=e("./index"),{Input:i}=e("../../../input");t.exports={WebGLKernelArray:class extends n{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`):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&&t.isTextureFloat&&(this.precision=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=y.indexOf(t);-1===r&&(r=y.length,y.push(t),b[r]=[e[0],e[1]]),this.maxTexSize=b[r]}this.maxTexSize[0]this.argumentNames.length)throw new Error("too many arguments for kernel");const{context:r}=this;let n=0;const i=()=>this.createTexture(),s=()=>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[i]=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 i=this.threadDim=Array.from(this.output);for(;i.length<3;)i.push(1);const s=this.getVertexShader(arguments),a=r.createShader(r.VERTEX_SHADER);r.shaderSource(a,s),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");r.enableVertexAttribArray(m),r.vertexAttribPointer(m,2,r.FLOAT,!1,0,0);const f=r.getAttribLocation(this.program,"aTexCoord");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=i.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 && integerMod(x, y) == 0.0) {\n return float(int(x) / int(y));\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 h(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=y.indexOf(this.canvas);e>=0&&(y[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=i.fromKernel(this,s).toJSON(),e.settings.threadDim=this.threadDim,e}}}},{"../../plugins/math-random-uniformly-distributed":112,"../../utils":114,"../function-builder":9,"../gl/kernel":13,"../gl/kernel-string":12,"./fragment-shader":37,"./function-node":38,"./kernel-value-maps":39,"./vertex-shader":71}],71:[function(e,t,r){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}"}},{}],72:[function(e,t,r){const n=`#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 (v1 == 0.0 || v2 == 0.0) return 0.0;\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 int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if (modi(a, 2) == 0) {\n result += n; \n }\n a = a / 2;\n n = n * 2;\n }\n return result;\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\nint bitwiseSignedRightShift(int num, int shifts) {\n return int(floor(float(num) / pow(2.0, 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__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\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 = exp2(round(exponent));\n texel.b = texel.b - 128.0 * gte128.x;\n res = dot(texel, SCALE_FACTOR) * exp2(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\n mantissa = value*pow(2.0, -exponent)-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}`;t.exports={fragmentShader:n}},{}],73:[function(e,t,r){const{utils:n}=e("../../utils"),{WebGLFunctionNode:i}=e("../web-gl/function-node");t.exports={WebGL2FunctionNode:class extends i{astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const r=this.getType(e),i=n.sanitizeName(e.name);return"Infinity"===e.name?t.push("intBitsToFloat(2139095039)"):"Boolean"===r&&this.argumentNames.indexOf(i)>-1?t.push(`bool(user_${i})`):t.push(`user_${i}`),t}}}},{"../../utils":114,"../web-gl/function-node":38}],74:[function(e,t,r){const{WebGL2KernelValueBoolean:n}=e("./kernel-value/boolean"),{WebGL2KernelValueFloat:i}=e("./kernel-value/float"),{WebGL2KernelValueInteger:s}=e("./kernel-value/integer"),{WebGL2KernelValueHTMLImage:a}=e("./kernel-value/html-image"),{WebGL2KernelValueDynamicHTMLImage:o}=e("./kernel-value/dynamic-html-image"),{WebGL2KernelValueHTMLImageArray:u}=e("./kernel-value/html-image-array"),{WebGL2KernelValueDynamicHTMLImageArray:l}=e("./kernel-value/dynamic-html-image-array"),{WebGL2KernelValueHTMLVideo:h}=e("./kernel-value/html-video"),{WebGL2KernelValueDynamicHTMLVideo:c}=e("./kernel-value/dynamic-html-video"),{WebGL2KernelValueSingleInput:p}=e("./kernel-value/single-input"),{WebGL2KernelValueDynamicSingleInput:d}=e("./kernel-value/dynamic-single-input"),{WebGL2KernelValueUnsignedInput:m}=e("./kernel-value/unsigned-input"),{WebGL2KernelValueDynamicUnsignedInput:f}=e("./kernel-value/dynamic-unsigned-input"),{WebGL2KernelValueMemoryOptimizedNumberTexture:g}=e("./kernel-value/memory-optimized-number-texture"),{WebGL2KernelValueDynamicMemoryOptimizedNumberTexture:x}=e("./kernel-value/dynamic-memory-optimized-number-texture"),{WebGL2KernelValueNumberTexture:y}=e("./kernel-value/number-texture"),{WebGL2KernelValueDynamicNumberTexture:b}=e("./kernel-value/dynamic-number-texture"),{WebGL2KernelValueSingleArray:T}=e("./kernel-value/single-array"),{WebGL2KernelValueDynamicSingleArray:v}=e("./kernel-value/dynamic-single-array"),{WebGL2KernelValueSingleArray1DI:S}=e("./kernel-value/single-array1d-i"),{WebGL2KernelValueDynamicSingleArray1DI:A}=e("./kernel-value/dynamic-single-array1d-i"),{WebGL2KernelValueSingleArray2DI:_}=e("./kernel-value/single-array2d-i"),{WebGL2KernelValueDynamicSingleArray2DI:E}=e("./kernel-value/dynamic-single-array2d-i"),{WebGL2KernelValueSingleArray3DI:w}=e("./kernel-value/single-array3d-i"),{WebGL2KernelValueDynamicSingleArray3DI:k}=e("./kernel-value/dynamic-single-array3d-i"),{WebGL2KernelValueArray2:I}=e("./kernel-value/array2"),{WebGL2KernelValueArray3:D}=e("./kernel-value/array3"),{WebGL2KernelValueArray4:C}=e("./kernel-value/array4"),{WebGL2KernelValueUnsignedArray:$}=e("./kernel-value/unsigned-array"),{WebGL2KernelValueDynamicUnsignedArray:L}=e("./kernel-value/dynamic-unsigned-array"),R={unsigned:{dynamic:{Boolean:n,Integer:s,Float:i,Array:L,"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:f,NumberTexture:b,"ArrayTexture(1)":b,"ArrayTexture(2)":b,"ArrayTexture(3)":b,"ArrayTexture(4)":b,MemoryOptimizedNumberTexture:x,HTMLCanvas:o,OffscreenCanvas:o,HTMLImage:o,ImageBitmap:o,ImageData:o,HTMLImageArray:l,HTMLVideo:c},static:{Boolean:n,Float:i,Integer:s,Array:$,"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:x,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:u,HTMLVideo:h}},single:{dynamic:{Boolean:n,Integer:s,Float:i,Array:v,"Array(2)":I,"Array(3)":D,"Array(4)":C,"Array1D(2)":A,"Array1D(3)":A,"Array1D(4)":A,"Array2D(2)":E,"Array2D(3)":E,"Array2D(4)":E,"Array3D(2)":k,"Array3D(3)":k,"Array3D(4)":k,Input:d,NumberTexture:b,"ArrayTexture(1)":b,"ArrayTexture(2)":b,"ArrayTexture(3)":b,"ArrayTexture(4)":b,MemoryOptimizedNumberTexture:x,HTMLCanvas:o,OffscreenCanvas:o,HTMLImage:o,ImageBitmap:o,ImageData:o,HTMLImageArray:l,HTMLVideo:c},static:{Boolean:n,Float:i,Integer:s,Array:T,"Array(2)":I,"Array(3)":D,"Array(4)":C,"Array1D(2)":S,"Array1D(3)":S,"Array1D(4)":S,"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:h}}};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 i=R[r][t];if(!1===i[e])return null;if(void 0===i[e])throw new Error(`Could not find a KernelValue for ${e}`);return i[e]}}},{"./kernel-value/array2":75,"./kernel-value/array3":76,"./kernel-value/array4":77,"./kernel-value/boolean":78,"./kernel-value/dynamic-html-image":80,"./kernel-value/dynamic-html-image-array":79,"./kernel-value/dynamic-html-video":81,"./kernel-value/dynamic-memory-optimized-number-texture":82,"./kernel-value/dynamic-number-texture":83,"./kernel-value/dynamic-single-array":84,"./kernel-value/dynamic-single-array1d-i":85,"./kernel-value/dynamic-single-array2d-i":86,"./kernel-value/dynamic-single-array3d-i":87,"./kernel-value/dynamic-single-input":88,"./kernel-value/dynamic-unsigned-array":89,"./kernel-value/dynamic-unsigned-input":90,"./kernel-value/float":91,"./kernel-value/html-image":93,"./kernel-value/html-image-array":92,"./kernel-value/html-video":94,"./kernel-value/integer":95,"./kernel-value/memory-optimized-number-texture":96,"./kernel-value/number-texture":97,"./kernel-value/single-array":98,"./kernel-value/single-array1d-i":99,"./kernel-value/single-array2d-i":100,"./kernel-value/single-array3d-i":101,"./kernel-value/single-input":102,"./kernel-value/unsigned-array":103,"./kernel-value/unsigned-input":104}],75:[function(e,t,r){const{WebGLKernelValueArray2:n}=e("../../web-gl/kernel-value/array2");t.exports={WebGL2KernelValueArray2:class extends n{}}},{"../../web-gl/kernel-value/array2":41}],76:[function(e,t,r){const{WebGLKernelValueArray3:n}=e("../../web-gl/kernel-value/array3");t.exports={WebGL2KernelValueArray3:class extends n{}}},{"../../web-gl/kernel-value/array3":42}],77:[function(e,t,r){const{WebGLKernelValueArray4:n}=e("../../web-gl/kernel-value/array4");t.exports={WebGL2KernelValueArray4:class extends n{}}},{"../../web-gl/kernel-value/array4":43}],78:[function(e,t,r){const{WebGLKernelValueBoolean:n}=e("../../web-gl/kernel-value/boolean");t.exports={WebGL2KernelValueBoolean:class extends n{}}},{"../../web-gl/kernel-value/boolean":44}],79:[function(e,t,r){const{utils:n}=e("../../../utils"),{WebGL2KernelValueHTMLImageArray:i}=e("./html-image-array");t.exports={WebGL2KernelValueDynamicHTMLImageArray:class extends i{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: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)}}}},{"../../../utils":114,"./html-image-array":92}],80:[function(e,t,r){const{utils:n}=e("../../../utils"),{WebGLKernelValueDynamicHTMLImage:i}=e("../../web-gl/kernel-value/dynamic-html-image");t.exports={WebGL2KernelValueDynamicHTMLImage:class extends i{getSource(){const e=this.getVariablePrecisionString();return n.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-html-image":45}],81:[function(e,t,r){const{utils:n}=e("../../../utils"),{WebGL2KernelValueDynamicHTMLImage:i}=e("./dynamic-html-image");t.exports={WebGL2KernelValueDynamicHTMLVideo:class extends i{}}},{"../../../utils":114,"./dynamic-html-image":80}],82:[function(e,t,r){const{utils:n}=e("../../../utils"),{WebGLKernelValueDynamicMemoryOptimizedNumberTexture:i}=e("../../web-gl/kernel-value/dynamic-memory-optimized-number-texture");t.exports={WebGL2KernelValueDynamicMemoryOptimizedNumberTexture:class extends i{getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-memory-optimized-number-texture":47}],83:[function(e,t,r){const{utils:n}=e("../../../utils"),{WebGLKernelValueDynamicNumberTexture:i}=e("../../web-gl/kernel-value/dynamic-number-texture");t.exports={WebGL2KernelValueDynamicNumberTexture:class extends i{getSource(){const e=this.getVariablePrecisionString();return n.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-number-texture":48}],84:[function(e,t,r){const{utils:n}=e("../../../utils"),{WebGL2KernelValueSingleArray:i}=e("../../web-gl2/kernel-value/single-array");t.exports={WebGL2KernelValueDynamicSingleArray:class extends i{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)}}}},{"../../../utils":114,"../../web-gl2/kernel-value/single-array":98}],85:[function(e,t,r){const{utils:n}=e("../../../utils"),{WebGL2KernelValueSingleArray1DI:i}=e("../../web-gl2/kernel-value/single-array1d-i");t.exports={WebGL2KernelValueDynamicSingleArray1DI:class extends i{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)}}}},{"../../../utils":114,"../../web-gl2/kernel-value/single-array1d-i":99}],86:[function(e,t,r){const{utils:n}=e("../../../utils"),{WebGL2KernelValueSingleArray2DI:i}=e("../../web-gl2/kernel-value/single-array2d-i");t.exports={WebGL2KernelValueDynamicSingleArray2DI:class extends i{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)}}}},{"../../../utils":114,"../../web-gl2/kernel-value/single-array2d-i":100}],87:[function(e,t,r){const{utils:n}=e("../../../utils"),{WebGL2KernelValueSingleArray3DI:i}=e("../../web-gl2/kernel-value/single-array3d-i");t.exports={WebGL2KernelValueDynamicSingleArray3DI:class extends i{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)}}}},{"../../../utils":114,"../../web-gl2/kernel-value/single-array3d-i":101}],88:[function(e,t,r){const{utils:n}=e("../../../utils"),{WebGL2KernelValueSingleInput:i}=e("../../web-gl2/kernel-value/single-input");t.exports={WebGL2KernelValueDynamicSingleInput:class extends i{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,i]=e.size;this.dimensions=new Int32Array([t||1,r||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),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":114,"../../web-gl2/kernel-value/single-input":102}],89:[function(e,t,r){const{utils:n}=e("../../../utils"),{WebGLKernelValueDynamicUnsignedArray:i}=e("../../web-gl/kernel-value/dynamic-unsigned-array");t.exports={WebGL2KernelValueDynamicUnsignedArray:class extends i{getSource(){const e=this.getVariablePrecisionString();return n.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-unsigned-array":54}],90:[function(e,t,r){const{utils:n}=e("../../../utils"),{WebGLKernelValueDynamicUnsignedInput:i}=e("../../web-gl/kernel-value/dynamic-unsigned-input");t.exports={WebGL2KernelValueDynamicUnsignedInput:class extends i{getSource(){const e=this.getVariablePrecisionString();return n.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-unsigned-input":55}],91:[function(e,t,r){const{utils:n}=e("../../../utils"),{WebGLKernelValueFloat:i}=e("../../web-gl/kernel-value/float");t.exports={WebGL2KernelValueFloat:class extends i{}}},{"../../../utils":114,"../../web-gl/kernel-value/float":56}],92:[function(e,t,r){const{utils:n}=e("../../../utils"),{WebGLKernelArray:i}=e("../../web-gl/kernel-value/array");t.exports={WebGL2KernelValueHTMLImageArray:class extends i{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 r=0;ri})}"undefined"!=typeof window&&s(window),"undefined"!=typeof self&&s(self),t.exports=n},{"./index":109}],108:[function(e,t,r){const{gpuMock:n}=e("gpu-mock.js"),{utils:i}=e("./utils"),{Kernel:s}=e("./backend/kernel"),{CPUKernel:a}=e("./backend/cpu/kernel"),{HeadlessGLKernel:o}=e("./backend/headless-gl/kernel"),{WebGL2Kernel:u}=e("./backend/web-gl2/kernel"),{WebGLKernel:l}=e("./backend/web-gl/kernel"),{kernelRunShortcut:h}=e("./kernel-run-shortcut"),c=[o,u,l],p=["gpu","cpu"],d={headlessgl:o,webgl2:u,webgl:l};let m=!0;function f(e){if(!e)return{};const t=Object.assign({},e);return e.hasOwnProperty("floatOutput")&&(i.warnDeprecated("setting","floatOutput","precision"),t.precision=e.floatOutput?"single":"unsigned"),e.hasOwnProperty("outputToTexture")&&(i.warnDeprecated("setting","outputToTexture","pipeline"),t.pipeline=Boolean(e.outputToTexture)),e.hasOwnProperty("outputImmutable")&&(i.warnDeprecated("setting","outputImmutable","immutable"),t.immutable=Boolean(e.outputImmutable)),e.hasOwnProperty("floatTextures")&&(i.warnDeprecated("setting","floatTextures","optimizeFloatMemory"),t.optimizeFloatMemory=Boolean(e.floatTextures)),t}t.exports={GPU:class{static disableValidation(){m=!1}static enableValidation(){m=!0}static get isGPUSupported(){return c.some((e=>e.isSupported))}static get isKernelMapSupported(){return c.some((e=>e.isSupported&&e.features.kernelMap))}static get isOffscreenCanvasSupported(){return"undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas||"undefined"!=typeof importScripts}static get isWebGLSupported(){return l.isSupported}static get isWebGL2Supported(){return u.isSupported}static get isHeadlessGLSupported(){return o.isSupported}static get isCanvasSupported(){return"undefined"!=typeof HTMLCanvasElement}static get isGPUHTMLImageArraySupported(){return u.isSupported}static get isSinglePrecisionSupported(){return c.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:m,onRequestFallback:u,onRequestSwitchKernel:function t(n,i,a){a.debug&&console.warn("Switching kernels");let o=null;if(a.signature&&!s[a.signature]&&(s[a.signature]=a),a.dynamicOutput)for(let e=n.length-1;e>=0;e--){const t=n[e];"outputPrecisionMismatch"===t.type&&(o=t.needed)}const l=a.constructor,h=l.getArgumentTypes(a,i),c=l.getSignature(a,h),d=s[c];if(d)return d.onActivate(a),d;const f=s[c]=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:o||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,debug:a.debug,gpu:a.gpu,validate:m,returnType:a.returnType,tactic:a.tactic,onRequestFallback:u,onRequestSwitchKernel:t,texture:a.texture,mappedTextures:a.mappedTextures,drawBuffersMap:a.drawBuffersMap});return f.build.apply(f,i),p.replaceKernel(f),r.push(f),f}},o),c=new this.Kernel(e,l),p=h(c);return this.canvas||(this.canvas=c.canvas),this.context||(this.context=c.context),r.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)&&this.mode&&p.indexOf(this.mode)<0)throw new Error(`kernelMap not supported on ${this.Kernel.name}`);const n=f(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{for(let e=0;et.kernel[i])),t.__defineSetter__(i,(e=>{t.kernel[i]=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(),i=e.onRequestSwitchKernel(n,arguments,e);r.kernel=e=i,t=i.run.apply(i,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){i(e=t,r)},i(e,r),r}}},{"./utils":114}],112:[function(e,t,r){const n={name:"math-random-uniformly-distributed",onBeforeRun:e=>{e.setUniform1f("randomSeed1",Math.random()),e.setUniform1f("randomSeed2",Math.random())},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}"};t.exports=n},{}],113:[function(e,t,r){t.exports={Texture:class{constructor(e){const{texture:t,size:r,dimensions:n,output:i,context:s,type:a="NumberTexture",kernel:o,internalFormat:u,textureFormat:l}=e;if(!i)throw new Error('settings property "output" required.');if(!s)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=i,this.context=s,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}`)}}}},{}],114:[function(e,t,r){const n=e("acorn"),{Input:i}=e("./input"),{Texture:s}=e("./texture"),a=/function ([^(]*)/,o=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,u=/([^\s,]+)/g,l={systemEndianness:()=>d,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=a.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(o,"");let r=t.slice(t.indexOf("(")+1,t.indexOf(")")).match(u);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]=l.clone(e[r]),delete e.isActiveClone);return t},isArray:e=>!isNaN(e.length),getVariableType(e,t){if(l.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 s:return e.type;case i: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,i]=t,s=(r||1)*(n||1)*(i||1);return e.optimizeFloatMemory&&"single"===e.precision&&(r=s=Math.ceil(s/4)),n>1&&r*n===s?new Int32Array([r,n]):l.closestSquareDimensions(s)},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(l.isArray(e)){const t=[];let n=e;for(;l.isArray(n);)t.push(n.length),n=n[0];r=t.reverse()}else if(e instanceof s)r=e.output;else{if(!(e instanceof i))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,i=4*t,s=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 i=0;i{const i=new Array(n);for(let s=0;se.subarray(0,t),erectMemoryOptimized2DFloat:(e,t,r)=>{const n=new Array(r);for(let i=0;i{const i=new Array(n);for(let s=0;s{const r=new Float32Array(t);let n=0;for(let i=0;i{const n=new Array(r);let i=0;for(let s=0;s{const i=new Array(n);let s=0;for(let a=0;a{const r=new Array(t),n=4*t;let i=0;for(let t=0;t{const n=new Array(r),i=4*t;for(let s=0;s{const i=4*t,s=new Array(n);for(let a=0;a{const r=new Array(t),n=4*t;let i=0;for(let t=0;t{const n=4*t,i=new Array(r);for(let s=0;s{const i=4*t,s=new Array(n);for(let a=0;a{const r=new Array(e),n=4*t;let i=0;for(let t=0;t{const n=4*t,i=new Array(r);for(let s=0;s{const i=4*t,s=new Array(n);for(let a=0;a{const{findDependency:r,thisLookup:i,doNotDefine:s}=t;let a=t.flattened;a||(a=t.flattened={});const o=n.parse(e),u=[];let h=0;const c=function e(t){if(Array.isArray(t)){const r=[];for(let n=0;nnull!==e));return n.length<1?"":`${t.kind} ${n.join(",")}`;case"VariableDeclarator":if(t.init.object&&"ThisExpression"===t.init.object.type){return i(t.init.property.name,!0)?`${t.id.name} = ${e(t.init)}`:null}return`${t.id.name} = ${e(t.init)}`;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?i(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":return`if (${e(t.test)}) ${e(t.consequent)}`;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"}}),i=e.createKernel((function(e){return 255*e[this.thread.y][this.thread.x].b}),{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),s=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),i(t),s(t)];return a.rKernel=r,a.gKernel=n,a.bKernel=i,a.aKernel=s,a.gpu=e,a},splitRGBAToCanvases:(e,t,r,n)=>{const i=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)"}});i(t);const s=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)"}});s(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),[i.canvas,s.canvas,a.canvas,o.canvas]},getMinifySafeName:e=>{try{const t=n.parse(`const value = ${e.toString()}`),{init:r}=t.body[0].declarations[0];return r.body.name||r.body.body[0].argument.name}catch(e){throw new Error("Unrecognized function type. Please use `() => yourFunctionVariableHere` or function() { return yourFunctionVariableHere; }")}},sanitizeName:function(e){return h.test(e)&&(e=e.replace(h,"S_S")),c.test(e)?e=e.replace(c,"U_U"):p.test(e)&&(e=e.replace(p,"u_u")),e}},h=/\$/,c=/__/,p=/_/,d=l.getSystemEndianness();t.exports={utils:l}},{"./input":110,"./texture":113,acorn:1}]},{},[107])(107)}));
\ No newline at end of file
diff --git a/dist/index-core.js b/dist/index-core.js
deleted file mode 100644
index 476e2810..00000000
--- a/dist/index-core.js
+++ /dev/null
@@ -1,12 +0,0 @@
-'use strict';
-
-var GPUCore = require("./core/gpu-core");
-if (typeof module !== 'undefined') {
- module.exports = GPUCore;
-}
-if (typeof window !== 'undefined') {
- window.GPUCore = GPUCore;
- if (window.GPU === null) {
- window.GPU = GPUCore;
- }
-}
\ No newline at end of file
diff --git a/dist/index.js b/dist/index.js
deleted file mode 100644
index 47558db8..00000000
--- a/dist/index.js
+++ /dev/null
@@ -1,42 +0,0 @@
-'use strict';
-
-var GPU = require('./core/gpu');
-var alias = require('./core/alias');
-var utils = require('./core/utils');
-var Input = require('./core/input');
-var Texture = require('./core/texture');
-
-var CPUFunctionBuilder = require('./backend/cpu/function-builder');
-var CPUFunctionNode = require('./backend/cpu/function-node');
-var CPUKernel = require('./backend/cpu/kernel');
-var CPURunner = require('./backend/cpu/runner');
-
-var WebGLFunctionBuilder = require('./backend/web-gl/function-builder');
-var WebGLFunctionNode = require('./backend/web-gl/function-node');
-var WebGLKernel = require('./backend/web-gl/kernel');
-var WebGLRunner = require('./backend/web-gl/runner');
-
-GPU.alias = alias;
-GPU.utils = utils;
-GPU.Texture = Texture;
-GPU.Input = Input;
-GPU.input = function (value, size) {
- return new Input(value, size);
-};
-
-GPU.CPUFunctionBuilder = CPUFunctionBuilder;
-GPU.CPUFunctionNode = CPUFunctionNode;
-GPU.CPUKernel = CPUKernel;
-GPU.CPURunner = CPURunner;
-
-GPU.WebGLFunctionBuilder = WebGLFunctionBuilder;
-GPU.WebGLFunctionNode = WebGLFunctionNode;
-GPU.WebGLKernel = WebGLKernel;
-GPU.WebGLRunner = WebGLRunner;
-
-if (typeof module !== 'undefined') {
- module.exports = GPU;
-}
-if (typeof window !== 'undefined') {
- window.GPU = GPU;
-}
\ No newline at end of file
diff --git a/dist/notes/js-native-class.js b/dist/notes/js-native-class.js
deleted file mode 100644
index 7c25dc65..00000000
--- a/dist/notes/js-native-class.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * File: js-native-classes
- *
- * This file represents documentation of native JS classes, for reference linking by other files in documentations.
- * In general you can ignore this file.
- *
- */
-
-/**
- * @class Object
- * Native javascript object, while this can mean anything in JS. You probably should not be using a string/numeric/array type here.
- *
- * See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
- *
- */
-
-/**
- * @class String
- * Native javascript String.
- *
- * See: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String
- *
- */
-
-/**
- * @class Boolean
- * Native javascript Boolean, basically TRUE or FALSE.
- *
- * See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean
- *
- */
-
-/**
- * @class Function
- * Native javascript Function object, that is executable, hopefully without exceptions.
- *
- * See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function
- *
- */
-
-/**
- * @class Number
- * Native javascript Number object.
- *
- * See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number
- *
- */
-
-/**
- * @class Int
- * Native javascript Number. But this time you probably shold limit it to a whole number.
- *
- * See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number
- *
- */
-"use strict";
\ No newline at end of file
diff --git a/dist/notes/kernel-obj-format.js b/dist/notes/kernel-obj-format.js
deleted file mode 100644
index f90830f1..00000000
--- a/dist/notes/kernel-obj-format.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * File: kernel-obj-format
- *
- * @class KernelObjFormat
- *
- * The kernelObj is a standard JS object that matches the following format.
- *
- * This is generated via
- *
- * |-----------------|---------------|---------------------------------------------------------------------------|
- * | Name | Value Type | Description |
- * |-----------------|---------------|---------------------------------------------------------------------------|
- * | isKernelObj | | Boolean true flag, that is compulsory in the kernel obj validation |
- * | optObj | | { option object } |
- * | jsPrecompile | | Object representing the precompiled kernel for CPU mode |
- * | webGlPrecompile | | Object representing the precompiled kernel for W mode |
- * | jsKernel | | String representation of the JS kernel |
- * | glHeaders | | Precompiled webgl prototype function headers |
- * | glKernel | | Precompiled webgl kernel functions |
- * | paramNames | | Array of strings, containing the kernel parameter names |
- * | paramType | | Array of strings, containing the kernel parameter types, can only be |
- * | | | either "Array", "Int", "Float" |
- * |-----------------|---------------|---------------------------------------------------------------------------|
- */
-"use strict";
\ No newline at end of file
diff --git a/dist/wrapper/header.js b/dist/wrapper/header.js
deleted file mode 100644
index eb94a26f..00000000
--- a/dist/wrapper/header.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * <%= pkg.name %>
- * <%= pkg.homepage %>
- *
- * <%= pkg.description %>
- *
- * @version <%= pkg.version %>
- * @date <%= new Date() %>
- *
- * @license <%= pkg.license %>
- * The MIT License
- *
- * Copyright (c) <%= new Date().getFullYear() %> gpu.js Team
- */
-"use strict";
\ No newline at end of file
diff --git a/examples/advanced-typescript.ts b/examples/advanced-typescript.ts
new file mode 100644
index 00000000..fa837224
--- /dev/null
+++ b/examples/advanced-typescript.ts
@@ -0,0 +1,66 @@
+/**
+ * This is an arbitrary example (overly complex with types for overly simplified kernel) to show type inheritance
+ * throughout the kernel's usage.
+ *
+ * The whole idea here is that you can define custom:
+ * - `constants`
+ * - `this` context
+ * - mapped kernels
+ * - arguments
+ * - kernel output
+ */
+
+import {
+ GPU,
+ Texture,
+ IKernelFunctionThis,
+ IConstantsThis,
+ KernelOutput,
+ ISubKernelsResults
+} from '../src';
+
+const gpu = new GPU();
+
+interface IConstants extends IConstantsThis {
+ rotation: number,
+}
+
+interface IThis extends IKernelFunctionThis {
+ constants: IConstants,
+}
+
+function kernelFunction(this: IThis, degrees: number, divisors: [number, number]): [number, number] {
+ const bounds = subKernel(this.constants.rotation * degrees);
+ return [bounds[0] / divisors[0], bounds[1] / divisors[1]];
+}
+
+function subKernel(value: number): [number, number] {
+ return [-value, value];
+}
+
+interface IKernelMapResult extends ISubKernelsResults {
+ test: KernelOutput;
+}
+
+const kernelMap = gpu.createKernelMap>({
+ test: subKernel,
+}, kernelFunction)
+ .setConstants({
+ rotation: 45,
+ })
+ .setOutput([1])
+ .setPrecision('single')
+ .setPipeline(true)
+ .setImmutable(true);
+
+const { test, result } = kernelMap(360, [256, 512]);
+const testTexture = test as Texture;
+const resultTexture = result as Texture;
+
+console.log(testTexture.toArray() as [number, number][]);
+console.log(resultTexture.toArray() as [number, number][]);
+
+testTexture.delete();
+resultTexture.delete();
+
+kernelMap.destroy();
diff --git a/examples/cat-image/cat.jpg b/examples/cat-image/cat.jpg
new file mode 100644
index 00000000..cc2fbd3e
Binary files /dev/null and b/examples/cat-image/cat.jpg differ
diff --git a/examples/cat-image/index.html b/examples/cat-image/index.html
new file mode 100644
index 00000000..0c6842ce
--- /dev/null
+++ b/examples/cat-image/index.html
@@ -0,0 +1,69 @@
+
+
+
+
+ Cat image with GPU.js
+
+
+
+
+
+
+
+
diff --git a/examples/fluid.html b/examples/fluid.html
new file mode 100644
index 00000000..2b3fd1ba
--- /dev/null
+++ b/examples/fluid.html
@@ -0,0 +1,1142 @@
+
+
+
+
+ SSPS - Chadams Studios (slightly upgraded)
+
+
+
+
+
+
+
diff --git a/examples/internal-variable-precision.html b/examples/internal-variable-precision.html
new file mode 100644
index 00000000..0cf6ee42
--- /dev/null
+++ b/examples/internal-variable-precision.html
@@ -0,0 +1,52 @@
+
+
+
+
+ GPU.js Internal Variable Precision
+
+
+GPU.js Internal variable precision:
+
+
+
+
diff --git a/examples/json-saving.js b/examples/json-saving.js
new file mode 100644
index 00000000..d9286ab5
--- /dev/null
+++ b/examples/json-saving.js
@@ -0,0 +1,17 @@
+const { GPU } = require('../src');
+const gpu1 = new GPU();
+
+const kernel1 = gpu1.createKernel(function(value) {
+ return value * 100;
+}, { output: [1] });
+
+const resultFromRegularKernel = kernel1(42);
+const json = kernel1.toJSON();
+console.log(resultFromRegularKernel);
+
+// Use bin/gpu-browser-core.js to get "CORE" mode, which works only with JSON
+const gpu2 = new GPU();
+const kernel2 = gpu2.createKernel(json);
+const resultFromJsonKernel = kernel2(42);
+console.log(resultFromJsonKernel);
+
diff --git a/examples/mandelbrot-set.html b/examples/mandelbrot-set.html
new file mode 100644
index 00000000..ca484e1a
--- /dev/null
+++ b/examples/mandelbrot-set.html
@@ -0,0 +1,123 @@
+
+
+
+
+
+ Left click to zoom in, right click to zoom out.
+
+
+
diff --git a/examples/mandelbulb.html b/examples/mandelbulb.html
new file mode 100644
index 00000000..5b93c642
--- /dev/null
+++ b/examples/mandelbulb.html
@@ -0,0 +1,587 @@
+
+
+
+
+
+
+ Frakal
+
+
+
+
+
+
+
Mandelbulb - Real-time 3d fractal in Javascript
+
Kamil Kiełczewski Airavana
+
+
Instruction
+
Click on picture and move mouse around
+ A S D W E C keys for change view poin position
+ Push ESC to stop move and unlock mouse
+
+
+
+
+
+ Level of Details (and camera speed)
+ Mouse whell or +/- keys
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/parallel-raytracer.html b/examples/parallel-raytracer.html
new file mode 100644
index 00000000..59c0fbce
--- /dev/null
+++ b/examples/parallel-raytracer.html
@@ -0,0 +1,1210 @@
+
+
+
+
+
+ GPU.js Raytracer
+
+
+
+
+
+
+
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.
+
+
+
Current mode
+
GPU
+
+
+
+
FPS Loading..
+
+
+
+
Number of spheres
+
4
+
+
+
+
Grid dimension
+
2
+
+
+
+
+
+ The canvas is 640px by 640px. Each canvas object is controlled by a single GPU.js kernel and a single thread is spawned for each pixel to compute the color of the pixel.
+
+
+
+ Increase the dimensions of the grid to break the canvas up into tiles, so that there are multiple kernels controlling multiple tiles. With this approach, the kernels will run sequentially, computing one canvas after another.
+
+
+
+
+
Benchmark
+
+
+
+ Benchmark the performance of the parallelized GPU and sequential CPU kernels.
+ This will render 30 frames each and compute min, max, median frame rendering durations, and speedups.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/random.html b/examples/random.html
new file mode 100644
index 00000000..0ef1b50c
--- /dev/null
+++ b/examples/random.html
@@ -0,0 +1,66 @@
+
+
+
+
+ GPU.js Random Examples
+
+
+ CPU Random
+
+ WebGL1 Random
+
+ WebGL2 Random
+
+
+
+
+
diff --git a/examples/raster-globe/earth-map.jpg b/examples/raster-globe/earth-map.jpg
new file mode 100644
index 00000000..f8f1a358
Binary files /dev/null and b/examples/raster-globe/earth-map.jpg differ
diff --git a/examples/raster-globe/index.html b/examples/raster-globe/index.html
new file mode 100644
index 00000000..def70c16
--- /dev/null
+++ b/examples/raster-globe/index.html
@@ -0,0 +1,135 @@
+
+
+
+
+ Raster projection with GPU.js
+
+
+
+
+
+
+
+
diff --git a/examples/raytracer.html b/examples/raytracer.html
new file mode 100644
index 00000000..274d598a
--- /dev/null
+++ b/examples/raytracer.html
@@ -0,0 +1,520 @@
+
+
+
+
+
+
+ GPU.js Raytracer
+
+
+
+
+
+
+
+
+
+ From https://staceytay.com/raytracer/. A simple ray tracer with Lambertian and specular reflection,
+ built with GPU.js . Read more
+ about ray tracing and GPU.js in
+ my blog
+ post . Code available
+ on GitHub .
+
+
+
+ CPU
+ GPU
+
+
+ Lambertian reflectance
+ Specular reflection
+
+
+
+
+
+ fps
+
+
+
+
+
+
+
diff --git a/examples/simple-javascript.js b/examples/simple-javascript.js
new file mode 100644
index 00000000..24123d25
--- /dev/null
+++ b/examples/simple-javascript.js
@@ -0,0 +1,17 @@
+const { GPU } = require('../src');
+
+const gpu = new GPU({ mode: 'gpu' });
+
+// Look ma! I can javascript on my GPU!
+function kernelFunction(anInt, anArray, aNestedArray) {
+ const x = .25 + anInt + anArray[this.thread.x] + aNestedArray[this.thread.x][this.thread.y];
+ return x;
+}
+
+const kernel = gpu.createKernel(kernelFunction, {
+ output: [1]
+});
+
+const result = kernel(1, [.25], [[1.5]]);
+
+console.log(result[0]); // 3
diff --git a/examples/simple-typescript.ts b/examples/simple-typescript.ts
new file mode 100644
index 00000000..a8ca3110
--- /dev/null
+++ b/examples/simple-typescript.ts
@@ -0,0 +1,16 @@
+import { GPU, KernelFunction, IKernelRunShortcut } from '../src';
+
+const gpu = new GPU({ mode: 'gpu' });
+
+// Look ma! I can typescript on my GPU!
+const kernelFunction: KernelFunction = function(anInt: number, anArray: number[], aNestedArray: number[][]) {
+ const x = .25 + anInt + anArray[this.thread.x] + aNestedArray[this.thread.x][this.thread.y];
+ return x;
+};
+
+const kernel: IKernelRunShortcut = gpu.createKernel(kernelFunction)
+ .setOutput([1]);
+
+const result = kernel(1, [.25], [[1.5]]);
+
+console.log(result[0]); // 3
diff --git a/examples/slow-fade.html b/examples/slow-fade.html
new file mode 100644
index 00000000..4c2ea171
--- /dev/null
+++ b/examples/slow-fade.html
@@ -0,0 +1,46 @@
+
+
+
+
+ Slow Fade
+
+
+ Slow Fade
+
+
+
+
+
+
+
diff --git a/examples/video/index.html b/examples/video/index.html
new file mode 100644
index 00000000..07b441d3
--- /dev/null
+++ b/examples/video/index.html
@@ -0,0 +1,101 @@
+
+
+
+
+ Video input with GPU.js
+
+
+
+Video input (and output) with GPU.js
+
+
+ Flip XY
+ Alter colors
+ GPU enabled
+ Pause GPU
+
+
+
+
+
Video
+
+
+
+
GPU.js Graphical Output 0 fps
+
+
+
+
+
+
diff --git a/folder-structure.md b/folder-structure.md
deleted file mode 100644
index c76c68ee..00000000
--- a/folder-structure.md
+++ /dev/null
@@ -1,7 +0,0 @@
-
-+ bin : Browser compiled JS files, and its minified version?
-+ dist : Node es5 distribution
-+ src : Node es6 source javascript
-+ test
- + html : QUnit html pages
- + src : Unit test source code
diff --git a/gulpfile.js b/gulpfile.js
index 17e2a172..b716c0e6 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -1,135 +1,121 @@
-'use strict';
-
const fs = require('fs');
const gulp = require('gulp');
-const concat = require('gulp-concat');
const rename = require('gulp-rename');
-const uglify = require('gulp-uglify');
-const gutil = require('gulp-util');
const header = require('gulp-header');
const browserSync = require('browser-sync');
const browserify = require('browserify');
+const replace = require('gulp-replace');
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');
+const path = require('path');
+const uglify = require('gulp-uglify-es').default;
const pkg = require('./package.json');
const jsprettify = require('gulp-jsbeautifier');
-const babel = require('gulp-babel');
const stripComments = require('gulp-strip-comments');
-const del = require('del');
-const merge = require('merge-stream');
-
-/// Build the scripts
-gulp.task('babelify', function () {
- return gulp.src(['./src/**'])
- .pipe(babel())
- .pipe(gulp.dest('dist'));
-});
-
-gulp.task('build', ['babelify'], function() {
-
- const gpu = browserify('./dist/index.js')
- .bundle()
- .pipe(source('gpu.js'))
- .pipe(buffer())
- .pipe(stripComments())
- .pipe(header(fs.readFileSync('./dist/wrapper/header.js', 'utf8'), { pkg : pkg }))
- .pipe(gulp.dest('bin'));
-
- const gpuCore = browserify('./dist/index-core.js')
- .bundle()
- .pipe(source('gpu-core.js'))
- .pipe(buffer())
- .pipe(stripComments())
- .pipe(header(fs.readFileSync('./dist/wrapper/header.js', 'utf8'), { pkg : pkg }))
- .pipe(gulp.dest('bin'));
-
- return merge(gpu, gpuCore);
+const merge = require('ordered-read-streams');
+const { readDirDeepSync } = require('read-dir-deep');
+
+gulp.task('build', () => {
+ const gpu = browserify('./src/browser.js', { standalone: 'GPU', browserField: false })
+ .ignore('gl')
+ .bundle()
+ .pipe(source('gpu-browser.js'))
+ .pipe(buffer())
+ .pipe(stripComments())
+ .pipe(header(fs.readFileSync('./src/browser-header.txt', 'utf8'), { pkg : pkg }))
+ .pipe(gulp.dest('./dist'))
+ .on('error', console.error);
+
+ const gpuCore = browserify('./src/browser.js', { standalone: 'GPU', browserField: false })
+ .ignore('gl')
+ .ignore('acorn')
+ .bundle()
+ .pipe(source('gpu-browser-core.js'))
+ .pipe(buffer())
+ .pipe(stripComments())
+ .pipe(header(fs.readFileSync('./src/browser-header.txt', 'utf8'), { pkg : pkg }))
+ .pipe(gulp.dest('./dist'))
+ .on('error', console.error);
+
+ return merge(gpu, gpuCore);
});
/// Minify the build script, after building it
-gulp.task('minify', function() {
- const gpu = gulp.src('bin/gpu.js')
- .pipe(rename('gpu.min.js'))
- .pipe(
- uglify({preserveComments: 'license'})
- .on('error', gutil.log)
- )
- .pipe(gulp.dest('bin'));
-
- const gpuCore = gulp.src('bin/gpu-core.js')
- .pipe(rename('gpu-core.min.js'))
- .pipe(
- uglify({preserveComments: 'license'})
- .on('error', gutil.log)
- )
- .pipe(gulp.dest('bin'));
-
- return merge(gpu, gpuCore);
+gulp.task('minify', () => {
+ const gpu = gulp.src('dist/gpu-browser.js')
+ .pipe(uglify())
+ .pipe(rename('gpu-browser.min.js'))
+ .pipe(header(fs.readFileSync('./src/browser-header.txt', 'utf8'), { pkg : pkg }))
+ .pipe(gulp.dest('./dist'))
+ .on('error', console.error);
+
+ const gpuCore = gulp.src('dist/gpu-browser-core.js')
+ .pipe(uglify())
+ .pipe(rename('gpu-browser-core.min.js'))
+ .pipe(header(fs.readFileSync('./src/browser-header.txt', 'utf8'), { pkg : pkg }))
+ .pipe(gulp.dest('./dist'))
+ .on('error', console.error);
+
+ return merge(gpu, gpuCore);
});
-
/// The browser sync prototyping
-gulp.task('bsync', function(){
- // Syncs browser
- browserSync.init({
- server: {
- baseDir: './'
- },
- open: true,
- startPath: "/test/html/test-all.html",
- // Makes it easier to test on external mobile devices
- host: "0.0.0.0",
- tunnel: true
- });
-
- // Detect change -> rebuild TS
- gulp.watch(['src/**.js'], ['minify']);
+gulp.task('bsync', () => {
+ // Syncs browser
+ browserSync.init({
+ server: {
+ baseDir: './'
+ },
+ open: true,
+ startPath: "./test/html/test-all.html",
+ // Makes it easier to test on external mobile devices
+ host: "0.0.0.0",
+ tunnel: true
+ });
+
+ // Detect change -> rebuild TS
+ gulp.watch(['src/**.js'], gulp.series('minify'));
});
/// Auto rebuild and host
-gulp.task('default', ['minify','bsync']);
-
+gulp.task('default', gulp.series('minify','bsync'));
/// Beautify source code
/// Use before merge request
-gulp.task('beautify', function() {
- gulp.src(['src/**/*.js'])
- .pipe(jsprettify({
- indent_size: 3,
- indent_char: ' ',
- indent_with_tabs: true
- }))
- .pipe(gulp.dest('src'));
+gulp.task('beautify', () => {
+ return gulp.src(['src/**/*.js'])
+ .pipe(jsprettify({
+ indent_size: 2,
+ indent_char: ' ',
+ indent_with_tabs: false,
+ eol: '\n',
+ brace_style: 'preserve-inline'
+ }))
+ .pipe(gulp.dest('src'));
});
-gulp.task('injectCSS', function(){
- let signatureColor = '#ff75cf';
- let linkColor = '#4c7fbd';
- let themeColor = '#186384';
-
- // !important is used because the original rule is using it.
- let cssRules = `
- .signature, a {
- color: ${signatureColor};
- }
-
- h4.name {
- background: ${themeColor};
- }
+gulp.task('build-tests', () => {
+ const folder = 'test';
+ const testFile = 'all.html';
+ try {
+ fs.unlinkSync(`${folder}/${testFile}`);
+ } catch (e) {}
+ const rootPath = path.resolve(process.cwd(), folder);
+ const warning = '\n';
+ const files = readDirDeepSync(rootPath, {
+ patterns: [
+ '**/*.js'
+ ],
+ ignore: [
+ '*.js'
+ ]
+ })
+ .map(file => file.replace(/^test\//, ''));
+ return gulp.src(`${folder}/all-template.html`)
+ .pipe(replace('{{test-files}}', warning + files.map(file => ``).join('\n')))
+ .pipe(rename(testFile))
+ .pipe(gulp.dest(folder));
+});
- nav > ul > li > a, nav a:hover, nav > h2 > a {
- color: ${linkColor} !important;
- }
+gulp.task('make', gulp.series('build', 'beautify', 'minify', 'build-tests'));
- span.param-type, .params td .param-type {
- color: ${themeColor};
- }
- `;
- fs.appendFile('./doc/styles/jsdoc.css', cssRules, (err)=>{
- if(err){
- throw new Error(err);
- }
-
- console.log('CSS Injected');
- });
-});
\ No newline at end of file
diff --git a/jsdoc.json b/jsdoc.json
deleted file mode 100644
index 7f24bd7a..00000000
--- a/jsdoc.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "source": {
- "excludePattern": "(parser.js$)"
- },
- "opts": {
- "template": "node_modules/docdash"
- },
- "plugins": [
- "plugins/markdown"
- ]
-}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 00000000..f272c25e
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,8472 @@
+{
+ "name": "gpu.js",
+ "version": "2.16.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "gpu.js",
+ "version": "2.16.0",
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "8.14.0",
+ "gl": "8.1.6",
+ "gl-wiretap": "0.6.2",
+ "gpu-mock.js": "github:weagle08/gpu-mock.js",
+ "ordered-read-streams": "^2.0.0",
+ "webgpu": "0.2.9"
+ },
+ "devDependencies": {
+ "benchmark": "2.1.4",
+ "browser-sync": "3.0.2",
+ "browserify": "17.0.0",
+ "c8": "10.1.2",
+ "gulp": "5.0.0",
+ "gulp-concat": "2.6.1",
+ "gulp-header": "2.0.9",
+ "gulp-jsbeautifier": "3.0.1",
+ "gulp-rename": "2.0.0",
+ "gulp-replace": "1.1.4",
+ "gulp-strip-comments": "2.6.0",
+ "gulp-uglify-es": "3.0.0",
+ "merge-stream": "2.0.0",
+ "qunit": "2.22.0",
+ "read-dir-deep": "8.0.0",
+ "sinon": "18.0.0",
+ "vinyl-buffer": "1.0.1",
+ "vinyl-source-stream": "2.0.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/@bcoe/v8-coverage": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@gulpjs/messages": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@gulpjs/messages/-/messages-1.1.0.tgz",
+ "integrity": "sha512-Ys9sazDatyTgZVb4xPlDufLweJ/Os2uHWOv+Caxvy2O85JcnT4M3vc73bi8pdLWlv3fdWQz3pdI9tVwo8rQQSg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/@gulpjs/to-absolute-glob": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@gulpjs/to-absolute-glob/-/to-absolute-glob-4.0.0.tgz",
+ "integrity": "sha512-kjotm7XJrJ6v+7knhPaRgaT6q8F8K2jiafwYdNHLzmV0uGLuZY43FK6smNSHUPrhq5kX2slCUy+RGG/xGqmIKA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-negated-glob": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
+ "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "license": "MIT"
+ },
+ "node_modules/@isaacs/cliui/node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
+ "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/set-array": "^1.2.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
+ "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.25",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@npmcli/agent": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz",
+ "integrity": "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==",
+ "license": "ISC",
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "http-proxy-agent": "^7.0.0",
+ "https-proxy-agent": "^7.0.1",
+ "lru-cache": "^10.0.1",
+ "socks-proxy-agent": "^8.0.3"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/fs": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz",
+ "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==",
+ "license": "ISC",
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@one-ini/wasm": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz",
+ "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@sinonjs/commons": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
+ "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "node_modules/@sinonjs/fake-timers": {
+ "version": "11.3.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.3.1.tgz",
+ "integrity": "sha512-EVJO7nW5M/F5Tur0Rf2z/QoMo+1Ia963RiMtapiQrEWvY0iBUvADo8Beegwjpnle5BHkyHuoxSTW3jF43H1XRA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.1"
+ }
+ },
+ "node_modules/@sinonjs/samsam": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.2.tgz",
+ "integrity": "sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.1",
+ "lodash.get": "^4.4.2",
+ "type-detect": "^4.1.0"
+ }
+ },
+ "node_modules/@sinonjs/samsam/node_modules/type-detect": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz",
+ "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@sinonjs/text-encoding": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz",
+ "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==",
+ "dev": true,
+ "license": "(Unlicense OR Apache-2.0)"
+ },
+ "node_modules/@socket.io/component-emitter": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
+ "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/cors": {
+ "version": "2.8.17",
+ "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz",
+ "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/expect": {
+ "version": "1.20.4",
+ "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz",
+ "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/istanbul-lib-coverage": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
+ "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "22.13.2",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.2.tgz",
+ "integrity": "sha512-Z+r8y3XL9ZpI2EY52YYygAFmo2/oWfNSj4BCpAXE2McAexDk8VcnBMGC9Djn9gTKt4d2T/hhXqmPzo4hfIXtTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.20.0"
+ }
+ },
+ "node_modules/@types/vinyl": {
+ "version": "2.0.12",
+ "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.12.tgz",
+ "integrity": "sha512-Sr2fYMBUVGYq8kj3UthXFAu5UN6ZW+rYr4NACjZQJvHvj+c8lYv0CahmZ2P/r7iUkN44gGUBwqxZkrKXYPb7cw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/expect": "^1.20.4",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@webgpu/types": {
+ "version": "0.1.54",
+ "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.54.tgz",
+ "integrity": "sha512-81oaalC8LFrXjhsczomEQ0u3jG+TqE6V9QHLA8GNZq/Rnot0KDugu3LhSYSlie8tSdooAN1Hov05asrUUp9qgg==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/abbrev": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.0.tgz",
+ "integrity": "sha512-+/kfrslGQ7TNV2ecmQwMJj/B65g5KVq1/L3SGVZ3tCYGqlzFuFCGBZJtMP99wH3NpEUyAjn0zPdPUg0D+DwrOA==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/accepts": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/accepts/node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.14.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
+ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-node": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz",
+ "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "acorn": "^7.0.0",
+ "acorn-walk": "^7.0.0",
+ "xtend": "^4.0.2"
+ }
+ },
+ "node_modules/acorn-node/node_modules/acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-walk": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
+ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
+ "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/aggregate-error": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+ "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
+ "license": "MIT",
+ "dependencies": {
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-colors": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
+ "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ansi-gray": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz",
+ "integrity": "sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-wrap": "0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/ansi-wrap": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
+ "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-each": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
+ "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-slice": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
+ "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/asn1.js": {
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
+ "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bn.js": "^4.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "node_modules/asn1.js/node_modules/bn.js": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
+ "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/assert": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.1.tgz",
+ "integrity": "sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "object.assign": "^4.1.4",
+ "util": "^0.10.4"
+ }
+ },
+ "node_modules/assert/node_modules/inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/assert/node_modules/util": {
+ "version": "0.10.4",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
+ "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "2.0.3"
+ }
+ },
+ "node_modules/assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/async": {
+ "version": "2.6.4",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
+ "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash": "^4.17.14"
+ }
+ },
+ "node_modules/async-done": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/async-done/-/async-done-2.0.0.tgz",
+ "integrity": "sha512-j0s3bzYq9yKIVLKGE/tWlCpa3PfFLcrDZLTSVdnnCTGagXuXBJO4SsY9Xdk/fQBirCkH4evW5xOeJXqlAQFdsw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "end-of-stream": "^1.4.4",
+ "once": "^1.4.0",
+ "stream-exhaust": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/async-each-series": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-0.1.1.tgz",
+ "integrity": "sha512-p4jj6Fws4Iy2m0iCmI2am2ZNZCgbdgE+P8F/8csmn2vx7ixXrO2zGcuNsD46X5uZSVecmkEy/M06X2vG8KD6dQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/async-settle": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-2.0.0.tgz",
+ "integrity": "sha512-Obu/KE8FurfQRN6ODdHN9LuXqwC+JFIM9NRyZqJJ4ZfLJmIYN9Rg0/kb+wF70VV5+fJusTMQlJ1t5rF7J/ETdg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async-done": "^2.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/b4a": {
+ "version": "1.6.7",
+ "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz",
+ "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/bach": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/bach/-/bach-2.0.1.tgz",
+ "integrity": "sha512-A7bvGMGiTOxGMpNupYl9HQTf0FFDNF4VCmks4PJpFyN1AX2pdKuxuwdvUz2Hu388wcgp+OvGFNsumBfFNkR7eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async-done": "^2.0.0",
+ "async-settle": "^2.0.0",
+ "now-and-later": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "license": "MIT"
+ },
+ "node_modules/bare-events": {
+ "version": "2.5.4",
+ "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz",
+ "integrity": "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==",
+ "license": "Apache-2.0",
+ "optional": true
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/base64id": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
+ "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^4.5.0 || >= 5.9"
+ }
+ },
+ "node_modules/batch": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
+ "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/benchmark": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz",
+ "integrity": "sha512-l9MlfN4M1K/H2fbhfMy3B7vJd6AGKJVQn2h6Sg/Yx+KckoUA7ewS5Vv6TjSq18ooE1kS9hhAlQRH3AkXIh/aOQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash": "^4.17.4",
+ "platform": "^1.3.3"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/binaryextensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-2.3.0.tgz",
+ "integrity": "sha512-nAihlQsYGyc5Bwq6+EsubvANYGExeJKHDO3RjnvwU042fawQTQfM3Kxn7IHUXQOz4bzfwsGYYHGSvXyW4zOGLg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ },
+ "funding": {
+ "url": "https://bevry.me/fund"
+ }
+ },
+ "node_modules/bindings": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+ "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+ "license": "MIT",
+ "dependencies": {
+ "file-uri-to-path": "1.0.0"
+ }
+ },
+ "node_modules/bit-twiddle": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bit-twiddle/-/bit-twiddle-1.0.2.tgz",
+ "integrity": "sha512-B9UhK0DKFZhoTFcfvAzhqsjStvGJp9vYWf3+6SNTtdSQnvIgfkHbgHrg/e4+TH71N2GDu8tpmCVoyfrL1d7ntA==",
+ "license": "MIT"
+ },
+ "node_modules/bl": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
+ "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+ "license": "MIT",
+ "dependencies": {
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "node_modules/bl/node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "node_modules/bl/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/bn.js": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
+ "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/brorand": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+ "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/browser-pack": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz",
+ "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "combine-source-map": "~0.8.0",
+ "defined": "^1.0.0",
+ "JSONStream": "^1.0.3",
+ "safe-buffer": "^5.1.1",
+ "through2": "^2.0.0",
+ "umd": "^3.0.0"
+ },
+ "bin": {
+ "browser-pack": "bin/cmd.js"
+ }
+ },
+ "node_modules/browser-resolve": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz",
+ "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve": "^1.17.0"
+ }
+ },
+ "node_modules/browser-sync": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-3.0.2.tgz",
+ "integrity": "sha512-PC9c7aWJFVR4IFySrJxOqLwB9ENn3/TaXCXtAa0SzLwocLN3qMjN+IatbjvtCX92BjNXsY6YWg9Eb7F3Wy255g==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "browser-sync-client": "^3.0.2",
+ "browser-sync-ui": "^3.0.2",
+ "bs-recipes": "1.3.4",
+ "chalk": "4.1.2",
+ "chokidar": "^3.5.1",
+ "connect": "3.6.6",
+ "connect-history-api-fallback": "^1",
+ "dev-ip": "^1.0.1",
+ "easy-extender": "^2.3.4",
+ "eazy-logger": "^4.0.1",
+ "etag": "^1.8.1",
+ "fresh": "^0.5.2",
+ "fs-extra": "3.0.1",
+ "http-proxy": "^1.18.1",
+ "immutable": "^3",
+ "micromatch": "^4.0.2",
+ "opn": "5.3.0",
+ "portscanner": "2.2.0",
+ "raw-body": "^2.3.2",
+ "resp-modifier": "6.0.2",
+ "rx": "4.1.0",
+ "send": "0.16.2",
+ "serve-index": "1.9.1",
+ "serve-static": "1.13.2",
+ "server-destroy": "1.0.1",
+ "socket.io": "^4.4.1",
+ "ua-parser-js": "^1.0.33",
+ "yargs": "^17.3.1"
+ },
+ "bin": {
+ "browser-sync": "dist/bin.js"
+ },
+ "engines": {
+ "node": ">= 8.0.0"
+ }
+ },
+ "node_modules/browser-sync-client": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/browser-sync-client/-/browser-sync-client-3.0.3.tgz",
+ "integrity": "sha512-TOEXaMgYNjBYIcmX5zDlOdjEqCeCN/d7opf/fuyUD/hhGVCfP54iQIDhENCi012AqzYZm3BvuFl57vbwSTwkSQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "etag": "1.8.1",
+ "fresh": "0.5.2",
+ "mitt": "^1.1.3"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/browser-sync-ui": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-3.0.3.tgz",
+ "integrity": "sha512-FcGWo5lP5VodPY6O/f4pXQy5FFh4JK0f2/fTBsp0Lx1NtyBWs/IfPPJbW8m1ujTW/2r07oUXKTF2LYZlCZktjw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "async-each-series": "0.1.1",
+ "chalk": "4.1.2",
+ "connect-history-api-fallback": "^1",
+ "immutable": "^3",
+ "server-destroy": "1.0.1",
+ "socket.io-client": "^4.4.1",
+ "stream-throttle": "^0.1.3"
+ }
+ },
+ "node_modules/browserify": {
+ "version": "17.0.0",
+ "resolved": "https://registry.npmjs.org/browserify/-/browserify-17.0.0.tgz",
+ "integrity": "sha512-SaHqzhku9v/j6XsQMRxPyBrSP3gnwmE27gLJYZgMT2GeK3J0+0toN+MnuNYDfHwVGQfLiMZ7KSNSIXHemy905w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assert": "^1.4.0",
+ "browser-pack": "^6.0.1",
+ "browser-resolve": "^2.0.0",
+ "browserify-zlib": "~0.2.0",
+ "buffer": "~5.2.1",
+ "cached-path-relative": "^1.0.0",
+ "concat-stream": "^1.6.0",
+ "console-browserify": "^1.1.0",
+ "constants-browserify": "~1.0.0",
+ "crypto-browserify": "^3.0.0",
+ "defined": "^1.0.0",
+ "deps-sort": "^2.0.1",
+ "domain-browser": "^1.2.0",
+ "duplexer2": "~0.1.2",
+ "events": "^3.0.0",
+ "glob": "^7.1.0",
+ "has": "^1.0.0",
+ "htmlescape": "^1.1.0",
+ "https-browserify": "^1.0.0",
+ "inherits": "~2.0.1",
+ "insert-module-globals": "^7.2.1",
+ "JSONStream": "^1.0.3",
+ "labeled-stream-splicer": "^2.0.0",
+ "mkdirp-classic": "^0.5.2",
+ "module-deps": "^6.2.3",
+ "os-browserify": "~0.3.0",
+ "parents": "^1.0.1",
+ "path-browserify": "^1.0.0",
+ "process": "~0.11.0",
+ "punycode": "^1.3.2",
+ "querystring-es3": "~0.2.0",
+ "read-only-stream": "^2.0.0",
+ "readable-stream": "^2.0.2",
+ "resolve": "^1.1.4",
+ "shasum-object": "^1.0.0",
+ "shell-quote": "^1.6.1",
+ "stream-browserify": "^3.0.0",
+ "stream-http": "^3.0.0",
+ "string_decoder": "^1.1.1",
+ "subarg": "^1.0.0",
+ "syntax-error": "^1.1.1",
+ "through2": "^2.0.0",
+ "timers-browserify": "^1.0.1",
+ "tty-browserify": "0.0.1",
+ "url": "~0.11.0",
+ "util": "~0.12.0",
+ "vm-browserify": "^1.0.0",
+ "xtend": "^4.0.0"
+ },
+ "bin": {
+ "browserify": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/browserify-aes": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+ "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-xor": "^1.0.3",
+ "cipher-base": "^1.0.0",
+ "create-hash": "^1.1.0",
+ "evp_bytestokey": "^1.0.3",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/browserify-cipher": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+ "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserify-aes": "^1.0.4",
+ "browserify-des": "^1.0.0",
+ "evp_bytestokey": "^1.0.0"
+ }
+ },
+ "node_modules/browserify-des": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
+ "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cipher-base": "^1.0.1",
+ "des.js": "^1.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "node_modules/browserify-rsa": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.1.tgz",
+ "integrity": "sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bn.js": "^5.2.1",
+ "randombytes": "^2.1.0",
+ "safe-buffer": "^5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/browserify-sign": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz",
+ "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "bn.js": "^5.2.1",
+ "browserify-rsa": "^4.1.0",
+ "create-hash": "^1.2.0",
+ "create-hmac": "^1.1.7",
+ "elliptic": "^6.5.5",
+ "hash-base": "~3.0",
+ "inherits": "^2.0.4",
+ "parse-asn1": "^5.1.7",
+ "readable-stream": "^2.3.8",
+ "safe-buffer": "^5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.12"
+ }
+ },
+ "node_modules/browserify-zlib": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+ "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pako": "~1.0.5"
+ }
+ },
+ "node_modules/bs-recipes": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/bs-recipes/-/bs-recipes-1.3.4.tgz",
+ "integrity": "sha512-BXvDkqhDNxXEjeGM8LFkSbR+jzmP/CYpCiVKYn+soB1dDldeU15EBNDkwVXndKuX35wnNUaPd0qSoQEAkmQtMw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz",
+ "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/buffer-xor": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+ "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/builtin-status-codes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
+ "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/c8": {
+ "version": "10.1.2",
+ "resolved": "https://registry.npmjs.org/c8/-/c8-10.1.2.tgz",
+ "integrity": "sha512-Qr6rj76eSshu5CgRYvktW0uM0CFY0yi4Fd5D0duDXO6sYinyopmftUiJVuzBQxQcwQLor7JWDVRP+dUfCmzgJw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@bcoe/v8-coverage": "^0.2.3",
+ "@istanbuljs/schema": "^0.1.3",
+ "find-up": "^5.0.0",
+ "foreground-child": "^3.1.1",
+ "istanbul-lib-coverage": "^3.2.0",
+ "istanbul-lib-report": "^3.0.1",
+ "istanbul-reports": "^3.1.6",
+ "test-exclude": "^7.0.1",
+ "v8-to-istanbul": "^9.0.0",
+ "yargs": "^17.7.2",
+ "yargs-parser": "^21.1.1"
+ },
+ "bin": {
+ "c8": "bin/c8.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "monocart-coverage-reports": "^2"
+ },
+ "peerDependenciesMeta": {
+ "monocart-coverage-reports": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/cacache": {
+ "version": "18.0.4",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz",
+ "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==",
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/fs": "^3.1.0",
+ "fs-minipass": "^3.0.0",
+ "glob": "^10.2.2",
+ "lru-cache": "^10.0.1",
+ "minipass": "^7.0.3",
+ "minipass-collect": "^2.0.1",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "p-map": "^4.0.0",
+ "ssri": "^10.0.0",
+ "tar": "^6.1.11",
+ "unique-filename": "^3.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/cacache/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/cacache/node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/cacache/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/cached-path-relative": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.1.0.tgz",
+ "integrity": "sha512-WF0LihfemtesFcJgO7xfOoOcnWzY/QHR4qeDqV44jPU3HTI54+LnfXK3SA27AVVGCdZFgjjFFaqUA9Jx7dMJZA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
+ "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz",
+ "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/caller-callsite": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
+ "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/caller-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz",
+ "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "caller-callsite": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
+ "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chownr": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/cipher-base": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.6.tgz",
+ "integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.4",
+ "safe-buffer": "^5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/clean-stack": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/clone": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/clone-buffer": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
+ "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/clone-stats": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
+ "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cloneable-readable": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz",
+ "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "process-nextick-args": "^2.0.0",
+ "readable-stream": "^2.3.5"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "license": "MIT"
+ },
+ "node_modules/color-support": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
+ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "color-support": "bin.js"
+ }
+ },
+ "node_modules/combine-source-map": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz",
+ "integrity": "sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "convert-source-map": "~1.1.0",
+ "inline-source-map": "~0.6.0",
+ "lodash.memoize": "~3.0.3",
+ "source-map": "~0.5.3"
+ }
+ },
+ "node_modules/commander": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+ "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "dev": true,
+ "engines": [
+ "node >= 0.8"
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "node_modules/concat-with-sourcemaps": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz",
+ "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "source-map": "^0.6.1"
+ }
+ },
+ "node_modules/concat-with-sourcemaps/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/config-chain": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
+ "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ini": "^1.3.4",
+ "proto-list": "~1.2.1"
+ }
+ },
+ "node_modules/connect": {
+ "version": "3.6.6",
+ "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz",
+ "integrity": "sha512-OO7axMmPpu/2XuX1+2Yrg0ddju31B6xLZMWkJ5rYBu4YRmRVlOjvlY6kw2FJKiAzyxGwnrDUAG4s1Pf0sbBMCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "finalhandler": "1.1.0",
+ "parseurl": "~1.3.2",
+ "utils-merge": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/connect-history-api-fallback": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz",
+ "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/console-browserify": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
+ "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==",
+ "dev": true
+ },
+ "node_modules/constants-browserify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
+ "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/convert-source-map": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz",
+ "integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cookie": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/copy-props": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-4.0.0.tgz",
+ "integrity": "sha512-bVWtw1wQLzzKiYROtvNlbJgxgBYt2bMJpkCbKmXM3xyijvcjjWXEk5nyrrT3bgJ7ODb19ZohE2T0Y3FgNPyoTw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "each-props": "^3.0.0",
+ "is-plain-object": "^5.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "license": "MIT"
+ },
+ "node_modules/cors": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+ "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/cosmiconfig": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
+ "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "import-fresh": "^2.0.0",
+ "is-directory": "^0.3.1",
+ "js-yaml": "^3.13.1",
+ "parse-json": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/create-ecdh": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
+ "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bn.js": "^4.1.0",
+ "elliptic": "^6.5.3"
+ }
+ },
+ "node_modules/create-ecdh/node_modules/bn.js": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
+ "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/create-hash": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+ "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cipher-base": "^1.0.1",
+ "inherits": "^2.0.1",
+ "md5.js": "^1.3.4",
+ "ripemd160": "^2.0.1",
+ "sha.js": "^2.4.0"
+ }
+ },
+ "node_modules/create-hmac": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+ "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cipher-base": "^1.0.3",
+ "create-hash": "^1.1.0",
+ "inherits": "^2.0.1",
+ "ripemd160": "^2.0.0",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/crypto-browserify": {
+ "version": "3.12.1",
+ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.1.tgz",
+ "integrity": "sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserify-cipher": "^1.0.1",
+ "browserify-sign": "^4.2.3",
+ "create-ecdh": "^4.0.4",
+ "create-hash": "^1.2.0",
+ "create-hmac": "^1.1.7",
+ "diffie-hellman": "^5.0.3",
+ "hash-base": "~3.0.4",
+ "inherits": "^2.0.4",
+ "pbkdf2": "^3.1.2",
+ "public-encrypt": "^4.0.3",
+ "randombytes": "^2.1.0",
+ "randomfill": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/dash-ast": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz",
+ "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/decomment": {
+ "version": "0.9.5",
+ "resolved": "https://registry.npmjs.org/decomment/-/decomment-0.9.5.tgz",
+ "integrity": "sha512-h0TZ8t6Dp49duwyDHo3iw67mnh9/UpFiSSiOb5gDK1sqoXzrfX/SQxIUQd2R2QEiSnqib0KF2fnKnGfAhAs6lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esprima": "4.0.1"
+ },
+ "engines": {
+ "node": ">=6.4",
+ "npm": ">=2.15"
+ }
+ },
+ "node_modules/decompress-response": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
+ "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+ "license": "MIT",
+ "dependencies": {
+ "mimic-response": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/defined": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz",
+ "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/deps-sort": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.1.tgz",
+ "integrity": "sha512-1orqXQr5po+3KI6kQb9A4jnXT1PBwggGl2d7Sq2xsnOeI9GPcE/tGcF9UiSZtZBM7MukY4cAh7MemS6tZYipfw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "JSONStream": "^1.0.3",
+ "shasum-object": "^1.0.0",
+ "subarg": "^1.0.0",
+ "through2": "^2.0.0"
+ },
+ "bin": {
+ "deps-sort": "bin/cmd.js"
+ }
+ },
+ "node_modules/des.js": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz",
+ "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "node_modules/destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/detect-file": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
+ "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/detect-libc": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
+ "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/detective": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz",
+ "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn-node": "^1.8.2",
+ "defined": "^1.0.0",
+ "minimist": "^1.2.6"
+ },
+ "bin": {
+ "detective": "bin/detective.js"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/dev-ip": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dev-ip/-/dev-ip-1.0.1.tgz",
+ "integrity": "sha512-LmVkry/oDShEgSZPNgqCIp2/TlqtExeGmymru3uCELnfyjY11IzpAproLYs+1X88fXO6DBoYP3ul2Xo2yz2j6A==",
+ "dev": true,
+ "bin": {
+ "dev-ip": "lib/dev-ip.js"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/diff": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
+ "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/diffie-hellman": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+ "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bn.js": "^4.1.0",
+ "miller-rabin": "^4.0.0",
+ "randombytes": "^2.0.0"
+ }
+ },
+ "node_modules/diffie-hellman/node_modules/bn.js": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
+ "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/domain-browser": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
+ "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4",
+ "npm": ">=1.2"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/duplexer2": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
+ "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "node_modules/each-props": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/each-props/-/each-props-3.0.0.tgz",
+ "integrity": "sha512-IYf1hpuWrdzse/s/YJOrFmU15lyhSzxelNVAHTEG3DtP4QsLTWZUzcUL3HMXmKQxXpa4EIrBPpwRgj0aehdvAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-object": "^5.0.0",
+ "object.defaults": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "license": "MIT"
+ },
+ "node_modules/easy-extender": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/easy-extender/-/easy-extender-2.3.4.tgz",
+ "integrity": "sha512-8cAwm6md1YTiPpOvDULYJL4ZS6WfM5/cTeVVh4JsvyYZAoqlRVUpHL9Gr5Fy7HA6xcSZicUia3DeAgO3Us8E+Q==",
+ "dev": true,
+ "dependencies": {
+ "lodash": "^4.17.10"
+ },
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/eazy-logger": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-4.0.1.tgz",
+ "integrity": "sha512-2GSFtnnC6U4IEKhEI7+PvdxrmjJ04mdsj3wHZTFiw0tUtG4HCWzTr13ZYTk8XOGnA1xQMaDljoBOYlk3D/MMSw==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "4.1.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/editorconfig": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz",
+ "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@one-ini/wasm": "0.1.1",
+ "commander": "^10.0.0",
+ "minimatch": "9.0.1",
+ "semver": "^7.5.3"
+ },
+ "bin": {
+ "editorconfig": "bin/editorconfig"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/editorconfig/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/editorconfig/node_modules/minimatch": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz",
+ "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/elliptic": {
+ "version": "6.6.1",
+ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz",
+ "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bn.js": "^4.11.9",
+ "brorand": "^1.1.0",
+ "hash.js": "^1.0.0",
+ "hmac-drbg": "^1.0.1",
+ "inherits": "^2.0.4",
+ "minimalistic-assert": "^1.0.1",
+ "minimalistic-crypto-utils": "^1.0.1"
+ }
+ },
+ "node_modules/elliptic/node_modules/bn.js": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
+ "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "license": "MIT"
+ },
+ "node_modules/encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/encoding": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
+ "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "iconv-lite": "^0.6.2"
+ }
+ },
+ "node_modules/end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "license": "MIT",
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
+ "node_modules/engine.io": {
+ "version": "6.6.4",
+ "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz",
+ "integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/cors": "^2.8.12",
+ "@types/node": ">=10.0.0",
+ "accepts": "~1.3.4",
+ "base64id": "2.0.0",
+ "cookie": "~0.7.2",
+ "cors": "~2.8.5",
+ "debug": "~4.3.1",
+ "engine.io-parser": "~5.2.1",
+ "ws": "~8.17.1"
+ },
+ "engines": {
+ "node": ">=10.2.0"
+ }
+ },
+ "node_modules/engine.io-client": {
+ "version": "6.6.3",
+ "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.3.tgz",
+ "integrity": "sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@socket.io/component-emitter": "~3.1.0",
+ "debug": "~4.3.1",
+ "engine.io-parser": "~5.2.1",
+ "ws": "~8.17.1",
+ "xmlhttprequest-ssl": "~2.1.1"
+ }
+ },
+ "node_modules/engine.io-client/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/engine.io-client/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/engine.io-parser": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
+ "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/engine.io/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/engine.io/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/err-code": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
+ "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
+ "license": "MIT"
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/eventemitter3": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
+ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.x"
+ }
+ },
+ "node_modules/evp_bytestokey": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "md5.js": "^1.3.4",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/expand-template": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
+ "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
+ "license": "(MIT OR WTFPL)",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/expand-tilde": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
+ "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "homedir-polyfill": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/exponential-backoff": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz",
+ "integrity": "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fancy-log": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz",
+ "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-gray": "^0.1.1",
+ "color-support": "^1.1.3",
+ "parse-node-version": "^1.0.0",
+ "time-stamp": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/fast-fifo": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
+ "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",
+ "license": "MIT"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz",
+ "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fastest-levenshtein": "^1.0.7"
+ }
+ },
+ "node_modules/fast-safe-stringify": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
+ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fastest-levenshtein": {
+ "version": "1.0.16",
+ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+ "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4.9.1"
+ }
+ },
+ "node_modules/fastq": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz",
+ "integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/file-uri-to-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+ "license": "MIT"
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
+ "integrity": "sha512-ejnvM9ZXYzp6PUPUyQBMBf0Co5VX2gr5H2VQe2Ui2jWXNlxv+PYZo8wpAymJNJdLsG1R4p+M4aynF8KuoUEwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.1",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.2",
+ "statuses": "~1.3.1",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/findup-sync": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz",
+ "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "detect-file": "^1.0.0",
+ "is-glob": "^4.0.3",
+ "micromatch": "^4.0.4",
+ "resolve-dir": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/fined": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fined/-/fined-2.0.0.tgz",
+ "integrity": "sha512-OFRzsL6ZMHz5s0JrsEr+TpdGNCtrVtnuG3x1yzGNiQHT0yaDnXAj8V/lWcpJVrnoDpcwXcASxAZYbuXda2Y82A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "expand-tilde": "^2.0.2",
+ "is-plain-object": "^5.0.0",
+ "object.defaults": "^1.1.0",
+ "object.pick": "^1.3.0",
+ "parse-filepath": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/flagged-respawn": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-2.0.0.tgz",
+ "integrity": "sha512-Gq/a6YCi8zexmGHMuJwahTGzXlAZAOsbCVKduWXC6TlLCjjFRlExMJc4GC2NYPYZ0r/brw9P7CpRgQmlPVeOoA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.9",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
+ "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/for-each": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
+ "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/for-own": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
+ "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "for-in": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/foreground-child": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
+ "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.0",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fs-constants": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
+ "license": "MIT"
+ },
+ "node_modules/fs-extra": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz",
+ "integrity": "sha512-V3Z3WZWVUYd8hoCL5xfXJCaHWYzmtwW5XWYSlLgERi8PWd8bx1kUHUk8L1BT57e49oKnDDD180mjfrHc1yA9rg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^3.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "node_modules/fs-minipass": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz",
+ "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==",
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/fs-mkdirp-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-2.0.1.tgz",
+ "integrity": "sha512-UTOY+59K6IA94tec8Wjqm0FSh5OVudGNB0NL/P6fB3HiE3bYOY3VYBGijsnOHNkQSwC1FKkU77pmq7xp9CskLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.8",
+ "streamx": "^2.12.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-assigned-identifiers": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz",
+ "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz",
+ "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.0",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/github-from-package": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
+ "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
+ "license": "MIT"
+ },
+ "node_modules/gl": {
+ "version": "8.1.6",
+ "resolved": "https://registry.npmjs.org/gl/-/gl-8.1.6.tgz",
+ "integrity": "sha512-BcvkgW+jWiX2SjTddgq4lOfkFmeiKE/n1N3zFnq/JlSwemIvQvH1rLURz5oMdfp4ZT5bzseuIOE608zQI0DRYA==",
+ "hasInstallScript": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "bindings": "^1.5.0",
+ "bit-twiddle": "^1.0.2",
+ "glsl-tokenizer": "^2.1.5",
+ "nan": "^2.22.0",
+ "node-abi": "^3.71.0",
+ "node-gyp": "^10.2.0",
+ "prebuild-install": "^7.1.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/gl-wiretap": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/gl-wiretap/-/gl-wiretap-0.6.2.tgz",
+ "integrity": "sha512-fxy1XGiPkfzK+T3XKDbY7yaqMBmozCGvAFyTwaZA3imeZH83w7Hr3r3bYlMRWIyzMI/lDUvUMM/92LE2OwqFyQ==",
+ "license": "MIT"
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/glob-stream": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.2.tgz",
+ "integrity": "sha512-R8z6eTB55t3QeZMmU1C+Gv+t5UnNRkA55c5yo67fAVfxODxieTwsjNG7utxS/73NdP1NbDgCrhVEg2h00y4fFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@gulpjs/to-absolute-glob": "^4.0.0",
+ "anymatch": "^3.1.3",
+ "fastq": "^1.13.0",
+ "glob-parent": "^6.0.2",
+ "is-glob": "^4.0.3",
+ "is-negated-glob": "^1.0.0",
+ "normalize-path": "^3.0.0",
+ "streamx": "^2.12.5"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/glob-stream/node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/glob-watcher": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-6.0.0.tgz",
+ "integrity": "sha512-wGM28Ehmcnk2NqRORXFOTOR064L4imSw3EeOqU5bIwUf62eXGwg89WivH6VMahL8zlQHeodzvHpXplrqzrz3Nw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async-done": "^2.0.0",
+ "chokidar": "^3.5.3"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/global-modules": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
+ "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "global-prefix": "^1.0.1",
+ "is-windows": "^1.0.1",
+ "resolve-dir": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/global-prefix": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
+ "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "expand-tilde": "^2.0.2",
+ "homedir-polyfill": "^1.0.1",
+ "ini": "^1.3.4",
+ "is-windows": "^1.0.1",
+ "which": "^1.2.14"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/global-prefix/node_modules/which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "which": "bin/which"
+ }
+ },
+ "node_modules/globalyzer": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz",
+ "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/globby": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+ "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.9",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globrex": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz",
+ "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/glogg": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/glogg/-/glogg-2.2.0.tgz",
+ "integrity": "sha512-eWv1ds/zAlz+M1ioHsyKJomfY7jbDDPpwSkv14KQj89bycx1nvK5/2Cj/T9g7kzJcX5Bc7Yv22FjfBZS/jl94A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sparkles": "^2.1.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/glsl-tokenizer": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/glsl-tokenizer/-/glsl-tokenizer-2.1.5.tgz",
+ "integrity": "sha512-XSZEJ/i4dmz3Pmbnpsy3cKh7cotvFlBiZnDOwnj/05EwNp2XrhQ4XKJxT7/pDt4kp4YcpRSKz8eTV7S+mwV6MA==",
+ "license": "MIT",
+ "dependencies": {
+ "through2": "^0.6.3"
+ }
+ },
+ "node_modules/glsl-tokenizer/node_modules/isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
+ "license": "MIT"
+ },
+ "node_modules/glsl-tokenizer/node_modules/readable-stream": {
+ "version": "1.0.34",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+ "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==",
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "node_modules/glsl-tokenizer/node_modules/string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
+ "license": "MIT"
+ },
+ "node_modules/glsl-tokenizer/node_modules/through2": {
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz",
+ "integrity": "sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg==",
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": ">=1.0.33-1 <1.1.0-0",
+ "xtend": ">=4.0.0 <4.1.0-0"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gpu-mock.js": {
+ "version": "1.3.1",
+ "resolved": "git+ssh://git@github.com/weagle08/gpu-mock.js.git#7f3d7a75d29e34c5098d6102fce006c53b5df50d",
+ "license": "MIT"
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "license": "ISC"
+ },
+ "node_modules/gulp": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/gulp/-/gulp-5.0.0.tgz",
+ "integrity": "sha512-S8Z8066SSileaYw1S2N1I64IUc/myI2bqe2ihOBzO6+nKpvNSg7ZcWJt/AwF8LC/NVN+/QZ560Cb/5OPsyhkhg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "glob-watcher": "^6.0.0",
+ "gulp-cli": "^3.0.0",
+ "undertaker": "^2.0.0",
+ "vinyl-fs": "^4.0.0"
+ },
+ "bin": {
+ "gulp": "bin/gulp.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/gulp-cli": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-3.0.0.tgz",
+ "integrity": "sha512-RtMIitkT8DEMZZygHK2vEuLPqLPAFB4sntSxg4NoDta7ciwGZ18l7JuhCTiS5deOJi2IoK0btE+hs6R4sfj7AA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@gulpjs/messages": "^1.1.0",
+ "chalk": "^4.1.2",
+ "copy-props": "^4.0.0",
+ "gulplog": "^2.2.0",
+ "interpret": "^3.1.1",
+ "liftoff": "^5.0.0",
+ "mute-stdout": "^2.0.0",
+ "replace-homedir": "^2.0.0",
+ "semver-greatest-satisfied-range": "^2.0.0",
+ "string-width": "^4.2.3",
+ "v8flags": "^4.0.0",
+ "yargs": "^16.2.0"
+ },
+ "bin": {
+ "gulp": "bin/gulp.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/gulp-cli/node_modules/cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "node_modules/gulp-cli/node_modules/yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/gulp-cli/node_modules/yargs-parser": {
+ "version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/gulp-concat": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz",
+ "integrity": "sha512-a2scActrQrDBpBbR3WUZGyGS1JEPLg5PZJdIa7/Bi3GuKAmPYDK6SFhy/NZq5R8KsKKFvtfR0fakbUCcKGCCjg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "concat-with-sourcemaps": "^1.0.0",
+ "through2": "^2.0.0",
+ "vinyl": "^2.0.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/gulp-header": {
+ "version": "2.0.9",
+ "resolved": "https://registry.npmjs.org/gulp-header/-/gulp-header-2.0.9.tgz",
+ "integrity": "sha512-LMGiBx+qH8giwrOuuZXSGvswcIUh0OiioNkUpLhNyvaC6/Ga8X6cfAeme2L5PqsbXMhL8o8b/OmVqIQdxprhcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "concat-with-sourcemaps": "^1.1.0",
+ "lodash.template": "^4.5.0",
+ "map-stream": "0.0.7",
+ "through2": "^2.0.0"
+ }
+ },
+ "node_modules/gulp-jsbeautifier": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/gulp-jsbeautifier/-/gulp-jsbeautifier-3.0.1.tgz",
+ "integrity": "sha512-zSXsXQy0/s6qjhhtTun+/ZfC/q8cz/fZpZmxoGPKpmxjuP7/F+oGpV/LHqtOAaWNo+WjcxLVey0cFoNrPZiHWg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-colors": "^4.1.1",
+ "cosmiconfig": "^5.2.1",
+ "fancy-log": "^1.3.3",
+ "js-beautify": "^1.10.1",
+ "lodash.mergewith": "^4.6.2",
+ "plugin-error": "^1.0.1",
+ "through2": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/gulp-jsbeautifier/node_modules/through2": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz",
+ "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.4",
+ "readable-stream": "2 || 3"
+ }
+ },
+ "node_modules/gulp-rename": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-2.0.0.tgz",
+ "integrity": "sha512-97Vba4KBzbYmR5VBs9mWmK+HwIf5mj+/zioxfZhOKeXtx5ZjBk57KFlePf5nxq9QsTtFl0ejnHE3zTC9MHXqyQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/gulp-replace": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/gulp-replace/-/gulp-replace-1.1.4.tgz",
+ "integrity": "sha512-SVSF7ikuWKhpAW4l4wapAqPPSToJoiNKsbDoUnRrSgwZHH7lH8pbPeQj1aOVYQrbZKhfSVBxVW+Py7vtulRktw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "@types/vinyl": "^2.0.4",
+ "istextorbinary": "^3.0.0",
+ "replacestream": "^4.0.3",
+ "yargs-parser": ">=5.0.0-security.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/gulp-strip-comments": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/gulp-strip-comments/-/gulp-strip-comments-2.6.0.tgz",
+ "integrity": "sha512-tl3xM5zAcdgvyXxd70riKn4l9mroU/4WMYbMzyYJB8/NJNcW/Z78FRGMYwcHvAfHH7v5K7MF4kumdZ0JAXKjag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "decomment": "^0.9.5",
+ "plugin-error": "^2.0.1",
+ "through2": "^4.0.2"
+ }
+ },
+ "node_modules/gulp-strip-comments/node_modules/ansi-colors": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz",
+ "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-wrap": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/gulp-strip-comments/node_modules/plugin-error": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-2.0.1.tgz",
+ "integrity": "sha512-zMakqvIDyY40xHOvzXka0kUvf40nYIuwRE8dWhti2WtjQZ31xAgBZBhxsK7vK3QbRXS1Xms/LO7B5cuAsfB2Gg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-colors": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/gulp-strip-comments/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/gulp-strip-comments/node_modules/through2": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz",
+ "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "3"
+ }
+ },
+ "node_modules/gulp-uglify-es": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/gulp-uglify-es/-/gulp-uglify-es-3.0.0.tgz",
+ "integrity": "sha512-dQ3czMFFojNgCajcrYl0oa98+YayaQ8kXRdaacpZRZ3iw2sdVURfdt8y8Ki1ogZGQqw8BUawnB7V6NkanxqnDg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "o-stream": "^0.3.0",
+ "plugin-error": "^1.0.1",
+ "terser": "^5.7.1",
+ "vinyl": "^2.2.1",
+ "vinyl-sourcemaps-apply": "^0.2.1"
+ }
+ },
+ "node_modules/gulplog": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-2.2.0.tgz",
+ "integrity": "sha512-V2FaKiOhpR3DRXZuYdRLn/qiY0yI5XmqbTKrYbdemJ+xOh2d2MOweI/XFgMzd/9+1twdvMwllnZbWZNJ+BOm4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "glogg": "^2.2.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/has": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz",
+ "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hash-base": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.5.tgz",
+ "integrity": "sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.4",
+ "safe-buffer": "^5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/hash.js": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+ "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "minimalistic-assert": "^1.0.1"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/hmac-drbg": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+ "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hash.js": "^1.0.3",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.1"
+ }
+ },
+ "node_modules/homedir-polyfill": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
+ "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parse-passwd": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/htmlescape": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz",
+ "integrity": "sha512-eVcrzgbR4tim7c7soKQKtxa/kQM4TzjnlU83rcZ9bHU6t31ehfV7SktN6McWgwPWg+JYMA/O3qpGxBvFq1z2Jg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/http-cache-semantics": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
+ "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/http-errors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/http-errors/node_modules/statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/http-proxy": {
+ "version": "1.18.1",
+ "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
+ "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eventemitter3": "^4.0.0",
+ "follow-redirects": "^1.0.0",
+ "requires-port": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/http-proxy-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/http-proxy-agent/node_modules/debug": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/http-proxy-agent/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/https-browserify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
+ "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/https-proxy-agent/node_modules/debug": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/https-proxy-agent/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/immutable": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz",
+ "integrity": "sha512-15gZoQ38eYjEjxkorfbcgBKBL6R7T459OuK+CpcWt7O3KF4uPCx2tD0uFETlUDIyo+1789crbMhTvQBSR5yBMg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
+ "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "caller-path": "^2.0.0",
+ "resolve-from": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "license": "ISC"
+ },
+ "node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "license": "ISC"
+ },
+ "node_modules/inline-source-map": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.3.tgz",
+ "integrity": "sha512-1aVsPEsJWMJq/pdMU61CDlm1URcW702MTB4w9/zUjMus6H/Py8o7g68Pr9D4I6QluWGt/KdmswuRhaA05xVR1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "source-map": "~0.5.3"
+ }
+ },
+ "node_modules/insert-module-globals": {
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.1.tgz",
+ "integrity": "sha512-ufS5Qq9RZN+Bu899eA9QCAYThY+gGW7oRkmb0vC93Vlyu/CFGcH0OYPEjVkDXA5FEbTt1+VWzdoOD3Ny9N+8tg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn-node": "^1.5.2",
+ "combine-source-map": "^0.8.0",
+ "concat-stream": "^1.6.1",
+ "is-buffer": "^1.1.0",
+ "JSONStream": "^1.0.3",
+ "path-is-absolute": "^1.0.1",
+ "process": "~0.11.0",
+ "through2": "^2.0.0",
+ "undeclared-identifiers": "^1.1.2",
+ "xtend": "^4.0.0"
+ },
+ "bin": {
+ "insert-module-globals": "bin/cmd.js"
+ }
+ },
+ "node_modules/interpret": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
+ "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/ip-address": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
+ "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==",
+ "license": "MIT",
+ "dependencies": {
+ "jsbn": "1.1.0",
+ "sprintf-js": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/ip-address/node_modules/sprintf-js": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
+ "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/is-absolute": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
+ "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-relative": "^1.0.0",
+ "is-windows": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-arguments": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz",
+ "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-directory": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
+ "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-object": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-extendable/node_modules/is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-generator-function": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz",
+ "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.0",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-lambda": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
+ "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
+ "license": "MIT"
+ },
+ "node_modules/is-negated-glob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz",
+ "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-number-like": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/is-number-like/-/is-number-like-1.0.8.tgz",
+ "integrity": "sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "lodash.isfinite": "^3.3.2"
+ }
+ },
+ "node_modules/is-path-cwd": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
+ "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is-path-in-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-3.0.0.tgz",
+ "integrity": "sha512-QGuLYLNfpHI/xLQ8ctyeD9mMCf2eBqrtxYWKQxlExrD0l3wBSDcplKYfV55lnTDB4MDvh9SRDt/VnDwVn0dYOw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-path-inside": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-regex": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
+ "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-relative": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
+ "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-unc-path": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
+ "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-unc-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
+ "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "unc-path-regex": "^0.1.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-valid-glob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz",
+ "integrity": "sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-wsl": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
+ "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "license": "ISC"
+ },
+ "node_modules/isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+ "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^4.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-reports": {
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz",
+ "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istextorbinary": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-3.3.0.tgz",
+ "integrity": "sha512-Tvq1W6NAcZeJ8op+Hq7tdZ434rqnMx4CCZ7H0ff83uEloDvVbqAwaMTZcafKGJT0VHkYzuXUiCY4hlXQg6WfoQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binaryextensions": "^2.2.0",
+ "textextensions": "^3.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://bevry.me/fund"
+ }
+ },
+ "node_modules/jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/js-beautify": {
+ "version": "1.15.3",
+ "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.3.tgz",
+ "integrity": "sha512-rKKGuyTxGNlyN4EQKWzNndzXpi0bOl8Gl8YQAW1as/oMz0XhD6sHJO1hTvoBDOSzKuJb9WkwoAb34FfdkKMv2A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "config-chain": "^1.1.13",
+ "editorconfig": "^1.0.4",
+ "glob": "^10.4.2",
+ "js-cookie": "^3.0.5",
+ "nopt": "^8.0.0"
+ },
+ "bin": {
+ "css-beautify": "js/bin/css-beautify.js",
+ "html-beautify": "js/bin/html-beautify.js",
+ "js-beautify": "js/bin/js-beautify.js"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/js-beautify/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/js-beautify/node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/js-beautify/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/js-cookie": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
+ "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsbn": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
+ "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==",
+ "license": "MIT"
+ },
+ "node_modules/json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/jsonfile": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz",
+ "integrity": "sha512-oBko6ZHlubVB5mRFkur5vgYR1UyqX+S6Y/oCfLhqNdcc2fYFlDpIoNc7AfKS1KOGcnNAkvsr0grLck9ANM815w==",
+ "dev": true,
+ "license": "MIT",
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/jsonparse": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
+ "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==",
+ "dev": true,
+ "engines": [
+ "node >= 0.2.0"
+ ],
+ "license": "MIT"
+ },
+ "node_modules/JSONStream": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
+ "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
+ "dev": true,
+ "license": "(MIT OR Apache-2.0)",
+ "dependencies": {
+ "jsonparse": "^1.2.0",
+ "through": ">=2.2.7 <3"
+ },
+ "bin": {
+ "JSONStream": "bin.js"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/just-extend": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz",
+ "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/labeled-stream-splicer": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz",
+ "integrity": "sha512-Ca4LSXFFZUjPScRaqOcFxneA0VpKZr4MMYCljyQr4LIewTLb3Y0IUTIsnBBsVubIeEfxeSZpSjSsRM8APEQaAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "stream-splicer": "^2.0.0"
+ }
+ },
+ "node_modules/last-run": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/last-run/-/last-run-2.0.0.tgz",
+ "integrity": "sha512-j+y6WhTLN4Itnf9j5ZQos1BGPCS8DAwmgMroR3OzfxAsBxam0hMw7J8M3KqZl0pLQJ1jNnwIexg5DYpC/ctwEQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/lead": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/lead/-/lead-4.0.0.tgz",
+ "integrity": "sha512-DpMa59o5uGUWWjruMp71e6knmwKU3jRBBn1kjuLWN9EeIOxNeSAwvHf03WIl8g/ZMR2oSQC9ej3yeLBwdDc/pg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/liftoff": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-5.0.0.tgz",
+ "integrity": "sha512-a5BQjbCHnB+cy+gsro8lXJ4kZluzOijzJ1UVVfyJYZC+IP2pLv1h4+aysQeKuTmyO8NAqfyQAk4HWaP/HjcKTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "extend": "^3.0.2",
+ "findup-sync": "^5.0.0",
+ "fined": "^2.0.0",
+ "flagged-respawn": "^2.0.0",
+ "is-plain-object": "^5.0.0",
+ "rechoir": "^0.8.0",
+ "resolve": "^1.20.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/limiter": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz",
+ "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==",
+ "dev": true
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash._reinterpolate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
+ "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
+ "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.isfinite": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz",
+ "integrity": "sha512-7FGG40uhC8Mm633uKW1r58aElFlBlxCrg9JfSi3P6aYiWmfiWF0PgMd86ZUsxE5GwWPdHoS2+48bwTh2VPkIQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.memoize": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz",
+ "integrity": "sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.mergewith": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
+ "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.template": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
+ "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==",
+ "deprecated": "This package is deprecated. Use https://socket.dev/npm/package/eta instead.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash._reinterpolate": "^3.0.0",
+ "lodash.templatesettings": "^4.0.0"
+ }
+ },
+ "node_modules/lodash.templatesettings": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz",
+ "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash._reinterpolate": "^3.0.0"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "license": "ISC"
+ },
+ "node_modules/make-dir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
+ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/make-fetch-happen": {
+ "version": "13.0.1",
+ "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz",
+ "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==",
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/agent": "^2.0.0",
+ "cacache": "^18.0.0",
+ "http-cache-semantics": "^4.1.1",
+ "is-lambda": "^1.0.1",
+ "minipass": "^7.0.2",
+ "minipass-fetch": "^3.0.0",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "negotiator": "^0.6.3",
+ "proc-log": "^4.2.0",
+ "promise-retry": "^2.0.1",
+ "ssri": "^10.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/map-stream": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz",
+ "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/md5.js": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
+ "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/miller-rabin": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+ "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bn.js": "^4.0.0",
+ "brorand": "^1.0.1"
+ },
+ "bin": {
+ "miller-rabin": "bin/miller-rabin"
+ }
+ },
+ "node_modules/miller-rabin/node_modules/bn.js": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
+ "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mime": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
+ "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-response": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
+ "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/minimalistic-assert": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/minimalistic-crypto-utils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+ "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/minipass-collect": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz",
+ "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==",
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/minipass-fetch": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz",
+ "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==",
+ "license": "MIT",
+ "dependencies": {
+ "minipass": "^7.0.3",
+ "minipass-sized": "^1.0.3",
+ "minizlib": "^2.1.2"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ },
+ "optionalDependencies": {
+ "encoding": "^0.1.13"
+ }
+ },
+ "node_modules/minipass-flush": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
+ "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/minipass-flush/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-pipeline": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
+ "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-pipeline/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-sized": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
+ "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-sized/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minizlib": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+ "license": "MIT",
+ "dependencies": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/minizlib/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/mitt": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.2.0.tgz",
+ "integrity": "sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "license": "MIT",
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/mkdirp-classic": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
+ "license": "MIT"
+ },
+ "node_modules/module-deps": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.3.tgz",
+ "integrity": "sha512-fg7OZaQBcL4/L+AK5f4iVqf9OMbCclXfy/znXRxTVhJSeW5AIlS9AwheYwDaXM3lVW7OBeaeUEY3gbaC6cLlSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browser-resolve": "^2.0.0",
+ "cached-path-relative": "^1.0.2",
+ "concat-stream": "~1.6.0",
+ "defined": "^1.0.0",
+ "detective": "^5.2.0",
+ "duplexer2": "^0.1.2",
+ "inherits": "^2.0.1",
+ "JSONStream": "^1.0.3",
+ "parents": "^1.0.0",
+ "readable-stream": "^2.0.2",
+ "resolve": "^1.4.0",
+ "stream-combiner2": "^1.1.1",
+ "subarg": "^1.0.0",
+ "through2": "^2.0.0",
+ "xtend": "^4.0.0"
+ },
+ "bin": {
+ "module-deps": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mute-stdout": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-2.0.0.tgz",
+ "integrity": "sha512-32GSKM3Wyc8dg/p39lWPKYu8zci9mJFzV1Np9Of0ZEpe6Fhssn/FbI7ywAMd40uX+p3ZKh3T5EeCFv81qS3HmQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/nan": {
+ "version": "2.22.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz",
+ "integrity": "sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==",
+ "license": "MIT"
+ },
+ "node_modules/napi-build-utils": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
+ "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
+ "license": "MIT"
+ },
+ "node_modules/negotiator": {
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
+ "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/nise": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/nise/-/nise-6.1.1.tgz",
+ "integrity": "sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.1",
+ "@sinonjs/fake-timers": "^13.0.1",
+ "@sinonjs/text-encoding": "^0.7.3",
+ "just-extend": "^6.2.0",
+ "path-to-regexp": "^8.1.0"
+ }
+ },
+ "node_modules/nise/node_modules/@sinonjs/fake-timers": {
+ "version": "13.0.5",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz",
+ "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.1"
+ }
+ },
+ "node_modules/node-abi": {
+ "version": "3.74.0",
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.74.0.tgz",
+ "integrity": "sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w==",
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/node-gyp": {
+ "version": "10.3.1",
+ "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.3.1.tgz",
+ "integrity": "sha512-Pp3nFHBThHzVtNY7U6JfPjvT/DTE8+o/4xKsLQtBoU+j2HLsGlhcfzflAoUreaJbNmYnX+LlLi0qjV8kpyO6xQ==",
+ "license": "MIT",
+ "dependencies": {
+ "env-paths": "^2.2.0",
+ "exponential-backoff": "^3.1.1",
+ "glob": "^10.3.10",
+ "graceful-fs": "^4.2.6",
+ "make-fetch-happen": "^13.0.0",
+ "nopt": "^7.0.0",
+ "proc-log": "^4.1.0",
+ "semver": "^7.3.5",
+ "tar": "^6.2.1",
+ "which": "^4.0.0"
+ },
+ "bin": {
+ "node-gyp": "bin/node-gyp.js"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/node-gyp/node_modules/abbrev": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz",
+ "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==",
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/node-gyp/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/node-gyp/node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/node-gyp/node_modules/isexe": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz",
+ "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/node-gyp/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/node-gyp/node_modules/nopt": {
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz",
+ "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==",
+ "license": "ISC",
+ "dependencies": {
+ "abbrev": "^2.0.0"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/node-gyp/node_modules/which": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz",
+ "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==",
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^3.1.1"
+ },
+ "bin": {
+ "node-which": "bin/which.js"
+ },
+ "engines": {
+ "node": "^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/node-watch": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.7.3.tgz",
+ "integrity": "sha512-3l4E8uMPY1HdMMryPRUAl+oIHtXtyiTlIiESNSVSNxcPfzAFzeTbXFQkZfAwBbo0B1qMSG8nUABx+Gd+YrbKrQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/nopt": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz",
+ "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "abbrev": "^3.0.0"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/now-and-later": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz",
+ "integrity": "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "once": "^1.4.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/o-stream": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/o-stream/-/o-stream-0.3.0.tgz",
+ "integrity": "sha512-gbzl6qCJZ609x/M2t25HqCYQagFzWYCtQ84jcuObGr+V8D1Am4EVubkF4J+XFs6ukfiv96vNeiBb8FrbbMZYiQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.7",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
+ "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0",
+ "has-symbols": "^1.1.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.defaults": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz",
+ "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-each": "^1.0.1",
+ "array-slice": "^1.0.0",
+ "for-own": "^1.0.0",
+ "isobject": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/opn": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz",
+ "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-wsl": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ordered-read-streams": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-2.0.0.tgz",
+ "integrity": "sha512-YT9wHHV9mB/qadhWnBsC57JKhAMA22/aR+RwZRgcf4K4Q7IIfmSsnYGxgiu9LVZP3wddRAm5pfYkzkmBb+HuwA==",
+ "license": "MIT",
+ "dependencies": {
+ "streamx": "^2.12.5"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/os-browserify": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
+ "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-map": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
+ "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
+ "license": "MIT",
+ "dependencies": {
+ "aggregate-error": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+ "license": "BlueOak-1.0.0"
+ },
+ "node_modules/pako": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+ "dev": true,
+ "license": "(MIT AND Zlib)"
+ },
+ "node_modules/parents": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz",
+ "integrity": "sha512-mXKF3xkoUt5td2DoxpLmtOmZvko9VfFpwRwkKDHSNvgmpLAeBo18YDhcPbBzJq+QLCHMbGOfzia2cX4U+0v9Mg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-platform": "~0.11.15"
+ }
+ },
+ "node_modules/parse-asn1": {
+ "version": "5.1.7",
+ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz",
+ "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "asn1.js": "^4.10.1",
+ "browserify-aes": "^1.2.0",
+ "evp_bytestokey": "^1.0.3",
+ "hash-base": "~3.0",
+ "pbkdf2": "^3.1.2",
+ "safe-buffer": "^5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/parse-filepath": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
+ "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-absolute": "^1.0.0",
+ "map-cache": "^0.2.0",
+ "path-root": "^0.1.1"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/parse-node-version": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz",
+ "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/parse-passwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+ "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/path-browserify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
+ "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-platform": {
+ "version": "0.11.15",
+ "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz",
+ "integrity": "sha512-Y30dB6rab1A/nfEKsZxmr01nUotHX0c/ZiIAsCTatEe1CmS5Pm5He7fZ195bPT7RdquoaL8lLxFCMQi/bS7IJg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/path-root": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
+ "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-root-regex": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-root-regex": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
+ "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/path-sort2": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/path-sort2/-/path-sort2-1.0.0.tgz",
+ "integrity": "sha512-OwUzmr3+avyEANhpUkUv+nlwAM/sCX5y9Ylok8fj3OK3SmLclq7jyEoqSL5qi+5bJAOskWGZPtdtjnoRGy5lxA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-to-regexp": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
+ "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pbkdf2": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz",
+ "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "create-hash": "^1.1.2",
+ "create-hmac": "^1.1.4",
+ "ripemd160": "^2.0.1",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ },
+ "engines": {
+ "node": ">=0.12"
+ }
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/platform": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz",
+ "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/plugin-error": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz",
+ "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-colors": "^1.0.1",
+ "arr-diff": "^4.0.0",
+ "arr-union": "^3.1.0",
+ "extend-shallow": "^3.0.2"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/plugin-error/node_modules/ansi-colors": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz",
+ "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-wrap": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/portscanner": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.2.0.tgz",
+ "integrity": "sha512-IFroCz/59Lqa2uBvzK3bKDbDDIEaAY8XJ1jFxcLWTqosrsc32//P4VuSB2vZXoHiHqOmx8B5L5hnKOxL/7FlPw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async": "^2.6.0",
+ "is-number-like": "^1.0.3"
+ },
+ "engines": {
+ "node": ">=0.4",
+ "npm": ">=1.0.0"
+ }
+ },
+ "node_modules/possible-typed-array-names": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
+ "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/prebuild-install": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
+ "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
+ "license": "MIT",
+ "dependencies": {
+ "detect-libc": "^2.0.0",
+ "expand-template": "^2.0.3",
+ "github-from-package": "0.0.0",
+ "minimist": "^1.2.3",
+ "mkdirp-classic": "^0.5.3",
+ "napi-build-utils": "^2.0.0",
+ "node-abi": "^3.3.0",
+ "pump": "^3.0.0",
+ "rc": "^1.2.7",
+ "simple-get": "^4.0.0",
+ "tar-fs": "^2.0.0",
+ "tunnel-agent": "^0.6.0"
+ },
+ "bin": {
+ "prebuild-install": "bin.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/proc-log": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz",
+ "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==",
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6.0"
+ }
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/promise-retry": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
+ "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
+ "license": "MIT",
+ "dependencies": {
+ "err-code": "^2.0.2",
+ "retry": "^0.12.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/proto-list": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+ "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/public-encrypt": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
+ "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bn.js": "^4.1.0",
+ "browserify-rsa": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "parse-asn1": "^5.0.0",
+ "randombytes": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "node_modules/public-encrypt/node_modules/bn.js": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
+ "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pump": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
+ "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
+ "license": "MIT",
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/qs": {
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
+ "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/querystring-es3": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+ "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.x"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/qunit": {
+ "version": "2.22.0",
+ "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.22.0.tgz",
+ "integrity": "sha512-wPYvAvpjTL3zlUeyCX75T8gfZfdVXZa8y1EVkGe/XZNORIsCH/WI2X8R2KlemT921X9EKSZUL6CLGSPC7Ks08g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "commander": "7.2.0",
+ "node-watch": "0.7.3",
+ "tiny-glob": "0.2.9"
+ },
+ "bin": {
+ "qunit": "bin/qunit.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/qunit/node_modules/commander": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/randomfill": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+ "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "randombytes": "^2.0.5",
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
+ "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/raw-body/node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
+ "dependencies": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ },
+ "bin": {
+ "rc": "cli.js"
+ }
+ },
+ "node_modules/read-dir-deep": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/read-dir-deep/-/read-dir-deep-8.0.0.tgz",
+ "integrity": "sha512-gh+BoQZ7tR5tfpbYyU9vLJ5u3mKxB9Os9/5dKjmtJCrtU9Ef7BUWoxQ8LQ8aa1zATIrWGCdvQttqIhaVDPltbQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "globby": "^11.1.0",
+ "is-path-cwd": "^2.2.0",
+ "is-path-in-cwd": "^3.0.0",
+ "path-sort2": "^1.0.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=18.12.0"
+ }
+ },
+ "node_modules/read-only-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz",
+ "integrity": "sha512-3ALe0bjBVZtkdWKIcThYpQCLbBMd/+Tbh2CDSrAIDO3UsZ4Xs+tnyjv2MjCOMMgBG+AsUOeuP1cgtY1INISc8w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/readable-stream/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/readable-stream/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/rechoir": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
+ "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve": "^1.20.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/remove-trailing-separator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+ "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/replace-ext": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz",
+ "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/replace-homedir": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-2.0.0.tgz",
+ "integrity": "sha512-bgEuQQ/BHW0XkkJtawzrfzHFSN70f/3cNOiHa2QsYxqrjaC30X1k74FJ6xswVBP0sr0SpGIdVFuPwfrYziVeyw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/replacestream": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/replacestream/-/replacestream-4.0.3.tgz",
+ "integrity": "sha512-AC0FiLS352pBBiZhd4VXB1Ab/lh0lEgpP+GGvZqbQh8a5cmXVoTe5EX/YeTFArnp4SRGTHh1qCHu9lGs1qG8sA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "escape-string-regexp": "^1.0.3",
+ "object-assign": "^4.0.1",
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/resolve": {
+ "version": "1.22.10",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
+ "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.16.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-dir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
+ "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "expand-tilde": "^2.0.0",
+ "global-modules": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+ "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/resolve-options": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-2.0.0.tgz",
+ "integrity": "sha512-/FopbmmFOQCfsCx77BRFdKOniglTiHumLgwvd6IDPihy1GKkadZbgQJBcTb2lMzSR1pndzd96b1nZrreZ7+9/A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "value-or-function": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/resp-modifier": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/resp-modifier/-/resp-modifier-6.0.2.tgz",
+ "integrity": "sha512-U1+0kWC/+4ncRFYqQWTx/3qkfE6a4B/h3XXgmXypfa0SPZ3t7cbbaFk297PjQS/yov24R18h6OZe6iZwj3NSLw==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^2.2.0",
+ "minimatch": "^3.0.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/retry": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
+ "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ripemd160": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+ "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/rx": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz",
+ "integrity": "sha512-CiaiuN6gapkdl+cZUr67W6I8jquN4lkak3vtIsIWCl4XIPP8ffsoyN6/+PuGXnQy8Cu8W2y9Xxh31Rq4M6wUug==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/safe-regex-test": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+ "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-regex": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/semver": {
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/semver-greatest-satisfied-range": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-2.0.0.tgz",
+ "integrity": "sha512-lH3f6kMbwyANB7HuOWRMlLCa2itaCrZJ+SAqqkSZrZKO/cAsk2EOyaKHUtNkVLFyFW9pct22SFesFp3Z7zpA0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sver": "^1.8.3"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/send": {
+ "version": "0.16.2",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
+ "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "destroy": "~1.0.4",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "~1.6.2",
+ "mime": "1.4.1",
+ "ms": "2.0.0",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.2.0",
+ "statuses": "~1.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/send/node_modules/depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/send/node_modules/http-errors": {
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+ "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.0",
+ "statuses": ">= 1.4.0 < 2"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/send/node_modules/inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/send/node_modules/setprototypeof": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/send/node_modules/statuses": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
+ "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/serve-index": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
+ "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "~1.3.4",
+ "batch": "0.6.1",
+ "debug": "2.6.9",
+ "escape-html": "~1.0.3",
+ "http-errors": "~1.6.2",
+ "mime-types": "~2.1.17",
+ "parseurl": "~1.3.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/serve-index/node_modules/depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/serve-index/node_modules/http-errors": {
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+ "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.0",
+ "statuses": ">= 1.4.0 < 2"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/serve-index/node_modules/inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/serve-index/node_modules/setprototypeof": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/serve-index/node_modules/statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/serve-static": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
+ "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.2",
+ "send": "0.16.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/server-destroy": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz",
+ "integrity": "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/sha.js": {
+ "version": "2.4.11",
+ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+ "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+ "dev": true,
+ "license": "(MIT AND BSD-3-Clause)",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ },
+ "bin": {
+ "sha.js": "bin.js"
+ }
+ },
+ "node_modules/shasum-object": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shasum-object/-/shasum-object-1.0.0.tgz",
+ "integrity": "sha512-Iqo5rp/3xVi6M4YheapzZhhGPVs0yZwHj7wvwQ1B9z8H6zk+FEnI7y3Teq7qwnekfEhu8WmG2z0z4iWZaxLWVg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "fast-safe-stringify": "^2.0.7"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shell-quote": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz",
+ "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/simple-concat": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/simple-get": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
+ "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "decompress-response": "^6.0.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ }
+ },
+ "node_modules/sinon": {
+ "version": "18.0.0",
+ "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.0.tgz",
+ "integrity": "sha512-+dXDXzD1sBO6HlmZDd7mXZCR/y5ECiEiGCBSGuFD/kZ0bDTofPYc6JaeGmPSF+1j1MejGUWkORbYOLDyvqCWpA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.1",
+ "@sinonjs/fake-timers": "^11.2.2",
+ "@sinonjs/samsam": "^8.0.0",
+ "diff": "^5.2.0",
+ "nise": "^6.0.0",
+ "supports-color": "^7"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/sinon"
+ }
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/smart-buffer": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
+ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/socket.io": {
+ "version": "4.8.1",
+ "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz",
+ "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "~1.3.4",
+ "base64id": "~2.0.0",
+ "cors": "~2.8.5",
+ "debug": "~4.3.2",
+ "engine.io": "~6.6.0",
+ "socket.io-adapter": "~2.5.2",
+ "socket.io-parser": "~4.2.4"
+ },
+ "engines": {
+ "node": ">=10.2.0"
+ }
+ },
+ "node_modules/socket.io-adapter": {
+ "version": "2.5.5",
+ "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz",
+ "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "~4.3.4",
+ "ws": "~8.17.1"
+ }
+ },
+ "node_modules/socket.io-adapter/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/socket.io-adapter/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/socket.io-client": {
+ "version": "4.8.1",
+ "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz",
+ "integrity": "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@socket.io/component-emitter": "~3.1.0",
+ "debug": "~4.3.2",
+ "engine.io-client": "~6.6.1",
+ "socket.io-parser": "~4.2.4"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/socket.io-client/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/socket.io-client/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/socket.io-parser": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
+ "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@socket.io/component-emitter": "~3.1.0",
+ "debug": "~4.3.1"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/socket.io-parser/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/socket.io-parser/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/socket.io/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/socket.io/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/socks": {
+ "version": "2.8.4",
+ "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.4.tgz",
+ "integrity": "sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ip-address": "^9.0.5",
+ "smart-buffer": "^4.2.0"
+ },
+ "engines": {
+ "node": ">= 10.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/socks-proxy-agent": {
+ "version": "8.0.5",
+ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz",
+ "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "^4.3.4",
+ "socks": "^2.8.3"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/socks-proxy-agent/node_modules/debug": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/socks-proxy-agent/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/source-map-support/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/sparkles": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-2.1.0.tgz",
+ "integrity": "sha512-r7iW1bDw8R/cFifrD3JnQJX0K1jqT0kprL48BiBpLZLJPmAm34zsVBsK5lc7HirZYZqMW65dOXZgbAGt/I6frg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/ssri": {
+ "version": "10.0.6",
+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz",
+ "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==",
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/statuses": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+ "integrity": "sha512-wuTCPGlJONk/a1kqZ4fQM2+908lC7fa7nPYpTC1EhnvqLX/IICbeP1OZGDtA374trpSq68YubKUMo8oRhN46yg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/stream-browserify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz",
+ "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "~2.0.4",
+ "readable-stream": "^3.5.0"
+ }
+ },
+ "node_modules/stream-browserify/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/stream-combiner2": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz",
+ "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "duplexer2": "~0.1.0",
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "node_modules/stream-composer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/stream-composer/-/stream-composer-1.0.2.tgz",
+ "integrity": "sha512-bnBselmwfX5K10AH6L4c8+S5lgZMWI7ZYrz2rvYjCPB2DIMC4Ig8OpxGpNJSxRZ58oti7y1IcNvjBAz9vW5m4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "streamx": "^2.13.2"
+ }
+ },
+ "node_modules/stream-exhaust": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz",
+ "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/stream-http": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz",
+ "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "builtin-status-codes": "^3.0.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.6.0",
+ "xtend": "^4.0.2"
+ }
+ },
+ "node_modules/stream-http/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/stream-splicer": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.1.tgz",
+ "integrity": "sha512-Xizh4/NPuYSyAXyT7g8IvdJ9HJpxIGL9PjyhtywCZvvP0OPIdqyrr4dMikeuvY8xahpdKEBlBTySe583totajg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "node_modules/stream-throttle": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/stream-throttle/-/stream-throttle-0.1.3.tgz",
+ "integrity": "sha512-889+B9vN9dq7/vLbGyuHeZ6/ctf5sNuGWsDy89uNxkFTAgzy0eK7+w5fL3KLNRTkLle7EgZGvHUphZW0Q26MnQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "commander": "^2.2.0",
+ "limiter": "^1.0.5"
+ },
+ "bin": {
+ "throttleproxy": "bin/throttleproxy.js"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/stream-throttle/node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/streamx": {
+ "version": "2.22.0",
+ "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.0.tgz",
+ "integrity": "sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==",
+ "license": "MIT",
+ "dependencies": {
+ "fast-fifo": "^1.3.2",
+ "text-decoder": "^1.1.0"
+ },
+ "optionalDependencies": {
+ "bare-events": "^2.2.0"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/subarg": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz",
+ "integrity": "sha512-RIrIdRY0X1xojthNcVtgT9sjpOGagEUKpZdgBUi054OEPFo282yg+zE+t1Rj3+RqKq2xStL7uUHhY+AjbC4BXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.1.0"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/sver": {
+ "version": "1.8.4",
+ "resolved": "https://registry.npmjs.org/sver/-/sver-1.8.4.tgz",
+ "integrity": "sha512-71o1zfzyawLfIWBOmw8brleKyvnbn73oVHNCsu51uPMz/HWiKkkXsI31JjHW5zqXEqnPYkIiHd8ZmL7FCimLEA==",
+ "dev": true,
+ "license": "MIT",
+ "optionalDependencies": {
+ "semver": "^6.3.0"
+ }
+ },
+ "node_modules/sver/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "optional": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/syntax-error": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz",
+ "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn-node": "^1.2.0"
+ }
+ },
+ "node_modules/tar": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
+ "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
+ "license": "ISC",
+ "dependencies": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^5.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/tar-fs": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz",
+ "integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==",
+ "license": "MIT",
+ "dependencies": {
+ "chownr": "^1.1.1",
+ "mkdirp-classic": "^0.5.2",
+ "pump": "^3.0.0",
+ "tar-stream": "^2.1.4"
+ }
+ },
+ "node_modules/tar-fs/node_modules/chownr": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+ "license": "ISC"
+ },
+ "node_modules/tar-stream": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
+ "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+ "license": "MIT",
+ "dependencies": {
+ "bl": "^4.0.3",
+ "end-of-stream": "^1.4.1",
+ "fs-constants": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.1.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/tar-stream/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/tar/node_modules/fs-minipass": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/tar/node_modules/minipass": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
+ "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/teex": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz",
+ "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "streamx": "^2.12.5"
+ }
+ },
+ "node_modules/terser": {
+ "version": "5.39.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz",
+ "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.8.2",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/terser/node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/test-exclude": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz",
+ "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^10.4.1",
+ "minimatch": "^9.0.4"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/test-exclude/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/test-exclude/node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/test-exclude/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/text-decoder": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz",
+ "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "b4a": "^1.6.4"
+ }
+ },
+ "node_modules/textextensions": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-3.3.0.tgz",
+ "integrity": "sha512-mk82dS8eRABNbeVJrEiN5/UMSCliINAuz8mkUwH4SwslkNP//gbEzlWNS5au0z5Dpx40SQxzqZevZkn+WYJ9Dw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://bevry.me/fund"
+ }
+ },
+ "node_modules/through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/through2": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+ "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "~2.3.6",
+ "xtend": "~4.0.1"
+ }
+ },
+ "node_modules/time-stamp": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz",
+ "integrity": "sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/timers-browserify": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz",
+ "integrity": "sha512-PIxwAupJZiYU4JmVZYwXp9FKsHMXb5h0ZEFyuXTAn8WLHOlcij+FEcbrvDsom1o5dr1YggEtFbECvGCW2sT53Q==",
+ "dev": true,
+ "dependencies": {
+ "process": "~0.11.0"
+ },
+ "engines": {
+ "node": ">=0.6.0"
+ }
+ },
+ "node_modules/tiny-glob": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz",
+ "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "globalyzer": "0.1.0",
+ "globrex": "^0.1.2"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/to-through": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/to-through/-/to-through-3.0.0.tgz",
+ "integrity": "sha512-y8MN937s/HVhEoBU1SxfHC+wxCHkV1a9gW8eAdTadYh/bGyesZIVcbjI+mSpFbSVwQici/XjBjuUyri1dnXwBw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "streamx": "^2.12.5"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/tty-browserify": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz",
+ "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ua-parser-js": {
+ "version": "1.0.40",
+ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.40.tgz",
+ "integrity": "sha512-z6PJ8Lml+v3ichVojCiB8toQJBuwR42ySM4ezjXIqXK3M0HczmKQ3LF4rhU55PfD99KEEXQG6yb7iOMyvYuHew==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/ua-parser-js"
+ },
+ {
+ "type": "paypal",
+ "url": "https://paypal.me/faisalman"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/faisalman"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "ua-parser-js": "script/cli.js"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/umd": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz",
+ "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "umd": "bin/cli.js"
+ }
+ },
+ "node_modules/unc-path-regex": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
+ "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/undeclared-identifiers": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz",
+ "integrity": "sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "acorn-node": "^1.3.0",
+ "dash-ast": "^1.0.0",
+ "get-assigned-identifiers": "^1.2.0",
+ "simple-concat": "^1.0.0",
+ "xtend": "^4.0.1"
+ },
+ "bin": {
+ "undeclared-identifiers": "bin.js"
+ }
+ },
+ "node_modules/undertaker": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-2.0.0.tgz",
+ "integrity": "sha512-tO/bf30wBbTsJ7go80j0RzA2rcwX6o7XPBpeFcb+jzoeb4pfMM2zUeSDIkY1AWqeZabWxaQZ/h8N9t35QKDLPQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bach": "^2.0.1",
+ "fast-levenshtein": "^3.0.0",
+ "last-run": "^2.0.0",
+ "undertaker-registry": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/undertaker-registry": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-2.0.0.tgz",
+ "integrity": "sha512-+hhVICbnp+rlzZMgxXenpvTxpuvA67Bfgtt+O9WOE5jo7w/dyiF1VmoZVIHvP2EkUjsyKyTwYKlLhA+j47m1Ew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "6.20.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
+ "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/unique-filename": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz",
+ "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==",
+ "license": "ISC",
+ "dependencies": {
+ "unique-slug": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/unique-slug": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz",
+ "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==",
+ "license": "ISC",
+ "dependencies": {
+ "imurmurhash": "^0.1.4"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/url": {
+ "version": "0.11.4",
+ "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz",
+ "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^1.4.1",
+ "qs": "^6.12.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/util": {
+ "version": "0.12.5",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
+ "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "is-arguments": "^1.0.4",
+ "is-generator-function": "^1.0.7",
+ "is-typed-array": "^1.1.3",
+ "which-typed-array": "^1.1.2"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "license": "MIT"
+ },
+ "node_modules/utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/v8-to-istanbul": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
+ "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.12",
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.12.0"
+ }
+ },
+ "node_modules/v8-to-istanbul/node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/v8flags": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-4.0.1.tgz",
+ "integrity": "sha512-fcRLaS4H/hrZk9hYwbdRM35D0U8IYMfEClhXxCivOojl+yTRAZH3Zy2sSy6qVCiGbV9YAtPssP6jaChqC9vPCg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/value-or-function": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-4.0.0.tgz",
+ "integrity": "sha512-aeVK81SIuT6aMJfNo9Vte8Dw0/FZINGBV8BfCraGtqVxIeLAEhJyoWs8SmvRVmXfGss2PmmOwZCuBPbZR+IYWg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/vinyl": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz",
+ "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "clone": "^2.1.1",
+ "clone-buffer": "^1.0.0",
+ "clone-stats": "^1.0.0",
+ "cloneable-readable": "^1.0.0",
+ "remove-trailing-separator": "^1.0.1",
+ "replace-ext": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/vinyl-buffer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/vinyl-buffer/-/vinyl-buffer-1.0.1.tgz",
+ "integrity": "sha512-LRBE2/g3C1hSHL2k/FynSZcVTRhEw8sb08oKGt/0hukZXwrh2m8nfy+r5yLhGEk7eFFuclhyIuPct/Bxlxk6rg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bl": "^1.2.1",
+ "through2": "^2.0.3"
+ }
+ },
+ "node_modules/vinyl-buffer/node_modules/bl": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz",
+ "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "^2.3.5",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/vinyl-contents": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl-contents/-/vinyl-contents-2.0.0.tgz",
+ "integrity": "sha512-cHq6NnGyi2pZ7xwdHSW1v4Jfnho4TEGtxZHw01cmnc8+i7jgR6bRnED/LbrKan/Q7CvVLbnvA5OepnhbpjBZ5Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bl": "^5.0.0",
+ "vinyl": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/vinyl-contents/node_modules/bl": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz",
+ "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer": "^6.0.3",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "node_modules/vinyl-contents/node_modules/buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
+ "node_modules/vinyl-contents/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/vinyl-contents/node_modules/replace-ext": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz",
+ "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/vinyl-contents/node_modules/vinyl": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz",
+ "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "clone": "^2.1.2",
+ "clone-stats": "^1.0.0",
+ "remove-trailing-separator": "^1.1.0",
+ "replace-ext": "^2.0.0",
+ "teex": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/vinyl-fs": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-4.0.0.tgz",
+ "integrity": "sha512-7GbgBnYfaquMk3Qu9g22x000vbYkOex32930rBnc3qByw6HfMEAoELjCjoJv4HuEQxHAurT+nvMHm6MnJllFLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fs-mkdirp-stream": "^2.0.1",
+ "glob-stream": "^8.0.0",
+ "graceful-fs": "^4.2.11",
+ "iconv-lite": "^0.6.3",
+ "is-valid-glob": "^1.0.0",
+ "lead": "^4.0.0",
+ "normalize-path": "3.0.0",
+ "resolve-options": "^2.0.0",
+ "stream-composer": "^1.0.2",
+ "streamx": "^2.14.0",
+ "to-through": "^3.0.0",
+ "value-or-function": "^4.0.0",
+ "vinyl": "^3.0.0",
+ "vinyl-sourcemap": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/vinyl-fs/node_modules/replace-ext": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz",
+ "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/vinyl-fs/node_modules/vinyl": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz",
+ "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "clone": "^2.1.2",
+ "clone-stats": "^1.0.0",
+ "remove-trailing-separator": "^1.1.0",
+ "replace-ext": "^2.0.0",
+ "teex": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/vinyl-source-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl-source-stream/-/vinyl-source-stream-2.0.0.tgz",
+ "integrity": "sha512-Y5f1wRGajOfYukhv8biIGA7iZiY8UOIc3zJ6zcUNIbRG1BVuXzBsfSfe7MUJTttVkuy64k/pGQtJdd/aIt+hbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "through2": "^2.0.3",
+ "vinyl": "^2.1.0"
+ }
+ },
+ "node_modules/vinyl-sourcemap": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-2.0.0.tgz",
+ "integrity": "sha512-BAEvWxbBUXvlNoFQVFVHpybBbjW1r03WhohJzJDSfgrrK5xVYIDTan6xN14DlyImShgDRv2gl9qhM6irVMsV0Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "convert-source-map": "^2.0.0",
+ "graceful-fs": "^4.2.10",
+ "now-and-later": "^3.0.0",
+ "streamx": "^2.12.5",
+ "vinyl": "^3.0.0",
+ "vinyl-contents": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/vinyl-sourcemap/node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/vinyl-sourcemap/node_modules/replace-ext": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz",
+ "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/vinyl-sourcemap/node_modules/vinyl": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz",
+ "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "clone": "^2.1.2",
+ "clone-stats": "^1.0.0",
+ "remove-trailing-separator": "^1.1.0",
+ "replace-ext": "^2.0.0",
+ "teex": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/vinyl-sourcemaps-apply": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz",
+ "integrity": "sha512-+oDh3KYZBoZC8hfocrbrxbLUeaYtQK7J5WU5Br9VqWqmCll3tFJqKp97GC9GmMsVIL0qnx2DgEDVxdo5EZ5sSw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "source-map": "^0.5.1"
+ }
+ },
+ "node_modules/vm-browserify": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
+ "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/webgpu": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/webgpu/-/webgpu-0.2.9.tgz",
+ "integrity": "sha512-3Qbbz6ido0YCRA55u1NhUe8rlcjxLWcSmoTVU4MIbxI8YbHiSrhUnJ1we2ySIal4co7e+Gd8ffL3hHXebvpehw==",
+ "license": "MIT",
+ "dependencies": {
+ "@webgpu/types": "^0.1.54"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.18",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz",
+ "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "license": "ISC"
+ },
+ "node_modules/ws": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
+ "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/xmlhttprequest-ssl": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz",
+ "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "license": "ISC"
+ },
+ "node_modules/yargs": {
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
index 5bcef9c1..b71cd989 100644
--- a/package.json
+++ b/package.json
@@ -1,41 +1,57 @@
{
"name": "gpu.js",
- "version": "1.0.0-rc.8",
+ "version": "2.16.0",
"description": "GPU Accelerated JavaScript",
- "main": "./dist/index.js",
+ "engines": {
+ "node": ">=8.0.0"
+ },
+ "main": "./src/index.js",
+ "files": [
+ "src",
+ "dist"
+ ],
+ "unpkg": "./dist/gpu-browser.js",
+ "jsdelivr": "./dist/gpu-browser.js",
+ "browser": "./dist/gpu-browser.js",
"directories": {
"doc": "doc",
"test": "test"
},
- "dependencies": { "acorn": "^5.1.1" },
+ "dependencies": {
+ "acorn": "8.14.0",
+ "gl": "8.1.6",
+ "gl-wiretap": "0.6.2",
+ "gpu-mock.js": "github:weagle08/gpu-mock.js",
+ "ordered-read-streams": "^2.0.0",
+ "webgpu": "0.2.9"
+ },
"devDependencies": {
- "babel-plugin-syntax-async-functions": "^6.5.0",
- "babel-preset-env": "^1.5.2",
- "browser-sync": "^2.18.2",
- "browserify": "^14.3.0",
- "del": "^3.0.0",
- "docdash": "^0.4.0",
- "gulp": "^3.9.1",
- "gulp-babel": "^6.1.2",
- "gulp-concat": "^2.6.0",
- "gulp-header": "^1.7.1",
- "gulp-jsbeautifier": "^2.1.0",
- "gulp-rename": "^1.2.2",
- "gulp-strip-comments": "^2.4.5",
- "gulp-uglify": "^1.5.2",
- "gulp-util": "^3.0.7",
- "jsdoc": "^3.5.0",
- "merge-stream": "^1.0.1",
- "qunit-assert-close": "^2.1.2",
- "qunitjs": "^2.3.2",
- "vinyl-buffer": "^1.0.0",
- "vinyl-source-stream": "^1.1.0"
+ "benchmark": "2.1.4",
+ "browser-sync": "3.0.2",
+ "browserify": "17.0.0",
+ "c8": "10.1.2",
+ "gulp": "5.0.0",
+ "gulp-concat": "2.6.1",
+ "gulp-header": "2.0.9",
+ "gulp-jsbeautifier": "3.0.1",
+ "gulp-rename": "2.0.0",
+ "gulp-replace": "1.1.4",
+ "gulp-strip-comments": "2.6.0",
+ "gulp-uglify-es": "3.0.0",
+ "merge-stream": "2.0.0",
+ "qunit": "2.22.0",
+ "read-dir-deep": "8.0.0",
+ "sinon": "18.0.0",
+ "vinyl-buffer": "1.0.1",
+ "vinyl-source-stream": "2.0.0"
},
"scripts": {
- "test": "echo \"Error: no test specified\" && exit 1",
+ "test": "qunit test/issues test/internal test/features",
+ "coverage": "c8 qunit test/issues test/internal test/features",
"setup": "npm i -g gulp-cli",
- "build-docs": "./node_modules/.bin/jsdoc -c jsdoc.json src -r -d doc --debug && gulp injectCSS",
- "make": "gulp build && gulp beautify && gulp minify"
+ "make": "gulp make",
+ "build": "gulp build",
+ "docs": "doxdox ./src --layout bootstrap --output docs.html"
},
"repository": {
"type": "git",
@@ -50,5 +66,6 @@
"bugs": {
"url": "https://github.com/gpujs/gpu.js/issues"
},
- "homepage": "http://gpu.rocks/"
+ "homepage": "http://gpu.rocks/",
+ "typings": "./src/index.d.ts"
}
diff --git a/src/alias.js b/src/alias.js
new file mode 100644
index 00000000..4a279099
--- /dev/null
+++ b/src/alias.js
@@ -0,0 +1,18 @@
+const { utils } = require('./utils');
+
+/**
+ *
+ * @param name
+ * @param source
+ * @returns {Function}
+ */
+function alias(name, source) {
+ const fnString = source.toString();
+ return new Function(`return function ${ name } (${ utils.getArgumentNamesFromString(fnString).join(', ') }) {
+ ${ utils.getFunctionBodyFromString(fnString) }
+}`)();
+}
+
+module.exports = {
+ alias
+};
\ No newline at end of file
diff --git a/src/backend/cpu/function-builder.js b/src/backend/cpu/function-builder.js
deleted file mode 100644
index 8dcc6eae..00000000
--- a/src/backend/cpu/function-builder.js
+++ /dev/null
@@ -1,21 +0,0 @@
-'use strict';
-
-const FunctionBuilderBase = require('../function-builder-base');
-const CPUFunctionNode = require('./function-node');
-
-/**
- * @class CPUFunctionBuilder
- *
- * @extends FunctionBuilderBase
- *
- * @desc Builds functions to execute on CPU from JavaScript function Strings
- *
- */
-module.exports = class CPUFunctionBuilder extends FunctionBuilderBase {
- constructor() {
- super();
- this.Node = CPUFunctionNode;
- }
-
- polyfillStandardFunctions() {}
-};
\ No newline at end of file
diff --git a/src/backend/cpu/function-node.js b/src/backend/cpu/function-node.js
index 7ec9cfb0..aa037507 100644
--- a/src/backend/cpu/function-node.js
+++ b/src/backend/cpu/function-node.js
@@ -1,1006 +1,668 @@
-'use strict';
-
-const BaseFunctionNode = require('../function-node-base');
-const utils = require('../../core/utils');
+const { FunctionNode } = require('../function-node');
/**
- * @class CPUFunctionNode
- *
- * @extends BaseFunctionNode
- *
- * @desc [INTERNAL] Represents a single function, inside JS, webGL, or openGL.
+ * @desc [INTERNAL] Represents a single function, inside JS
*
* This handles all the raw state, converted state, etc. Of a single function.
- *
- * @prop functionName - {String} Name of the function
- * @prop jsFunction - {Function} The JS Function the node represents
- * @prop jsFunctionString - {String} jsFunction.toString()
- * @prop paramNames - {String[]} Parameter names of the function
- * @prop paramTypes - {String[]} Shader land parameters type assumption
- * @prop isRootKernel - {Boolean} Special indicator, for kernel function
- * @prop webglFunctionString - {String} webgl converted function string
- * @prop openglFunctionString - {String} opengl converted function string
- * @prop calledFunctions - {String[]} List of all the functions called
- * @prop initVariables - {String[]} List of variables initialized in the function
- * @prop readVariables - {String[]} List of variables read operations occur
- * @prop writeVariables - {String[]} List of variables write operations occur
- *
*/
-module.exports = class CPUFunctionNode extends BaseFunctionNode {
- generate() {
- if (this.debug) {
- console.log(this);
- }
- this.functionStringArray = this.astGeneric(this.getJsAST(), [], this);
- this.functionString = this.functionStringArray.join('').trim();
- return this.functionString;
- }
-
- /**
- * @memberOf CPUFunctionNode#
- * @function
- * @name getFunctionPrototypeString
- *
- * @desc Returns the converted JS function
- *
- * @returns {String} function string, result is cached under this.getFunctionPrototypeString
- *
- */
- getFunctionPrototypeString() {
- if (this.webGlFunctionPrototypeString) {
- return this.webGlFunctionPrototypeString;
- }
- return this.webGlFunctionPrototypeString = this.generate();
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astGeneric
- *
- * @desc Parses the abstract syntax tree for generically to its respective function
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {String} the prased openclgl string array
- */
- astGeneric(ast, retArr, funcParam) {
- if (ast === null) {
- throw this.astErrorOutput('NULL ast', ast, funcParam);
- } else {
- if (Array.isArray(ast)) {
- for (let i = 0; i < ast.length; i++) {
- this.astGeneric(ast[i], retArr, funcParam);
- }
- return retArr;
- }
-
- switch (ast.type) {
- case 'FunctionDeclaration':
- return this.astFunctionDeclaration(ast, retArr, funcParam);
- case 'FunctionExpression':
- return this.astFunctionExpression(ast, retArr, funcParam);
- case 'ReturnStatement':
- return this.astReturnStatement(ast, retArr, funcParam);
- case 'Literal':
- return this.astLiteral(ast, retArr, funcParam);
- case 'BinaryExpression':
- return this.astBinaryExpression(ast, retArr, funcParam);
- case 'Identifier':
- return this.astIdentifierExpression(ast, retArr, funcParam);
- case 'AssignmentExpression':
- return this.astAssignmentExpression(ast, retArr, funcParam);
- case 'ExpressionStatement':
- return this.astExpressionStatement(ast, retArr, funcParam);
- case 'EmptyStatement':
- return this.astEmptyStatement(ast, retArr, funcParam);
- case 'BlockStatement':
- return this.astBlockStatement(ast, retArr, funcParam);
- case 'IfStatement':
- return this.astIfStatement(ast, retArr, funcParam);
- case 'BreakStatement':
- return this.astBreakStatement(ast, retArr, funcParam);
- case 'ContinueStatement':
- return this.astContinueStatement(ast, retArr, funcParam);
- case 'ForStatement':
- return this.astForStatement(ast, retArr, funcParam);
- case 'WhileStatement':
- return this.astWhileStatement(ast, retArr, funcParam);
- case 'VariableDeclaration':
- return this.astVariableDeclaration(ast, retArr, funcParam);
- case 'VariableDeclarator':
- return this.astVariableDeclarator(ast, retArr, funcParam);
- case 'ThisExpression':
- return this.astThisExpression(ast, retArr, funcParam);
- case 'SequenceExpression':
- return this.astSequenceExpression(ast, retArr, funcParam);
- case 'UnaryExpression':
- return this.astUnaryExpression(ast, retArr, funcParam);
- case 'UpdateExpression':
- return this.astUpdateExpression(ast, retArr, funcParam);
- case 'LogicalExpression':
- return this.astLogicalExpression(ast, retArr, funcParam);
- case 'MemberExpression':
- return this.astMemberExpression(ast, retArr, funcParam);
- case 'CallExpression':
- return this.astCallExpression(ast, retArr, funcParam);
- case 'ArrayExpression':
- return this.astArrayExpression(ast, retArr, funcParam);
- case 'DebuggerStatement':
- return this.astDebuggerStatement(ast, retArr, funcParam);
- }
-
- throw this.astErrorOutput('Unknown ast type : ' + ast.type, ast, funcParam);
- }
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astFunctionDeclaration
- *
- * @desc Parses the abstract syntax tree for to its *named function declaration*
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astFunctionDeclaration(ast, retArr, funcParam) {
- if (this.addFunction) {
- this.addFunction(null, utils.getAstString(this.jsFunctionString, ast));
- }
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astFunctionPrototype
- * @static
- *
- * @desc Parses the abstract syntax tree for to its *named function prototype*
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- static astFunctionPrototype(ast, retArr, funcParam) {
- // Setup function return type and name
- if (funcParam.isRootKernel || funcParam.isSubKernel) {
- return retArr;
- }
-
- retArr.push(funcParam.returnType);
- retArr.push(' ');
- retArr.push(funcParam.functionName);
- retArr.push('(');
-
- // Arguments handling
- for (let i = 0; i < funcParam.paramNames.length; ++i) {
- if (i > 0) {
- retArr.push(', ');
- }
-
- retArr.push(funcParam.paramTypes[i]);
- retArr.push(' ');
- retArr.push('user_');
- retArr.push(funcParam.paramNames[i]);
- }
-
- retArr.push(');\n');
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astFunctionExpression
- *
- * @desc Parses the abstract syntax tree for to its *named function*
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astFunctionExpression(ast, retArr, funcParam) {
-
- // Setup function return type and name
- if (!funcParam.isRootKernel) {
- retArr.push('function');
- funcParam.kernalAst = ast;
- retArr.push(' ');
- retArr.push(funcParam.functionName);
- retArr.push('(');
-
- // Arguments handling
- for (let i = 0; i < funcParam.paramNames.length; ++i) {
- const paramName = funcParam.paramNames[i];
-
- if (i > 0) {
- retArr.push(', ');
- }
-
- retArr.push(' ');
- retArr.push('user_');
- retArr.push(paramName);
- }
-
- // Function opening
- retArr.push(') {\n');
- }
-
- // Body statement iteration
- for (let i = 0; i < ast.body.body.length; ++i) {
- this.astGeneric(ast.body.body[i], retArr, funcParam);
- retArr.push('\n');
- }
-
- if (!funcParam.isRootKernel) {
- // Function closing
- retArr.push('}\n');
- }
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astReturnStatement
- *
- * @desc Parses the abstract syntax tree for to *return* statement
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Object} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astReturnStatement(ast, retArr, funcParam) {
- if (funcParam.isRootKernel) {
- retArr.push('kernelResult = ');
- this.astGeneric(ast.argument, retArr, funcParam);
- retArr.push(';');
- } else if (funcParam.isSubKernel) {
- retArr.push(`${ funcParam.functionName }Result = `);
- this.astGeneric(ast.argument, retArr, funcParam);
- retArr.push(';');
- retArr.push(`return ${ funcParam.functionName }Result;`);
- } else {
- retArr.push('return ');
- this.astGeneric(ast.argument, retArr, funcParam);
- retArr.push(';');
- }
-
- //throw this.astErrorOutput(
- // 'Non main function return, is not supported : '+funcParam.currentFunctionNamespace,
- // ast, funcParam
- //);
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astLiteral
- *
- * @desc Parses the abstract syntax tree for *literal value*
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astLiteral(ast, retArr, funcParam) {
-
- // Reject non numeric literals
- if (isNaN(ast.value)) {
- throw this.astErrorOutput(
- 'Non-numeric literal not supported : ' + ast.value,
- ast, funcParam
- );
- }
-
- retArr.push(ast.value);
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astBinaryExpression
- *
- * @desc Parses the abstract syntax tree for *binary* expression
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astBinaryExpression(ast, retArr, funcParam) {
- retArr.push('(');
- this.astGeneric(ast.left, retArr, funcParam);
- retArr.push(ast.operator);
- this.astGeneric(ast.right, retArr, funcParam);
- retArr.push(')');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astIdentifierExpression
- *
- * @desc Parses the abstract syntax tree for *identifier* expression
- *
- * @param {Object} idtNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astIdentifierExpression(idtNode, retArr, funcParam) {
- if (idtNode.type !== 'Identifier') {
- throw this.astErrorOutput(
- 'IdentifierExpression - not an Identifier',
- ast, funcParam
- );
- }
-
- switch (idtNode.name) {
- case 'gpu_threadX':
- retArr.push('threadId.x');
- break;
- case 'gpu_threadY':
- retArr.push('threadId.y');
- break;
- case 'gpu_threadZ':
- retArr.push('threadId.z');
- break;
- case 'gpu_outputX':
- retArr.push('uOutputDim.x');
- break;
- case 'gpu_outputY':
- retArr.push('uOutputDim.y');
- break;
- case 'gpu_outputZ':
- retArr.push('uOutputDim.z');
- break;
- default:
- if (this.constants && this.constants.hasOwnProperty(idtNode.name)) {
- retArr.push('constants_' + idtNode.name);
- } else {
- const userParamName = funcParam.getUserParamName(idtNode.name);
- if (userParamName !== null) {
- retArr.push('user_' + userParamName);
- } else {
- retArr.push('user_' + idtNode.name);
- }
- }
- }
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astForStatement
- *
- * @desc Parses the abstract syntax tree forfor *for-loop* expression
- *
- * @param {Object} forNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {String} the prased openclgl string
- */
- astForStatement(forNode, retArr, funcParam) {
- if (forNode.type !== 'ForStatement') {
- throw this.astErrorOutput(
- 'Invalid for statment',
- ast, funcParam
- );
- }
-
- if (forNode.test && forNode.test.type === 'BinaryExpression') {
- if ((forNode.test.right.type === 'Identifier' || forNode.test.right.type === 'Literal') &&
- forNode.test.operator === '<' &&
- this.isIdentifierConstant(forNode.test.right.name) === false) {
-
- if (!this.loopMaxIterations) {
- console.warn('Warning: loopMaxIterations is not set! Using default of 1000 which may result in unintended behavior.');
- console.warn('Set loopMaxIterations or use a for loop of fixed length to silence this message.');
- }
-
- retArr.push('for (');
- this.astGeneric(forNode.init, retArr, funcParam);
- if (retArr[retArr.length - 1] !== ';') {
- retArr.push(';');
- }
- this.astGeneric(forNode.test.left, retArr, funcParam);
- retArr.push(forNode.test.operator);
- retArr.push('LOOP_MAX');
- retArr.push(';');
- this.astGeneric(forNode.update, retArr, funcParam);
- retArr.push(')');
-
- retArr.push('{\n');
- retArr.push('if (');
- this.astGeneric(forNode.test.left, retArr, funcParam);
- retArr.push(forNode.test.operator);
- this.astGeneric(forNode.test.right, retArr, funcParam);
- retArr.push(') {\n');
- if (forNode.body.type === 'BlockStatement') {
- for (let i = 0; i < forNode.body.body.length; i++) {
- this.astGeneric(forNode.body.body[i], retArr, funcParam);
- }
- } else {
- this.astGeneric(forNode.body, retArr, funcParam);
- }
- retArr.push('} else {\n');
- retArr.push('break;\n');
- retArr.push('}\n');
- retArr.push('}\n');
-
- return retArr;
- } else if (forNode.init.declarations) {
- const declarations = JSON.parse(JSON.stringify(forNode.init.declarations));
- const updateArgument = forNode.update.argument;
- if (!Array.isArray(declarations) || declarations.length < 1) {
- console.log(this.jsFunctionString);
- throw new Error('Error: Incompatible for loop declaration');
- }
-
- if (declarations.length > 1) {
- let initArgument = null;
- for (let i = 0; i < declarations.length; i++) {
- const declaration = declarations[i];
- if (declaration.id.name === updateArgument.name) {
- initArgument = declaration;
- declarations.splice(i, 1);
- } else {
- retArr.push('var ');
- this.astGeneric(declaration, retArr, funcParam);
- retArr.push(';');
- }
- }
-
- retArr.push('for (let ');
- this.astGeneric(initArgument, retArr, funcParam);
- retArr.push(';');
- } else {
- retArr.push('for (');
- this.astGeneric(forNode.init, retArr, funcParam);
- }
-
- this.astGeneric(forNode.test, retArr, funcParam);
- retArr.push(';');
- this.astGeneric(forNode.update, retArr, funcParam);
- retArr.push(')');
- this.astGeneric(forNode.body, retArr, funcParam);
- return retArr;
- }
- }
-
- throw this.astErrorOutput(
- 'Invalid for statement',
- forNode, funcParam
- );
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astWhileStatement
- *
- * @desc Parses the abstract syntax tree for *while* loop
- *
- *
- * @param {Object} whileNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {String} the parsed openclgl string
- */
- astWhileStatement(whileNode, retArr, funcParam) {
- if (whileNode.type !== 'WhileStatement') {
- throw this.astErrorOutput(
- 'Invalid while statment',
- ast, funcParam
- );
- }
-
- retArr.push('for (let i = 0; i < LOOP_MAX; i++) {');
- retArr.push('if (');
- this.astGeneric(whileNode.test, retArr, funcParam);
- retArr.push(') {\n');
- this.astGeneric(whileNode.body, retArr, funcParam);
- retArr.push('} else {\n');
- retArr.push('break;\n');
- retArr.push('}\n');
- retArr.push('}\n');
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astAssignmentExpression
- *
- * @desc Parses the abstract syntax tree for *Assignment* Expression
- *
- * @param {Object} assNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astAssignmentExpression(assNode, retArr, funcParam) {
- this.astGeneric(assNode.left, retArr, funcParam);
- retArr.push(assNode.operator);
- this.astGeneric(assNode.right, retArr, funcParam);
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astEmptyStatement
- *
- * @desc Parses the abstract syntax tree for an *Empty* Statement
- *
- * @param {Object} eNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astEmptyStatement(eNode, retArr, funcParam) {
- //retArr.push(';\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astBlockStatement
- *
- * @desc Parses the abstract syntax tree for *Block* statement
- *
- * @param {Object} bnode - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astBlockStatement(bNode, retArr, funcParam) {
- retArr.push('{\n');
- for (let i = 0; i < bNode.body.length; i++) {
- this.astGeneric(bNode.body[i], retArr, funcParam);
- }
- retArr.push('}\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astExpressionStatement
- *
- * @desc Parses the abstract syntax tree for *generic expression* statement
- *
- * @param {Object} esNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astExpressionStatement(esNode, retArr, funcParam) {
- this.astGeneric(esNode.expression, retArr, funcParam);
- retArr.push(';\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astVariableDeclaration
- *
- * @desc Parses the abstract syntax tree for *Variable Declaration*
- *
- * @param {Object} vardecNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astVariableDeclaration(vardecNode, retArr, funcParam) {
- retArr.push('var ');
- for (let i = 0; i < vardecNode.declarations.length; i++) {
- if (i > 0) {
- retArr.push(',');
- }
- this.astGeneric(vardecNode.declarations[i], retArr, funcParam);
- }
- retArr.push(';');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astVariableDeclarator
- *
- * @desc Parses the abstract syntax tree for *Variable Declarator*
- *
- * @param {Object} ivardecNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astVariableDeclarator(ivardecNode, retArr, funcParam) {
- this.astGeneric(ivardecNode.id, retArr, funcParam);
- if (ivardecNode.init !== null) {
- retArr.push('=');
- this.astGeneric(ivardecNode.init, retArr, funcParam);
- }
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astIfStatement
- *
- * @desc Parses the abstract syntax tree for *If* Statement
- *
- * @param {Object} ifNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astIfStatement(ifNode, retArr, funcParam) {
- retArr.push('if (');
- this.astGeneric(ifNode.test, retArr, funcParam);
- retArr.push(')');
- if (ifNode.consequent.type === 'BlockStatement') {
- this.astGeneric(ifNode.consequent, retArr, funcParam);
- } else {
- retArr.push(' {\n');
- this.astGeneric(ifNode.consequent, retArr, funcParam);
- retArr.push('\n}\n');
- }
-
- if (ifNode.alternate) {
- retArr.push('else ');
- if (ifNode.alternate.type === 'BlockStatement') {
- this.astGeneric(ifNode.alternate, retArr, funcParam);
- } else {
- retArr.push(' {\n');
- this.astGeneric(ifNode.alternate, retArr, funcParam);
- retArr.push('\n}\n');
- }
- }
- return retArr;
-
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astBreakStatement
- *
- * @desc Parses the abstract syntax tree for *Break* Statement
- *
- * @param {Object} brNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astBreakStatement(brNode, retArr, funcParam) {
- retArr.push('break;\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astContinueStatement
- *
- * @desc Parses the abstract syntax tree for *Continue* Statement
- *
- * @param {Object} crNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astContinueStatement(crNode, retArr, funcParam) {
- retArr.push('continue;\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astLogicalExpression
- *
- * @desc Parses the abstract syntax tree for *Logical* Expression
- *
- * @param {Object} logNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astLogicalExpression(logNode, retArr, funcParam) {
- retArr.push('(');
- this.astGeneric(logNode.left, retArr, funcParam);
- retArr.push(logNode.operator);
- this.astGeneric(logNode.right, retArr, funcParam);
- retArr.push(')');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astUpdateExpression
- *
- * @desc Parses the abstract syntax tree for *Update* Expression
- *
- * @param {Object} uNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astUpdateExpression(uNode, retArr, funcParam) {
- if (uNode.prefix) {
- retArr.push(uNode.operator);
- this.astGeneric(uNode.argument, retArr, funcParam);
- } else {
- this.astGeneric(uNode.argument, retArr, funcParam);
- retArr.push(uNode.operator);
- }
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astUnaryExpression
- *
- * @desc Parses the abstract syntax tree for *Unary* Expression
- *
- * @param {Object} uNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astUnaryExpression(uNode, retArr, funcParam) {
- if (uNode.prefix) {
- retArr.push(uNode.operator);
- this.astGeneric(uNode.argument, retArr, funcParam);
- } else {
- this.astGeneric(uNode.argument, retArr, funcParam);
- retArr.push(uNode.operator);
- }
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astThisExpression
- *
- * @desc Parses the abstract syntax tree for *This* expression
- *
- * @param {Object} tNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astThisExpression(tNode, retArr, funcParam) {
- retArr.push('_this');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astMemberExpression
- *
- * @desc Parses the abstract syntax tree for *Member* Expression
- *
- * @param {Object} mNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astMemberExpression(mNode, retArr, funcParam) {
- if (mNode.computed) {
- if (mNode.object.type === 'Identifier') {
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push('[');
- this.astGeneric(mNode.property, retArr, funcParam);
- retArr.push(']');
- } else {
- this.astGeneric(mNode.object, retArr, funcParam);
- const last = retArr.pop();
- retArr.push('][');
- this.astGeneric(mNode.property, retArr, funcParam);
- retArr.push(last);
- }
- } else {
- let unrolled = this.astMemberExpressionUnroll(mNode);
- if (mNode.property.type === 'Identifier' && mNode.computed) {
- unrolled = 'user_' + unrolled;
- }
-
- // Its a reference to `this`, add '_' before
- if (unrolled.indexOf('this') === 0) {
- unrolled = '_' + unrolled;
- }
-
- switch (unrolled) {
- case '_this.output.x':
- retArr.push(this.output[0]);
- break;
- case '_this.output.y':
- retArr.push(this.output[1]);
- break;
- case '_this.output.z':
- retArr.push(this.output[2]);
- break;
- default:
- retArr.push(unrolled);
- }
- }
- return retArr;
- }
-
- astSequenceExpression(sNode, retArr, funcParam) {
- for (let i = 0; i < sNode.expressions.length; i++) {
- if (i > 0) {
- retArr.push(',');
- }
- this.astGeneric(sNode.expressions, retArr, funcParam);
- }
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astCallExpression
- *
- * @desc Parses the abstract syntax tree for *call* expression
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astCallExpression(ast, retArr, funcParam) {
- if (ast.callee) {
- // Get the full function call, unrolled
- let funcName = this.astMemberExpressionUnroll(ast.callee);
-
- // Register the function into the called registry
- if (funcParam.calledFunctions.indexOf(funcName) < 0) {
- funcParam.calledFunctions.push(funcName);
- }
- if (!funcParam.hasOwnProperty('funcName')) {
- funcParam.calledFunctionsArguments[funcName] = [];
- }
-
- const functionArguments = [];
- funcParam.calledFunctionsArguments[funcName].push(functionArguments);
-
- // Call the function
- retArr.push(funcName);
-
- // Open arguments space
- retArr.push('(');
-
- // Add the vars
- for (let i = 0; i < ast.arguments.length; ++i) {
- const argument = ast.arguments[i];
- if (i > 0) {
- retArr.push(', ');
- }
- this.astGeneric(argument, retArr, funcParam);
- if (argument.type === 'Identifier') {
- const paramIndex = funcParam.paramNames.indexOf(argument.name);
- if (paramIndex === -1) {
- functionArguments.push(null);
- } else {
- functionArguments.push({
- name: argument.name,
- type: funcParam.paramTypes[paramIndex]
- });
- }
- } else {
- functionArguments.push(null);
- }
- }
-
- // Close arguments space
- retArr.push(')');
-
- return retArr;
- }
-
- // Failure, unknown expression
- throw this.astErrorOutput(
- 'Unknown CallExpression',
- ast, funcParam
- );
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astArrayExpression
- *
- * @desc Parses the abstract syntax tree for *Array* Expression
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astArrayExpression(arrNode, retArr, funcParam) {
- const arrLen = arrNode.elements.length;
-
- retArr.push('new Float32Array(');
- for (let i = 0; i < arrLen; ++i) {
- if (i > 0) {
- retArr.push(', ');
- }
- const subNode = arrNode.elements[i];
- this.astGeneric(subNode, retArr, funcParam)
- }
- retArr.push(')');
-
- return retArr;
-
- // // Failure, unknown expression
- // throw this.astErrorOutput(
- // 'Unknown ArrayExpression',
- // arrNode, funcParam
- //);
- }
-
- astDebuggerStatement(arrNode, retArr, funcParam) {
- retArr.push('debugger;');
- return retArr;
- }
+class CPUFunctionNode extends FunctionNode {
+ /**
+ * @desc Parses the abstract syntax tree for to its *named function*
+ * @param {Object} ast - the AST object to parse
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astFunction(ast, retArr) {
+
+ // Setup function return type and name
+ if (!this.isRootKernel) {
+ retArr.push('function');
+ retArr.push(' ');
+ retArr.push(this.name);
+ retArr.push('(');
+
+ // Arguments handling
+ for (let i = 0; i < this.argumentNames.length; ++i) {
+ const argumentName = this.argumentNames[i];
+
+ if (i > 0) {
+ retArr.push(', ');
+ }
+ retArr.push('user_');
+ retArr.push(argumentName);
+ }
+
+ // Function opening
+ retArr.push(') {\n');
+ }
+
+ // Body statement iteration
+ for (let i = 0; i < ast.body.body.length; ++i) {
+ this.astGeneric(ast.body.body[i], retArr);
+ retArr.push('\n');
+ }
+
+ if (!this.isRootKernel) {
+ // Function closing
+ retArr.push('}\n');
+ }
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for to *return* statement
+ * @param {Object} ast - the AST object to parse
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astReturnStatement(ast, retArr) {
+ const type = this.returnType || this.getType(ast.argument);
+
+ if (!this.returnType) {
+ this.returnType = type;
+ }
+
+ if (this.isRootKernel) {
+ retArr.push(this.leadingReturnStatement);
+ this.astGeneric(ast.argument, retArr);
+ retArr.push(';\n');
+ retArr.push(this.followingReturnStatement);
+ retArr.push('continue;\n');
+ } else if (this.isSubKernel) {
+ retArr.push(`subKernelResult_${ this.name } = `);
+ this.astGeneric(ast.argument, retArr);
+ retArr.push(';');
+ retArr.push(`return subKernelResult_${ this.name };`);
+ } else {
+ retArr.push('return ');
+ this.astGeneric(ast.argument, retArr);
+ retArr.push(';');
+ }
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *literal value*
+ * @param {Object} ast - the AST object to parse
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astLiteral(ast, retArr) {
+
+ // Reject non numeric literals
+ if (isNaN(ast.value)) {
+ throw this.astErrorOutput(
+ 'Non-numeric literal not supported : ' + ast.value,
+ ast
+ );
+ }
+
+ retArr.push(ast.value);
+
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *binary* expression
+ * @param {Object} ast - the AST object to parse
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astBinaryExpression(ast, retArr) {
+ retArr.push('(');
+ this.astGeneric(ast.left, retArr);
+ retArr.push(ast.operator);
+ this.astGeneric(ast.right, retArr);
+ retArr.push(')');
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *identifier* expression
+ * @param {Object} idtNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astIdentifierExpression(idtNode, retArr) {
+ if (idtNode.type !== 'Identifier') {
+ throw this.astErrorOutput(
+ 'IdentifierExpression - not an Identifier',
+ idtNode
+ );
+ }
+
+ switch (idtNode.name) {
+ case 'Infinity':
+ retArr.push('Infinity');
+ break;
+ default:
+ if (this.constants && this.constants.hasOwnProperty(idtNode.name)) {
+ retArr.push('constants_' + idtNode.name);
+ } else {
+ retArr.push('user_' + idtNode.name);
+ }
+ }
+
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *for-loop* expression
+ * @param {Object} forNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the parsed webgl string
+ */
+ 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) {
+ this.pushState('in-for-loop-init');
+ this.astGeneric(forNode.init, initArr);
+ for (let i = 0; i < initArr.length; i++) {
+ if (initArr[i].includes && initArr[i].includes(',')) {
+ isSafe = false;
+ }
+ }
+ this.popState('in-for-loop-init');
+ } else {
+ isSafe = false;
+ }
+
+ if (forNode.test) {
+ this.astGeneric(forNode.test, testArr);
+ } else {
+ isSafe = false;
+ }
+
+ if (forNode.update) {
+ this.astGeneric(forNode.update, updateArr);
+ } else {
+ isSafe = false;
+ }
+
+ if (forNode.body) {
+ this.pushState('loop-body');
+ this.astGeneric(forNode.body, bodyArr);
+ this.popState('loop-body');
+ }
+
+ // have all parts, now make them safe
+ if (isSafe === null) {
+ isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test);
+ }
+
+ if (isSafe) {
+ retArr.push(`for (${initArr.join('')};${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 (let ${iVariableName}=0;${iVariableName} 0) {
+ retArr.push(`if (!${testArr.join('')}) break;\n`);
+ }
+ retArr.push(bodyArr.join(''));
+ retArr.push(`\n${updateArr.join('')};`);
+ retArr.push('}\n');
+ }
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *while* loop
+ * @param {Object} whileNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the parsed javascript string
+ */
+ astWhileStatement(whileNode, retArr) {
+ if (whileNode.type !== 'WhileStatement') {
+ throw this.astErrorOutput(
+ 'Invalid while statement',
+ whileNode
+ );
+ }
+
+ retArr.push('for (let i = 0; i < LOOP_MAX; i++) {');
+ retArr.push('if (');
+ this.astGeneric(whileNode.test, retArr);
+ retArr.push(') {\n');
+ this.astGeneric(whileNode.body, retArr);
+ retArr.push('} else {\n');
+ retArr.push('break;\n');
+ retArr.push('}\n');
+ retArr.push('}\n');
+
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *do while* loop
+ * @param {Object} doWhileNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the parsed webgl string
+ */
+ astDoWhileStatement(doWhileNode, retArr) {
+ if (doWhileNode.type !== 'DoWhileStatement') {
+ throw this.astErrorOutput(
+ 'Invalid while statement',
+ doWhileNode
+ );
+ }
+
+ retArr.push('for (let i = 0; i < LOOP_MAX; i++) {');
+ this.astGeneric(doWhileNode.body, retArr);
+ retArr.push('if (!');
+ this.astGeneric(doWhileNode.test, retArr);
+ retArr.push(') {\n');
+ retArr.push('break;\n');
+ retArr.push('}\n');
+ retArr.push('}\n');
+
+ return retArr;
+
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *Assignment* Expression
+ * @param {Object} assNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astAssignmentExpression(assNode, retArr) {
+ const declaration = this.getDeclaration(assNode.left);
+ if (declaration && !declaration.assignable) {
+ throw this.astErrorOutput(`Variable ${assNode.left.name} is not assignable here`, assNode);
+ }
+ this.astGeneric(assNode.left, retArr);
+ retArr.push(assNode.operator);
+ this.astGeneric(assNode.right, retArr);
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *Block* statement
+ * @param {Object} bNode - the AST object to parse
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astBlockStatement(bNode, retArr) {
+ if (this.isState('loop-body')) {
+ this.pushState('block-body'); // this prevents recursive removal of braces
+ for (let i = 0; i < bNode.body.length; i++) {
+ this.astGeneric(bNode.body[i], retArr);
+ }
+ this.popState('block-body');
+ } else {
+ retArr.push('{\n');
+ for (let i = 0; i < bNode.body.length; i++) {
+ this.astGeneric(bNode.body[i], retArr);
+ }
+ retArr.push('}\n');
+ }
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *Variable Declaration*
+ * @param {Object} varDecNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astVariableDeclaration(varDecNode, retArr) {
+ retArr.push(`${varDecNode.kind} `);
+ const { declarations } = varDecNode;
+ for (let i = 0; i < declarations.length; i++) {
+ if (i > 0) {
+ retArr.push(',');
+ }
+ const declaration = declarations[i];
+ const info = this.getDeclaration(declaration.id);
+ if (!info.valueType) {
+ info.valueType = this.getType(declaration.init);
+ }
+ this.astGeneric(declaration, retArr);
+ }
+ if (!this.isState('in-for-loop-init')) {
+ retArr.push(';');
+ }
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *If* Statement
+ * @param {Object} ifNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astIfStatement(ifNode, retArr) {
+ retArr.push('if (');
+ this.astGeneric(ifNode.test, retArr);
+ retArr.push(')');
+ if (ifNode.consequent.type === 'BlockStatement') {
+ this.astGeneric(ifNode.consequent, retArr);
+ } else {
+ retArr.push(' {\n');
+ this.astGeneric(ifNode.consequent, retArr);
+ retArr.push('\n}\n');
+ }
+
+ if (ifNode.alternate) {
+ retArr.push('else ');
+ if (ifNode.alternate.type === 'BlockStatement' || ifNode.alternate.type === 'IfStatement') {
+ this.astGeneric(ifNode.alternate, retArr);
+ } else {
+ retArr.push(' {\n');
+ this.astGeneric(ifNode.alternate, retArr);
+ retArr.push('\n}\n');
+ }
+ }
+ return retArr;
+
+ }
+
+ astSwitchStatement(ast, retArr) {
+ const { discriminant, cases } = ast;
+ retArr.push('switch (');
+ this.astGeneric(discriminant, retArr);
+ retArr.push(') {\n');
+ for (let i = 0; i < cases.length; i++) {
+ if (cases[i].test === null) {
+ retArr.push('default:\n');
+ this.astGeneric(cases[i].consequent, retArr);
+ if (cases[i].consequent && cases[i].consequent.length > 0) {
+ retArr.push('break;\n');
+ }
+ continue;
+ }
+ retArr.push('case ');
+ this.astGeneric(cases[i].test, retArr);
+ retArr.push(':\n');
+ if (cases[i].consequent && cases[i].consequent.length > 0) {
+ this.astGeneric(cases[i].consequent, retArr);
+ retArr.push('break;\n');
+ }
+ }
+ retArr.push('\n}');
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *This* expression
+ * @param {Object} tNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astThisExpression(tNode, retArr) {
+ retArr.push('_this');
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *Member* Expression
+ * @param {Object} mNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astMemberExpression(mNode, retArr) {
+ const {
+ signature,
+ type,
+ property,
+ xProperty,
+ yProperty,
+ zProperty,
+ name,
+ origin
+ } = this.getMemberExpressionDetails(mNode);
+ switch (signature) {
+ case 'this.thread.value':
+ retArr.push(`_this.thread.${ name }`);
+ return retArr;
+ case 'this.output.value':
+ switch (name) {
+ case 'x':
+ retArr.push('outputX');
+ break;
+ case 'y':
+ retArr.push('outputY');
+ break;
+ case 'z':
+ retArr.push('outputZ');
+ break;
+ default:
+ throw this.astErrorOutput('Unexpected expression', mNode);
+ }
+ return retArr;
+ case 'value':
+ throw this.astErrorOutput('Unexpected expression', mNode);
+ case 'value[]':
+ case 'value[][]':
+ case 'value[][][]':
+ case 'value.value':
+ if (origin === 'Math') {
+ retArr.push(Math[name]);
+ return retArr;
+ }
+ switch (property) {
+ case 'r':
+ retArr.push(`user_${ name }[0]`);
+ return retArr;
+ case 'g':
+ retArr.push(`user_${ name }[1]`);
+ return retArr;
+ case 'b':
+ retArr.push(`user_${ name }[2]`);
+ return retArr;
+ case 'a':
+ retArr.push(`user_${ name }[3]`);
+ return retArr;
+ }
+ break;
+ case 'this.constants.value':
+ case 'this.constants.value[]':
+ case 'this.constants.value[][]':
+ case 'this.constants.value[][][]':
+ break;
+ case 'fn()[]':
+ this.astGeneric(mNode.object, retArr);
+ retArr.push('[');
+ this.astGeneric(mNode.property, retArr);
+ retArr.push(']');
+ return retArr;
+ case 'fn()[][]':
+ this.astGeneric(mNode.object.object, retArr);
+ retArr.push('[');
+ this.astGeneric(mNode.object.property, retArr);
+ retArr.push(']');
+ retArr.push('[');
+ this.astGeneric(mNode.property, retArr);
+ retArr.push(']');
+ return retArr;
+ default:
+ throw this.astErrorOutput('Unexpected expression', mNode);
+ }
+
+ if (!mNode.computed) {
+ // handle simple types
+ switch (type) {
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ case 'Boolean':
+ retArr.push(`${origin}_${name}`);
+ return retArr;
+ }
+ }
+
+ // handle more complex types
+ // argument may have come from a parent
+ const markupName = `${origin}_${name}`;
+
+ switch (type) {
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ case 'Matrix(2)':
+ case 'Matrix(3)':
+ case 'Matrix(4)':
+ case 'HTMLImageArray':
+ case 'ArrayTexture(1)':
+ case 'ArrayTexture(2)':
+ case 'ArrayTexture(3)':
+ case 'ArrayTexture(4)':
+ case 'HTMLImage':
+ default:
+ let size;
+ let isInput;
+ if (origin === 'constants') {
+ const constant = this.constants[name];
+ isInput = this.constantTypes[name] === 'Input';
+ size = isInput ? constant.size : null;
+ } else {
+ isInput = this.isInput(name);
+ size = isInput ? this.argumentSizes[this.argumentNames.indexOf(name)] : null;
+ }
+ retArr.push(`${ markupName }`);
+ if (zProperty && yProperty) {
+ if (isInput) {
+ retArr.push('[(');
+ this.astGeneric(zProperty, retArr);
+ retArr.push(`*${ this.dynamicArguments ? '(outputY * outputX)' : size[1] * size[0] })+(`);
+ this.astGeneric(yProperty, retArr);
+ retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`);
+ this.astGeneric(xProperty, retArr);
+ retArr.push(']');
+ } else {
+ retArr.push('[');
+ this.astGeneric(zProperty, retArr);
+ retArr.push(']');
+ retArr.push('[');
+ this.astGeneric(yProperty, retArr);
+ retArr.push(']');
+ retArr.push('[');
+ this.astGeneric(xProperty, retArr);
+ retArr.push(']');
+ }
+ } else if (yProperty) {
+ if (isInput) {
+ retArr.push('[(');
+ this.astGeneric(yProperty, retArr);
+ retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`);
+ this.astGeneric(xProperty, retArr);
+ retArr.push(']');
+ } else {
+ retArr.push('[');
+ this.astGeneric(yProperty, retArr);
+ retArr.push(']');
+ retArr.push('[');
+ this.astGeneric(xProperty, retArr);
+ retArr.push(']');
+ }
+ } else if (typeof xProperty !== 'undefined') {
+ retArr.push('[');
+ this.astGeneric(xProperty, retArr);
+ retArr.push(']');
+ }
+ }
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *call* expression
+ * @param {Object} ast - the AST object to parse
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astCallExpression(ast, retArr) {
+ if (ast.type !== 'CallExpression') {
+ // Failure, unknown expression
+ throw this.astErrorOutput('Unknown CallExpression', ast);
+ }
+ // Get the full function call, unrolled
+ let functionName = this.astMemberExpressionUnroll(ast.callee);
+
+ // Register the function into the called registry
+ if (this.calledFunctions.indexOf(functionName) < 0) {
+ this.calledFunctions.push(functionName);
+ }
+
+ const isMathFunction = this.isAstMathFunction(ast);
+
+ // track the function was called
+ if (this.onFunctionCall) {
+ this.onFunctionCall(this.name, functionName, ast.arguments);
+ }
+
+ // Call the function
+ retArr.push(functionName);
+
+ // Open arguments space
+ retArr.push('(');
+ const targetTypes = this.lookupFunctionArgumentTypes(functionName) || [];
+ // Add the arguments
+ for (let i = 0; i < ast.arguments.length; ++i) {
+ const argument = ast.arguments[i];
+
+ // in order to track return type, even though this is CPU
+ let argumentType = this.getType(argument);
+ if (!targetTypes[i]) {
+ this.triggerImplyArgumentType(functionName, i, argumentType, this);
+ }
+
+ if (i > 0) {
+ retArr.push(', ');
+ }
+ this.astGeneric(argument, retArr);
+ }
+ // Close arguments space
+ retArr.push(')');
+
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *Array* Expression
+ * @param {Object} arrNode - the AST object to parse
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astArrayExpression(arrNode, retArr) {
+ const returnType = this.getType(arrNode);
+ const arrLen = arrNode.elements.length;
+ const elements = [];
+ for (let i = 0; i < arrLen; ++i) {
+ const element = [];
+ this.astGeneric(arrNode.elements[i], element);
+ elements.push(element.join(''));
+ }
+ switch (returnType) {
+ case 'Matrix(2)':
+ case 'Matrix(3)':
+ case 'Matrix(4)':
+ retArr.push(`[${elements.join(', ')}]`);
+ break;
+ default:
+ retArr.push(`new Float32Array([${elements.join(', ')}])`);
+ }
+ return retArr;
+ }
+
+ astDebuggerStatement(arrNode, retArr) {
+ retArr.push('debugger;');
+ return retArr;
+ }
+}
+
+module.exports = {
+ CPUFunctionNode
};
\ No newline at end of file
diff --git a/src/backend/cpu/kernel-string.js b/src/backend/cpu/kernel-string.js
index 41564be4..d619b477 100644
--- a/src/backend/cpu/kernel-string.js
+++ b/src/backend/cpu/kernel-string.js
@@ -1,54 +1,185 @@
-'use strict';
-
-const utils = require('../../core/utils');
-const kernelRunShortcut = require('../kernel-run-shortcut');
-
-module.exports = function(cpuKernel, name) {
- return `() => {
- ${ kernelRunShortcut.toString() };
- const utils = {
- allPropertiesOf: function ${ utils.allPropertiesOf.toString() },
- clone: function ${ utils.clone.toString() },
- /*splitArray: function ${ utils.splitArray.toString() },
- getArgumentType: function ${ utils.getArgumentType.toString() },
- getOutput: function ${ utils.getOutput.toString() },
- dimToTexSize: function ${ utils.dimToTexSize.toString() },
- copyFlatten: function ${ utils.copyFlatten.toString() },
- flatten: function ${ utils.flatten.toString() },
- systemEndianness: '${ utils.systemEndianness() }',
- initWebGl: function ${ utils.initWebGl.toString() },
- isArray: function ${ utils.isArray.toString() }*/
- };
- class ${ name || 'Kernel' } {
- constructor() {
- this.argumentsLength = 0;
- this._canvas = null;
- this._webGl = null;
- this.built = false;
- this.program = null;
- this.paramNames = ${ JSON.stringify(cpuKernel.paramNames) };
- this.paramTypes = ${ JSON.stringify(cpuKernel.paramTypes) };
- this.texSize = ${ JSON.stringify(cpuKernel.texSize) };
- this.output = ${ JSON.stringify(cpuKernel.output) };
- this._kernelString = \`${ cpuKernel._kernelString }\`;
- this.output = ${ JSON.stringify(cpuKernel.output) };
- this.run = function() {
- this.run = null;
- this.build();
- return this.run.apply(this, arguments);
- }.bind(this);
- this.thread = {
- x: 0,
- y: 0,
- z: 0
- };
+const { utils } = require('../../utils');
+
+function constantsToString(constants, types) {
+ const results = [];
+ for (const name in types) {
+ if (!types.hasOwnProperty(name)) continue;
+ const type = types[name];
+ const constant = constants[name];
+ switch (type) {
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ case 'Boolean':
+ results.push(`${name}:${constant}`);
+ break;
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ case 'Matrix(2)':
+ case 'Matrix(3)':
+ case 'Matrix(4)':
+ results.push(`${name}:new ${constant.constructor.name}(${JSON.stringify(Array.from(constant))})`);
+ break;
+ }
+ }
+ return `{ ${ results.join() } }`;
+}
+
+function cpuKernelString(cpuKernel, name) {
+ const header = [];
+ const thisProperties = [];
+ const beforeReturn = [];
+
+ const useFunctionKeyword = !/^function/.test(cpuKernel.color.toString());
+
+ header.push(
+ ' const { context, canvas, constants: incomingConstants } = settings;',
+ ` const output = new Int32Array(${JSON.stringify(Array.from(cpuKernel.output))});`,
+ ` const _constantTypes = ${JSON.stringify(cpuKernel.constantTypes)};`,
+ ` const _constants = ${constantsToString(cpuKernel.constants, cpuKernel.constantTypes)};`
+ );
+
+ thisProperties.push(
+ ' constants: _constants,',
+ ' context,',
+ ' output,',
+ ' thread: {x: 0, y: 0, z: 0},'
+ );
+
+ if (cpuKernel.graphical) {
+ header.push(` const _imageData = context.createImageData(${cpuKernel.output[0]}, ${cpuKernel.output[1]});`);
+ header.push(` const _colorData = new Uint8ClampedArray(${cpuKernel.output[0]} * ${cpuKernel.output[1]} * 4);`);
+
+ const colorFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.color.toString(), {
+ thisLookup: (propertyName) => {
+ switch (propertyName) {
+ case '_colorData':
+ return '_colorData';
+ case '_imageData':
+ return '_imageData';
+ case 'output':
+ return 'output';
+ case 'thread':
+ return 'this.thread';
+ }
+ return JSON.stringify(cpuKernel[propertyName]);
+ },
+ findDependency: (object, name) => {
+ return null;
+ }
+ });
+
+ const getPixelsFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.getPixels.toString(), {
+ thisLookup: (propertyName) => {
+ switch (propertyName) {
+ case '_colorData':
+ return '_colorData';
+ case '_imageData':
+ return '_imageData';
+ case 'output':
+ return 'output';
+ case 'thread':
+ return 'this.thread';
+ }
+ return JSON.stringify(cpuKernel[propertyName]);
+ },
+ findDependency: () => {
+ return null;
+ }
+ });
+
+ thisProperties.push(
+ ' _imageData,',
+ ' _colorData,',
+ ` color: ${colorFn},`
+ );
+
+ beforeReturn.push(
+ ` kernel.getPixels = ${getPixelsFn};`
+ );
+ }
+
+ const constantTypes = [];
+ const constantKeys = Object.keys(cpuKernel.constantTypes);
+ for (let i = 0; i < constantKeys.length; i++) {
+ constantTypes.push(cpuKernel.constantTypes[constantKeys]);
+ }
+ if (cpuKernel.argumentTypes.indexOf('HTMLImageArray') !== -1 || constantTypes.indexOf('HTMLImageArray') !== -1) {
+ const flattenedImageTo3DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._imageTo3DArray.toString(), {
+ doNotDefine: ['canvas'],
+ findDependency: (object, name) => {
+ if (object === 'this') {
+ return (useFunctionKeyword ? 'function ' : '') + cpuKernel[name].toString();
+ }
+ return null;
+ },
+ thisLookup: (propertyName) => {
+ switch (propertyName) {
+ case 'canvas':
+ return;
+ case 'context':
+ return 'context';
+ }
+ }
+ });
+ beforeReturn.push(flattenedImageTo3DArray);
+ thisProperties.push(` _mediaTo2DArray,`);
+ thisProperties.push(` _imageTo3DArray,`);
+ } else if (cpuKernel.argumentTypes.indexOf('HTMLImage') !== -1 || constantTypes.indexOf('HTMLImage') !== -1) {
+ const flattenedImageTo2DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._mediaTo2DArray.toString(), {
+ findDependency: (object, name) => {
+ return null;
+ },
+ thisLookup: (propertyName) => {
+ switch (propertyName) {
+ case 'canvas':
+ return 'settings.canvas';
+ case 'context':
+ return 'settings.context';
+ }
+ throw new Error('unhandled thisLookup');
}
- setCanvas(canvas) { this._canvas = canvas; return this; }
- setWebGl(webGl) { this._webGl = webGl; return this; }
- ${ cpuKernel.build.toString() }
- run () { ${ cpuKernel.kernelString } }
- getKernelString() { return this._kernelString; }
- };
- return kernelRunShortcut(new Kernel());
- };`;
+ });
+ beforeReturn.push(flattenedImageTo2DArray);
+ thisProperties.push(` _mediaTo2DArray,`);
+ }
+
+ return `function(settings) {
+${ header.join('\n') }
+ for (const p in _constantTypes) {
+ if (!_constantTypes.hasOwnProperty(p)) continue;
+ const type = _constantTypes[p];
+ switch (type) {
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ case 'Boolean':
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ case 'Matrix(2)':
+ case 'Matrix(3)':
+ case 'Matrix(4)':
+ if (incomingConstants.hasOwnProperty(p)) {
+ console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned');
+ }
+ continue;
+ }
+ if (!incomingConstants.hasOwnProperty(p)) {
+ throw new Error('constant ' + p + ' not found');
+ }
+ _constants[p] = incomingConstants[p];
+ }
+ const kernel = (function() {
+${cpuKernel._kernelString}
+ })
+ .apply({ ${thisProperties.join('\n')} });
+ ${ beforeReturn.join('\n') }
+ return kernel;
+}`;
+}
+
+module.exports = {
+ cpuKernelString
};
\ No newline at end of file
diff --git a/src/backend/cpu/kernel.js b/src/backend/cpu/kernel.js
index 33c082bd..13279e5c 100644
--- a/src/backend/cpu/kernel.js
+++ b/src/backend/cpu/kernel.js
@@ -1,356 +1,673 @@
-'use strict';
-
-const KernelBase = require('../kernel-base');
-const utils = require('../../core/utils');
-const kernelString = require('./kernel-string');
-
-module.exports = class CPUKernel extends KernelBase {
-
- /**
- * @constructor CPUKernel
- *
- * @desc Kernel Implementation for CPU.
- *
- * Instantiates properties to the CPU Kernel.
- *
- * @extends KernelBase
- *
- * @prop {Object} thread - The thread dimensions, x, y and z
- * @prop {Object} output - The canvas dimensions
- * @prop {Object} functionBuilder - Function Builder instance bound to this Kernel
- * @prop {Function} run - Method to run the kernel
- *
- */
- constructor(fnString, settings) {
- super(fnString, settings);
- this._fnBody = utils.getFunctionBodyFromString(fnString);
- this._fn = null;
- this.run = null;
- this._canvasCtx = null;
- this._imageData = null;
- this._colorData = null;
- this._kernelString = null;
- this.thread = {
- x: 0,
- y: 0,
- z: 0
- };
-
- this.run = function() {
- this.run = null;
- this.build.apply(this, arguments);
- return this.run.apply(this, arguments);
- }.bind(this);
- }
-
- /**
- * @memberOf CPUKernel#
- * @function
- * @name validateOptions
- *
- * @desc Validate options related to CPU Kernel, such as
- * dimensions size, and auto dimension support.
- *
- */
- validateOptions() {
- if (!this.output || this.output.length === 0) {
- if (arguments.length !== 1) {
- throw 'Auto dimensions only supported for kernels with only one input';
- }
-
- const argType = utils.getArgumentType(arguments[0]);
- if (argType === 'Array') {
- this.output = utils.getDimensions(argType);
- } else if (argType === 'Texture') {
- this.output = arguments[0].output;
- } else {
- throw 'Auto dimensions not supported for input type: ' + argType;
- }
- }
- }
-
- /**
- * @memberOf CPUKernel#
- * @function
- * @name build
- *
- * @desc Builds the Kernel, by generating the kernel
- * string using thread dimensions, and arguments
- * supplied to the kernel.
- *
- * If the graphical flag is enabled, canvas is used.
- *
- */
- build() {
- this.setupParams(arguments);
- const threadDim = this.threadDim = utils.clone(this.output);
-
- while (threadDim.length < 3) {
- threadDim.push(1);
- }
-
- if (this.graphical) {
- const canvas = this.getCanvas();
- canvas.width = threadDim[0];
- canvas.height = threadDim[1];
- this._canvasCtx = canvas.getContext('2d');
- this._imageData = this._canvasCtx.createImageData(threadDim[0], threadDim[1]);
- this._colorData = new Uint8ClampedArray(threadDim[0] * threadDim[1] * 4);
- }
-
- const kernelString = this.getKernelString();
-
- if (this.debug) {
- console.log('Options:');
- console.dir(this);
- console.log('Function output:');
- console.log(kernelString);
- }
-
- this.kernelString = kernelString;
- this.run = new Function([], kernelString).bind(this)();
- }
-
- color(r, g, b, a) {
- if (typeof a === 'undefined') {
- a = 1;
- }
-
- r = Math.floor(r * 255);
- g = Math.floor(g * 255);
- b = Math.floor(b * 255);
- a = Math.floor(a * 255);
-
- const width = this.output[0];
- const height = this.output[1];
-
- const x = this.thread.x;
- const y = height - this.thread.y - 1;
-
- const index = x + y * width;
-
- this._colorData[index * 4 + 0] = r;
- this._colorData[index * 4 + 1] = g;
- this._colorData[index * 4 + 2] = b;
- this._colorData[index * 4 + 3] = a;
- }
-
- /**
- * @memberOf CPUKernel#
- * @function
- * @name getKernelString
- *
- * @desc Generates kernel string for this kernel program.
- *
- * If sub-kernels are supplied, they are also factored in.
- * This string can be saved by calling the `toString` method
- * and then can be reused later.
- *
- * @returns {String} result
- *
- */
- getKernelString() {
- if (this._kernelString !== null) return this._kernelString;
-
- const builder = this.functionBuilder;
-
- // Thread dim fix (to make compilable)
- const threadDim = this.threadDim || (this.threadDim = utils.clone(this.output));
- while (threadDim.length < 3) {
- threadDim.push(1);
- }
-
- builder.addKernel(this.fnString, {
- prototypeOnly: false,
- constants: this.constants,
- output: this.output,
- debug: this.debug,
- loopMaxIterations: this.loopMaxIterations
- }, this.paramNames, this.paramTypes);
-
- builder.addFunctions(this.functions, {
- constants: this.constants,
- output: this.output
- });
-
- if (this.subKernels !== null) {
- this.subKernelOutputTextures = [];
- this.subKernelOutputVariableNames = [];
- for (let i = 0; i < this.subKernels.length; i++) {
- const subKernel = this.subKernels[i];
- builder.addSubKernel(subKernel, {
- prototypeOnly: false,
- constants: this.constants,
- output: this.output,
- debug: this.debug,
- loopMaxIterations: this.loopMaxIterations
- });
- this.subKernelOutputVariableNames.push(subKernel.name + 'Result');
- }
-
- } else if (this.subKernelProperties !== null) {
- this.subKernelOutputVariableNames = [];
- let i = 0;
- for (let p in this.subKernelProperties) {
- if (!this.subKernelProperties.hasOwnProperty(p)) continue;
- const subKernel = this.subKernelProperties[p];
- builder.addSubKernel(subKernel);
- this.subKernelOutputVariableNames.push(subKernel.name + 'Result');
- i++;
- }
- }
-
- const prototypes = builder.getPrototypes();
- const kernel = prototypes.shift();
- const kernelString = this._kernelString = `
- var LOOP_MAX = ${ this._getLoopMaxString() };
- var _this = this;
- ${ this.subKernelOutputVariableNames === null
- ? ''
- : this.subKernelOutputVariableNames.map((name) => ` var ${ name } = null;\n`).join('')
- }
- return function (${ this.paramNames.map(paramName => 'user_' + paramName).join(', ') }) {
- var ret = new Array(${ threadDim[2] });
- ${ this.subKernelOutputVariableNames === null
- ? ''
- : this.subKernelOutputVariableNames.map((name) => ` ${ name }Z = new Array(${ threadDim[2] });\n`).join('')
- }
- for (this.thread.z = 0; this.thread.z < ${ threadDim[2] }; this.thread.z++) {
- ret[this.thread.z] = new Array(${ threadDim[1] });
- ${ this.subKernelOutputVariableNames === null
- ? ''
- : this.subKernelOutputVariableNames.map((name) => ` ${ name }Z[this.thread.z] = new Array(${ threadDim[1] });\n`).join('')
- }
- for (this.thread.y = 0; this.thread.y < ${ threadDim[1] }; this.thread.y++) {
- ret[this.thread.z][this.thread.y] = new Array(${ threadDim[0] });
- ${ this.subKernelOutputVariableNames === null
- ? ''
- : this.subKernelOutputVariableNames.map((name) => ` ${ name }Z[this.thread.z][this.thread.y] = new Array(${ threadDim[0] });\n`).join('')
- }
- for (this.thread.x = 0; this.thread.x < ${ threadDim[0] }; this.thread.x++) {
- var kernelResult;
- ${ kernel }
- ret[this.thread.z][this.thread.y][this.thread.x] = kernelResult;
-${ this.subKernelOutputVariableNames === null
- ? ''
- : this.subKernelOutputVariableNames.map((name) => ` ${ name }Z[this.thread.z][this.thread.y][this.thread.x] = ${ name };\n`).join('') }
- }
+const { Kernel } = require('../kernel');
+const { FunctionBuilder } = require('../function-builder');
+const { CPUFunctionNode } = require('./function-node');
+const { utils } = require('../../utils');
+const { cpuKernelString } = require('./kernel-string');
+
+/**
+ * @desc Kernel Implementation for CPU.
+ * Instantiates properties to the CPU Kernel.
+ */
+class CPUKernel extends Kernel {
+ static getFeatures() {
+ return this.features;
+ }
+ static get features() {
+ return Object.freeze({
+ kernelMap: true,
+ isIntegerDivisionAccurate: true
+ });
+ }
+ static get isSupported() {
+ return true;
+ }
+ static isContextMatch(context) {
+ return false;
+ }
+ /**
+ * @desc The current mode in which gpu.js is executing.
+ */
+ 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(combinedKernel) {
+ return combinedKernel;
+ }
+
+ static getSignature(kernel, argumentTypes) {
+ return 'cpu' + (argumentTypes.length > 0 ? ':' + argumentTypes.join(',') : '');
+ }
+
+ constructor(source, settings) {
+ super(source, settings);
+ this.mergeSettings(source.settings || settings);
+
+ this._imageData = null;
+ this._colorData = null;
+ this._kernelString = null;
+ this._prependedString = [];
+ this.thread = {
+ x: 0,
+ y: 0,
+ z: 0
+ };
+ this.translatedSources = null;
+ }
+
+ initCanvas() {
+ if (typeof document !== 'undefined') {
+ return document.createElement('canvas');
+ } else if (typeof OffscreenCanvas !== 'undefined') {
+ return new OffscreenCanvas(0, 0);
+ }
+ }
+
+ initContext() {
+ if (!this.canvas) return null;
+ return this.canvas.getContext('2d');
+ }
+
+ initPlugins(settings) {
+ return [];
+ }
+
+ /**
+ * @desc Validate settings related to Kernel, such as dimensions size, and auto output support.
+ * @param {IArguments} args
+ */
+ validateSettings(args) {
+ 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 = utils.getDimensions(argType);
+ } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') {
+ this.output = args[0].output;
+ } else {
+ throw new Error('Auto output not supported for input type: ' + argType);
+ }
+ }
+
+ if (this.graphical) {
+ if (this.output.length !== 2) {
+ throw new Error('Output must have 2 dimensions on graphical mode');
+ }
+ }
+
+ this.checkOutput();
+ }
+
+ translateSource() {
+ this.leadingReturnStatement = this.output.length > 1 ? 'resultX[x] = ' : 'result[x] = ';
+ if (this.subKernels) {
+ const followingReturnStatement = [];
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const {
+ name
+ } = this.subKernels[i];
+ followingReturnStatement.push(this.output.length > 1 ? `resultX_${ name }[x] = subKernelResult_${ name };\n` : `result_${ name }[x] = subKernelResult_${ name };\n`);
+ }
+ this.followingReturnStatement = followingReturnStatement.join('');
+ }
+ const functionBuilder = FunctionBuilder.fromKernel(this, CPUFunctionNode);
+ this.translatedSources = functionBuilder.getPrototypes('kernel');
+ if (!this.graphical && !this.returnType) {
+ this.returnType = functionBuilder.getKernelResultType();
+ }
+ }
+
+ /**
+ * @desc Builds the Kernel, by generating the kernel
+ * string using thread dimensions, and arguments
+ * supplied to the kernel.
+ *
+ * If the graphical flag is enabled, canvas is used.
+ */
+ build() {
+ if (this.built) return;
+ this.setupConstants();
+ this.setupArguments(arguments);
+ this.validateSettings(arguments);
+ this.translateSource();
+
+ if (this.graphical) {
+ const {
+ canvas,
+ output
+ } = this;
+ if (!canvas) {
+ throw new Error('no canvas available for using graphical output');
+ }
+ const width = output[0];
+ const height = output[1] || 1;
+ canvas.width = width;
+ canvas.height = height;
+ this._imageData = this.context.createImageData(width, height);
+ this._colorData = new Uint8ClampedArray(width * height * 4);
+ }
+
+ const kernelString = this.getKernelString();
+ this.kernelString = kernelString;
+
+ if (this.debug) {
+ console.log('Function output:');
+ console.log(kernelString);
+ }
+
+ try {
+ this.run = new Function([], kernelString).bind(this)();
+ } catch (e) {
+ console.error('An error occurred compiling the javascript: ', e);
+ }
+ this.buildSignature(arguments);
+ this.built = true;
+ }
+
+ color(r, g, b, a) {
+ if (typeof a === 'undefined') {
+ a = 1;
+ }
+
+ r = Math.floor(r * 255);
+ g = Math.floor(g * 255);
+ b = Math.floor(b * 255);
+ a = Math.floor(a * 255);
+
+ const width = this.output[0];
+ const height = this.output[1];
+
+ const x = this.thread.x;
+ const y = height - this.thread.y - 1;
+
+ const index = x + y * width;
+
+ this._colorData[index * 4 + 0] = r;
+ this._colorData[index * 4 + 1] = g;
+ this._colorData[index * 4 + 2] = b;
+ this._colorData[index * 4 + 3] = a;
+ }
+
+ /**
+ * @desc Generates kernel string for this kernel program.
+ *
+ * If sub-kernels are supplied, they are also factored in.
+ * This string can be saved by calling the `toString` method
+ * and then can be reused later.
+ *
+ * @returns {String} result
+ *
+ */
+ getKernelString() {
+ if (this._kernelString !== null) return this._kernelString;
+
+ let kernelThreadString = null;
+ let {
+ translatedSources
+ } = this;
+ if (translatedSources.length > 1) {
+ translatedSources = translatedSources.filter(fn => {
+ if (/^function/.test(fn)) return fn;
+ kernelThreadString = fn;
+ return false;
+ });
+ } else {
+ kernelThreadString = translatedSources.shift();
+ }
+ return this._kernelString = ` const LOOP_MAX = ${ this._getLoopMaxString() };
+ ${ this.injectedNative || '' }
+ const _this = this;
+ ${ this._resultKernelHeader() }
+ ${ this._processConstants() }
+ return (${ this.argumentNames.map(argumentName => 'user_' + argumentName).join(', ') }) => {
+ ${ this._prependedString.join('') }
+ ${ this._earlyThrows() }
+ ${ this._processArguments() }
+ ${ this.graphical ? this._graphicalKernelBody(kernelThreadString) : this._resultKernelBody(kernelThreadString) }
+ ${ translatedSources.length > 0 ? translatedSources.join('\n') : '' }
+ };`;
+ }
+
+ /**
+ * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused.
+ */
+ toString() {
+ return cpuKernelString(this);
+ }
+
+ /**
+ * @desc Get the maximum loop size String.
+ * @returns {String} result
+ */
+ _getLoopMaxString() {
+ return (
+ this.loopMaxIterations ?
+ ` ${ parseInt(this.loopMaxIterations) };` :
+ ' 1000;'
+ );
+ }
+
+ _processConstants() {
+ if (!this.constants) return '';
+
+ const result = [];
+ for (let p in this.constants) {
+ const type = this.constantTypes[p];
+ switch (type) {
+ case 'HTMLCanvas':
+ case 'OffscreenCanvas':
+ case 'HTMLImage':
+ case 'ImageBitmap':
+ case 'ImageData':
+ case 'HTMLVideo':
+ result.push(` const constants_${p} = this._mediaTo2DArray(this.constants.${p});\n`);
+ break;
+ case 'HTMLImageArray':
+ result.push(` const constants_${p} = this._imageTo3DArray(this.constants.${p});\n`);
+ break;
+ case 'Input':
+ result.push(` const constants_${p} = this.constants.${p}.value;\n`);
+ break;
+ default:
+ result.push(` const constants_${p} = this.constants.${p};\n`);
+ }
+ }
+ return result.join('');
+ }
+
+ _earlyThrows() {
+ if (this.graphical) return '';
+ if (this.immutable) return '';
+ if (!this.pipeline) return '';
+ const arrayArguments = [];
+ for (let i = 0; i < this.argumentTypes.length; i++) {
+ if (this.argumentTypes[i] === 'Array') {
+ arrayArguments.push(this.argumentNames[i]);
+ }
+ }
+ if (arrayArguments.length === 0) return '';
+ const checks = [];
+ for (let i = 0; i < arrayArguments.length; i++) {
+ const argumentName = arrayArguments[i];
+ const checkSubKernels = this._mapSubKernels(subKernel => `user_${argumentName} === result_${subKernel.name}`).join(' || ');
+ checks.push(`user_${argumentName} === result${checkSubKernels ? ` || ${checkSubKernels}` : ''}`);
+ }
+ return `if (${checks.join(' || ')}) throw new Error('Source and destination arrays are the same. Use immutable = true');`;
+ }
+
+ _processArguments() {
+ const result = [];
+ for (let i = 0; i < this.argumentTypes.length; i++) {
+ const variableName = `user_${this.argumentNames[i]}`;
+ switch (this.argumentTypes[i]) {
+ case 'HTMLCanvas':
+ case 'OffscreenCanvas':
+ case 'HTMLImage':
+ case 'ImageBitmap':
+ case 'ImageData':
+ case 'HTMLVideo':
+ result.push(` ${variableName} = this._mediaTo2DArray(${variableName});\n`);
+ break;
+ case 'HTMLImageArray':
+ result.push(` ${variableName} = this._imageTo3DArray(${variableName});\n`);
+ break;
+ case 'Input':
+ result.push(` ${variableName} = ${variableName}.value;\n`);
+ break;
+ case 'ArrayTexture(1)':
+ case 'ArrayTexture(2)':
+ case 'ArrayTexture(3)':
+ case 'ArrayTexture(4)':
+ case 'NumberTexture':
+ case 'MemoryOptimizedNumberTexture':
+ result.push(`
+ if (${variableName}.toArray) {
+ if (!_this.textureCache) {
+ _this.textureCache = [];
+ _this.arrayCache = [];
+ }
+ const textureIndex = _this.textureCache.indexOf(${variableName});
+ if (textureIndex !== -1) {
+ ${variableName} = _this.arrayCache[textureIndex];
+ } else {
+ _this.textureCache.push(${variableName});
+ ${variableName} = ${variableName}.toArray();
+ _this.arrayCache.push(${variableName});
+ }
+ }`);
+ break;
+ }
+ }
+ return result.join('');
+ }
+
+ _mediaTo2DArray(media) {
+ const canvas = this.canvas;
+ const width = media.width > 0 ? media.width : media.videoWidth;
+ const height = media.height > 0 ? media.height : media.videoHeight;
+ if (canvas.width < width) {
+ canvas.width = width;
+ }
+ if (canvas.height < height) {
+ canvas.height = height;
+ }
+ const ctx = this.context;
+ let pixelsData;
+ if (media.constructor === ImageData) {
+ pixelsData = media.data;
+ } else {
+ ctx.drawImage(media, 0, 0, width, height);
+ pixelsData = ctx.getImageData(0, 0, width, height).data;
+ }
+ const imageArray = new Array(height);
+ let index = 0;
+ for (let y = height - 1; y >= 0; y--) {
+ const row = imageArray[y] = new Array(width);
+ for (let x = 0; x < width; x++) {
+ const pixel = new Float32Array(4);
+ pixel[0] = pixelsData[index++] / 255; // r
+ pixel[1] = pixelsData[index++] / 255; // g
+ pixel[2] = pixelsData[index++] / 255; // b
+ pixel[3] = pixelsData[index++] / 255; // a
+ row[x] = pixel;
+ }
+ }
+ return imageArray;
+ }
+
+ /**
+ *
+ * @param flip
+ * @return {Uint8ClampedArray}
+ */
+ getPixels(flip) {
+ const [width, height] = this.output;
+ // cpu is not flipped by default
+ return flip ? utils.flipPixels(this._imageData.data, width, height) : this._imageData.data.slice(0);
+ }
+
+ _imageTo3DArray(images) {
+ const imagesArray = new Array(images.length);
+ for (let i = 0; i < images.length; i++) {
+ imagesArray[i] = this._mediaTo2DArray(images[i]);
+ }
+ return imagesArray;
+ }
+
+ _resultKernelHeader() {
+ if (this.graphical) return '';
+ if (this.immutable) return '';
+ if (!this.pipeline) return '';
+ switch (this.output.length) {
+ case 1:
+ return this._mutableKernel1DResults();
+ case 2:
+ return this._mutableKernel2DResults();
+ case 3:
+ return this._mutableKernel3DResults();
+ }
+ }
+
+ _resultKernelBody(kernelString) {
+ switch (this.output.length) {
+ case 1:
+ return (!this.immutable && this.pipeline ? this._resultMutableKernel1DLoop(kernelString) : this._resultImmutableKernel1DLoop(kernelString)) + this._kernelOutput();
+ case 2:
+ return (!this.immutable && this.pipeline ? this._resultMutableKernel2DLoop(kernelString) : this._resultImmutableKernel2DLoop(kernelString)) + this._kernelOutput();
+ case 3:
+ return (!this.immutable && this.pipeline ? this._resultMutableKernel3DLoop(kernelString) : this._resultImmutableKernel3DLoop(kernelString)) + this._kernelOutput();
+ default:
+ throw new Error('unsupported size kernel');
+ }
+ }
+
+ _graphicalKernelBody(kernelThreadString) {
+ switch (this.output.length) {
+ case 2:
+ return this._graphicalKernel2DLoop(kernelThreadString) + this._graphicalOutput();
+ default:
+ throw new Error('unsupported size kernel');
+ }
+ }
+
+ _graphicalOutput() {
+ return `
+ this._imageData.data.set(this._colorData);
+ this.context.putImageData(this._imageData, 0, 0);
+ return;`
+ }
+
+ _getKernelResultTypeConstructorString() {
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ return 'Float32Array';
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ return 'Array';
+ default:
+ if (this.graphical) {
+ return 'Float32Array';
}
+ throw new Error(`unhandled returnType ${ this.returnType }`);
+ }
+ }
+
+ _resultImmutableKernel1DLoop(kernelString) {
+ const constructorString = this._getKernelResultTypeConstructorString();
+ return ` const outputX = _this.output[0];
+ const result = new ${constructorString}(outputX);
+ ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new ${constructorString}(outputX);\n`).join(' ') }
+ ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') }
+ for (let x = 0; x < outputX; x++) {
+ this.thread.x = x;
+ this.thread.y = 0;
+ this.thread.z = 0;
+ ${ kernelString }
+ }`;
+ }
+
+ _mutableKernel1DResults() {
+ const constructorString = this._getKernelResultTypeConstructorString();
+ return ` const outputX = _this.output[0];
+ const result = new ${constructorString}(outputX);
+ ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new ${constructorString}(outputX);\n`).join(' ') }
+ ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') }`;
+ }
+
+ _resultMutableKernel1DLoop(kernelString) {
+ return ` const outputX = _this.output[0];
+ for (let x = 0; x < outputX; x++) {
+ this.thread.x = x;
+ this.thread.y = 0;
+ this.thread.z = 0;
+ ${ kernelString }
+ }`;
+ }
+
+ _resultImmutableKernel2DLoop(kernelString) {
+ const constructorString = this._getKernelResultTypeConstructorString();
+ return ` const outputX = _this.output[0];
+ const outputY = _this.output[1];
+ const result = new Array(outputY);
+ ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\n`).join(' ') }
+ ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') }
+ for (let y = 0; y < outputY; y++) {
+ this.thread.z = 0;
+ this.thread.y = y;
+ const resultX = result[y] = new ${constructorString}(outputX);
+ ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join('') }
+ for (let x = 0; x < outputX; x++) {
+ this.thread.x = x;
+ ${ kernelString }
+ }
+ }`;
+ }
+
+ _mutableKernel2DResults() {
+ const constructorString = this._getKernelResultTypeConstructorString();
+ return ` const outputX = _this.output[0];
+ const outputY = _this.output[1];
+ const result = new Array(outputY);
+ ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\n`).join(' ') }
+ ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') }
+ for (let y = 0; y < outputY; y++) {
+ const resultX = result[y] = new ${constructorString}(outputX);
+ ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join('') }
+ }`;
+ }
+
+ _resultMutableKernel2DLoop(kernelString) {
+ const constructorString = this._getKernelResultTypeConstructorString();
+ return ` const outputX = _this.output[0];
+ const outputY = _this.output[1];
+ for (let y = 0; y < outputY; y++) {
+ this.thread.z = 0;
+ this.thread.y = y;
+ const resultX = result[y];
+ ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join('') }
+ for (let x = 0; x < outputX; x++) {
+ this.thread.x = x;
+ ${ kernelString }
}
-
- if (this.graphical) {
- this._imageData.data.set(this._colorData);
- this._canvasCtx.putImageData(this._imageData, 0, 0);
- return;
+ }`;
+ }
+
+ _graphicalKernel2DLoop(kernelString) {
+ return ` const outputX = _this.output[0];
+ const outputY = _this.output[1];
+ for (let y = 0; y < outputY; y++) {
+ this.thread.z = 0;
+ this.thread.y = y;
+ for (let x = 0; x < outputX; x++) {
+ this.thread.x = x;
+ ${ kernelString }
}
-
- if (this.output.length === 1) {
- ret = ret[0][0];
-${ this.subKernelOutputVariableNames === null
- ? ''
- : this.subKernelOutputVariableNames.map((name) => ` ${ name } = ${ name }Z[0][0];\n`).join('')
+ }`;
+ }
+
+ _resultImmutableKernel3DLoop(kernelString) {
+ const constructorString = this._getKernelResultTypeConstructorString();
+ return ` const outputX = _this.output[0];
+ const outputY = _this.output[1];
+ const outputZ = _this.output[2];
+ const result = new Array(outputZ);
+ ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputZ);\n`).join(' ') }
+ ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') }
+ for (let z = 0; z < outputZ; z++) {
+ this.thread.z = z;
+ const resultY = result[z] = new Array(outputY);
+ ${ this._mapSubKernels(subKernel => `const resultY_${ subKernel.name } = result_${subKernel.name}[z] = new Array(outputY);\n`).join(' ') }
+ for (let y = 0; y < outputY; y++) {
+ this.thread.y = y;
+ const resultX = resultY[y] = new ${constructorString}(outputX);
+ ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = resultY_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join(' ') }
+ for (let x = 0; x < outputX; x++) {
+ this.thread.x = x;
+ ${ kernelString }
}
-
- } else if (this.output.length === 2) {
- ret = ret[0];
- ${ this.subKernelOutputVariableNames === null
- ? ''
- : this.subKernelOutputVariableNames.map((name) => ` ${ name } = ${ name }Z[0];\n`).join('')
+ }
+ }`;
+ }
+
+ _mutableKernel3DResults() {
+ const constructorString = this._getKernelResultTypeConstructorString();
+ return ` const outputX = _this.output[0];
+ const outputY = _this.output[1];
+ const outputZ = _this.output[2];
+ const result = new Array(outputZ);
+ ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputZ);\n`).join(' ') }
+ ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') }
+ for (let z = 0; z < outputZ; z++) {
+ const resultY = result[z] = new Array(outputY);
+ ${ this._mapSubKernels(subKernel => `const resultY_${ subKernel.name } = result_${subKernel.name}[z] = new Array(outputY);\n`).join(' ') }
+ for (let y = 0; y < outputY; y++) {
+ const resultX = resultY[y] = new ${constructorString}(outputX);
+ ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = resultY_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join(' ') }
+ }
+ }`;
+ }
+
+ _resultMutableKernel3DLoop(kernelString) {
+ return ` const outputX = _this.output[0];
+ const outputY = _this.output[1];
+ const outputZ = _this.output[2];
+ for (let z = 0; z < outputZ; z++) {
+ this.thread.z = z;
+ const resultY = result[z];
+ for (let y = 0; y < outputY; y++) {
+ this.thread.y = y;
+ const resultX = resultY[y];
+ for (let x = 0; x < outputX; x++) {
+ this.thread.x = x;
+ ${ kernelString }
}
+ }
+ }`;
+ }
+
+ _kernelOutput() {
+ if (!this.subKernels) {
+ return '\n return result;';
}
-
- ${ this.subKernelOutputVariableNames === null
- ? 'return ret;\n'
- : this.subKernels !== null
- ? `var result = [
- ${ this.subKernelOutputVariableNames.map((name) => `${ name }`).join(',\n') }
- ];
- result.result = ret;
- return result;\n`
- : `return {
- result: ret,
- ${ Object.keys(this.subKernelProperties).map((name, i) => `${ name }: ${ this.subKernelOutputVariableNames[i] }`).join(',\n') }
- };`
- }
- ${ prototypes.length > 0 ? prototypes.join('\n') : '' }
- }.bind(this);`;
- return kernelString;
- }
-
- /**
- * @memberOf CPUKernel#
- * @function
- * @name toString
- *
- * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused.
- *
- */
- toString() {
- return kernelString(this);
- }
-
- /**
- * @memberOf CPUKernel#
- * @function
- * @name precompileKernelObj
- *
- * @desc Precompile the kernel into a single object,
- * that can be used for building the execution kernel subsequently.
- *
- * @param {Array} argTypes - Array of argument types
- *
- * Return:
- * Compiled kernel {Object}
- *
- */
- precompileKernelObj(argTypes) {
-
- const threadDim = this.threadDim || (this.threadDim = utils.clone(this.output));
-
-
- return {
- threadDim: threadDim
- };
- }
-
- /**
- * @memberOf CPUKernel
- * @function
- * @name compileKernel
- * @static
- *
- * @desc Takes a previously precompiled kernel object,
- * and complete compilation into a full kernel
- *
- * @returns {Function} Compiled kernel
- *
- */
- static compileKernel(precompileObj) {
-
- // Extract values from precompiled obj
- const threadDim = precompileObj.threadDim;
-
- // Normalize certain values : For actual build
- while (threadDim.length < 3) {
- threadDim.push(1);
- }
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getLoopMaxString
- *
- * @desc Get the maximum loop size String.
- *
- * @returns {String} result
- *
- */
- _getLoopMaxString() {
- return (
- this.loopMaxIterations ?
- ` ${ parseInt(this.loopMaxIterations) };\n` :
- ' 1000;\n'
- );
- }
+ return `\n return {
+ result: result,
+ ${ this.subKernels.map(subKernel => `${ subKernel.property }: result_${ subKernel.name }`).join(',\n ') }
+ };`;
+ }
+
+ _mapSubKernels(fn) {
+ return this.subKernels === null ? [''] :
+ this.subKernels.map(fn);
+ }
+
+ destroy(removeCanvasReference) {
+ if (removeCanvasReference) {
+ delete this.canvas;
+ }
+ }
+
+ static destroyContext(context) {}
+
+ toJSON() {
+ const json = super.toJSON();
+ json.functionNodes = FunctionBuilder.fromKernel(this, CPUFunctionNode).toJSON();
+ return json;
+ }
+
+ setOutput(output) {
+ super.setOutput(output);
+ const [width, height] = this.output;
+ if (this.graphical) {
+ this._imageData = this.context.createImageData(width, height);
+ this._colorData = new Uint8ClampedArray(width * height * 4);
+ }
+ }
+
+ prependString(value) {
+ if (this._kernelString) throw new Error('Kernel already built');
+ this._prependedString.push(value);
+ }
+
+ hasPrependString(value) {
+ return this._prependedString.indexOf(value) > -1;
+ }
+}
+
+module.exports = {
+ CPUKernel
};
\ No newline at end of file
diff --git a/src/backend/cpu/runner.js b/src/backend/cpu/runner.js
deleted file mode 100644
index 48052f0d..00000000
--- a/src/backend/cpu/runner.js
+++ /dev/null
@@ -1,40 +0,0 @@
-'use strict';
-
-const utils = require('../../core/utils');
-const RunnerBase = require('../runner-base');
-const CPUKernel = require('./kernel');
-const CPUFunctionBuilder = require('./function-builder');
-
-module.exports = class CPURunner extends RunnerBase {
-
- /**
- * @constructor CPURunner
- *
- * @desc Instantiates a Runner instance for the kernel.
- *
- * @extends RunnerBase
- *
- * @param {Object} settings - Settings to instantiate properties in RunnerBase, with given values
- *
- */
-
- constructor(settings) {
- super(new CPUFunctionBuilder(), settings);
- this.Kernel = CPUKernel;
- this.kernel = null;
- }
-
- /**
- * @memberOf CPURunner#
- * @function
- * @name getMode()
- *
- * Return the current mode in which gpu.js is executing.
- *
- * @returns {String} The current mode; "cpu".
- *
- */
- getMode() {
- return 'cpu';
- }
-};
\ No newline at end of file
diff --git a/src/backend/function-builder-base.js b/src/backend/function-builder-base.js
deleted file mode 100644
index 8a03c6ef..00000000
--- a/src/backend/function-builder-base.js
+++ /dev/null
@@ -1,321 +0,0 @@
-'use strict';
-
-module.exports = class FunctionBuilderBase {
-
- /**
- * @constructor FunctionBuilderBase
- *
- * @desc This handles all the raw state, converted state, etc. of a single function.
- * [INTERNAL] A collection of functionNodes.
- *
- * @prop {Object} nodeMap - Object map, where nodeMap[function] = new FunctionNode;
- * @prop {Object} gpu - The current gpu instance bound to this builder
- * @prop {Object} rootKernel - The root kernel object, contains the paramNames, dimensions etc.
- *
- */
- constructor(gpu) {
- this.nodeMap = {};
- this.nativeFunctions = {};
- this.gpu = gpu;
- this.rootKernel = null;
- this.Node = null;
- }
-
- addNativeFunction(functionName, glslFunctionString) {
- this.nativeFunctions[functionName] = glslFunctionString;
- }
-
- /**
- * @memberOf FunctionBuilderBase#
- * @function
- * @name addFunction
- *
- * @desc Instantiates a FunctionNode, and add it to the nodeMap
- *
- * @param {String} functionName - Function name to assume, if its null, it attempts to extract from the function
- * @param {Function} jsFunction - JS Function to do conversion
- * @param {Object} [options]
- * @param {String[]|Object} [paramTypes] - Parameter type array, assumes all parameters are 'float' if falsey
- * @param {String} [returnType] - The return type, assumes 'float' if falsey
- *
- */
- addFunction(functionName, jsFunction, options, paramTypes, returnType) {
- this.addFunctionNode(
- new this.Node(functionName, jsFunction, options, paramTypes, returnType)
- .setAddFunction(this.addFunction.bind(this))
- );
- }
-
- addFunctions(functions, options) {
- if (functions) {
- if (Array.isArray(functions)) {
- for (let i = 0; i < functions.length; i++) {
- this.addFunction(null, functions[i], options);
- }
- } else {
- for (let p in functions) {
- this.addFunction(p, functions[p], options);
- }
- }
- }
- }
-
- addNativeFunctions(nativeFunctions) {
- for (let functionName in nativeFunctions) {
- if (!nativeFunctions.hasOwnProperty(functionName)) continue;
- this.addNativeFunction(functionName, nativeFunctions[functionName]);
- }
- }
-
- /**
- * @memberOf FunctionBuilderBase#
- * @function
- * @name addFunctionNode
- *
- * @desc Add the function node directly
- *
- * @param {functionNode} inNode - functionNode to add
- *
- */
- addFunctionNode(inNode) {
- this.nodeMap[inNode.functionName] = inNode;
- if (inNode.isRootKernel) {
- this.rootKernel = inNode;
- }
- }
-
- /**
- * @memberOf FunctionBuilderBase#
- * @function
- * @name traceFunctionCalls
- *
- * @desc Trace all the depending functions being called, from a single function
- *
- * This allow for 'unneeded' functions to be automatically optimized out.
- * Note that the 0-index, is the starting function trace.
- *
- * @param {String} functionName - Function name to trace from, default to 'kernel'
- * @param {String[]} retList - Returning list of function names that is traced. Including itself.
- * @param {Object} [parent] - Parent node
- *
- * @returns {String[]} Returning list of function names that is traced. Including itself.
- */
- traceFunctionCalls(functionName, retList, parent) {
- functionName = functionName || 'kernel';
- retList = retList || [];
-
- const fNode = this.nodeMap[functionName];
- if (fNode) {
- // Check if function already exists
- const functionIndex = retList.indexOf(functionName);
- if (functionIndex === -1) {
- retList.push(functionName);
- if (parent) {
- fNode.parent = parent;
- }
- fNode.getFunctionString(); //ensure JS trace is done
- for (let i = 0; i < fNode.calledFunctions.length; ++i) {
- this.traceFunctionCalls(fNode.calledFunctions[i], retList, fNode);
- }
- } else {
- /**
- * https://github.com/gpujs/gpu.js/issues/207
- * if dependent function is already in the list, because a function depends on it, and because it has
- * already been traced, we know that we must move the dependent function to the end of the the retList.
- * */
- const dependantFunctionName = retList.splice(functionIndex, 1)[0];
- retList.push(dependantFunctionName);
- }
- }
-
- if (this.nativeFunctions[functionName]) {
- if (retList.indexOf(functionName) >= 0) {
- // Does nothing if already traced
- } else {
- retList.push(functionName);
- }
- }
-
- return retList;
- }
-
- /**
- * @memberOf FunctionBuilderBase#
- * @function
- * @name addKernel
- *
- * @desc Add a new kernel to this instance
- *
- * @param {String} fnString - Kernel function as a String
- * @param {Object} options - Settings object to set constants, debug mode, etc.
- * @param {Array} paramNames - Parameters of the kernel
- * @param {Array} paramTypes - Types of the parameters
- *
- *
- * @returns {Object} The inserted kernel as a Kernel Node
- *
- */
- addKernel(fnString, options, paramNames, paramTypes) {
- const kernelNode = new this.Node('kernel', fnString, options, paramTypes);
- kernelNode.setAddFunction(this.addFunction.bind(this));
- kernelNode.paramNames = paramNames;
- kernelNode.paramTypes = paramTypes;
- kernelNode.isRootKernel = true;
- this.addFunctionNode(kernelNode);
- return kernelNode;
- }
-
- /**
- * @memberOf FunctionBuilderBase#
- * @function
- * @name addSubKernel
- *
- * @desc Add a new sub-kernel to the current kernel instance
- *
- * @param {Function} jsFunction - Sub-kernel function (JavaScript)
- * @param {Object} options - Settings object to set constants, debug mode, etc.
- * @param {Array} paramNames - Parameters of the sub-kernel
- * @param {Array} returnType - Return type of the subKernel
- *
- * @returns {Object} The inserted sub-kernel as a Kernel Node
- *
- */
- addSubKernel(jsFunction, options, paramTypes, returnType) {
- const kernelNode = new this.Node(null, jsFunction, options, paramTypes, returnType);
- kernelNode.setAddFunction(this.addFunction.bind(this));
- kernelNode.isSubKernel = true;
- this.addFunctionNode(kernelNode);
- return kernelNode;
- }
-
- /**
- * @memberOf CPUFunctionBuilder#
- * @name getPrototypeString
- * @function
- *
- * @desc Return the string for a function
- *
- * @param {String} functionName - Function name to trace from. If null, it returns the WHOLE builder stack
- *
- * @returns {String} The full string, of all the various functions. Trace optimized if functionName given
- *
- */
- getPrototypeString(functionName) {
- return this.getPrototypes(functionName).join('\n');
- }
-
- /**
- * @memberOf CPUFunctionBuilder#
- * @name getPrototypeString
- * @function
- *
- * @desc Return the string for a function
- *
- * @param {String} [functionName] - Function name to trace from. If null, it returns the WHOLE builder stack
- *
- * @returns {Array} The full string, of all the various functions. Trace optimized if functionName given
- *
- */
- getPrototypes(functionName) {
- this.rootKernel.generate();
- if (functionName) {
- return this.getPrototypesFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse());
- }
- return this.getPrototypesFromFunctionNames(Object.keys(this.nodeMap));
- }
-
-
- /**
- * @memberOf FunctionBuilderBase#
- * @function
- * @name getStringFromFunctionNames
- *
- * @desc Get string from function names
- *
- * @param {String[]} functionList - List of function to build string
- *
- * @returns {String} The string, of all the various functions. Trace optimized if functionName given
- *
- */
- getStringFromFunctionNames(functionList) {
- const ret = [];
- for (let i = 0; i < functionList.length; ++i) {
- const node = this.nodeMap[functionList[i]];
- if (node) {
- ret.push(this.nodeMap[functionList[i]].getFunctionString());
- }
- }
- return ret.join('\n');
- }
-
- /**
- * @memberOf FunctionBuilderBase#
- * @function
- * @name getPrototypeStringFromFunctionNames
- *
- * @desc Return string of all functions converted
- *
- * @param {String[]} functionList - List of function names to build the string.
- * @param {Object} [opt - Settings object passed to functionNode. See functionNode for more details.
- *
- * @returns {Array} Prototypes of all functions converted
- *
- */
- getPrototypesFromFunctionNames(functionList, opt) {
- const ret = [];
- for (let i = 0; i < functionList.length; ++i) {
- const functionName = functionList[i];
- const node = this.nodeMap[functionName];
- if (node) {
- ret.push(node.getFunctionPrototypeString(opt));
- } else if (this.nativeFunctions[functionName]) {
- ret.push(this.nativeFunctions[functionName]);
- }
- }
- return ret;
- }
-
- /**
- * @memberOf FunctionBuilderBase#
- * @function
- * @name getPrototypeStringFromFunctionNames
- *
- * @desc Return string of all functions converted
- *
- * @param {String[]} functionList - List of function names to build the string.
- * @param {Object} opt - Settings object passed to functionNode. See functionNode for more details.
- *
- * @returns {String} Prototype string of all functions converted
- *
- */
- getPrototypeStringFromFunctionNames(functionList, opt) {
- return this.getPrototypesFromFunctionNames(functionList, opt).toString();
- }
-
- /**
- * @memberOf FunctionBuilderBase#
- * @function
- * @name getString
- *
- * Get string for a particular function name
- *
- * @param {String} functionName - Function name to trace from. If null, it returns the WHOLE builder stack
- *
- * @returns {String} The string, of all the various functions. Trace optimized if functionName given
- *
- */
- getString(functionName, opt) {
- if (opt === undefined) {
- opt = {};
- }
-
- if (functionName) {
- return this.getStringFromFunctionNames(this.traceFunctionCalls(functionName, [], opt).reverse(), opt);
- }
- return this.getStringFromFunctionNames(Object.keys(this.nodeMap), opt);
- }
-
- polyfillStandardFunctions() {
- throw new Error('polyfillStandardFunctions not defined on base function builder');
- }
-};
\ No newline at end of file
diff --git a/src/backend/function-builder.js b/src/backend/function-builder.js
new file mode 100644
index 00000000..1633f0e8
--- /dev/null
+++ b/src/backend/function-builder.js
@@ -0,0 +1,627 @@
+/**
+ * @desc This handles all the raw state, converted state, etc. of a single function.
+ * [INTERNAL] A collection of functionNodes.
+ * @class
+ */
+class FunctionBuilder {
+ /**
+ *
+ * @param {Kernel} kernel
+ * @param {FunctionNode} FunctionNode
+ * @param {object} [extraNodeOptions]
+ * @returns {FunctionBuilder}
+ * @static
+ */
+ static fromKernel(kernel, FunctionNode, extraNodeOptions) {
+ const {
+ kernelArguments,
+ kernelConstants,
+ argumentNames,
+ argumentSizes,
+ argumentBitRatios,
+ constants,
+ constantBitRatios,
+ debug,
+ loopMaxIterations,
+ nativeFunctions,
+ output,
+ optimizeFloatMemory,
+ precision,
+ plugins,
+ source,
+ subKernels,
+ functions,
+ leadingReturnStatement,
+ followingReturnStatement,
+ dynamicArguments,
+ dynamicOutput,
+ } = kernel;
+
+ const argumentTypes = new Array(kernelArguments.length);
+ const constantTypes = {};
+
+ for (let i = 0; i < kernelArguments.length; i++) {
+ argumentTypes[i] = kernelArguments[i].type;
+ }
+
+ for (let i = 0; i < kernelConstants.length; i++) {
+ const kernelConstant = kernelConstants[i];
+ constantTypes[kernelConstant.name] = kernelConstant.type;
+ }
+
+ const needsArgumentType = (functionName, index) => {
+ return functionBuilder.needsArgumentType(functionName, index);
+ };
+
+ const assignArgumentType = (functionName, index, type) => {
+ functionBuilder.assignArgumentType(functionName, index, type);
+ };
+
+ const lookupReturnType = (functionName, ast, requestingNode) => {
+ return functionBuilder.lookupReturnType(functionName, ast, requestingNode);
+ };
+
+ const lookupFunctionArgumentTypes = (functionName) => {
+ return functionBuilder.lookupFunctionArgumentTypes(functionName);
+ };
+
+ const lookupFunctionArgumentName = (functionName, argumentIndex) => {
+ return functionBuilder.lookupFunctionArgumentName(functionName, argumentIndex);
+ };
+
+ const lookupFunctionArgumentBitRatio = (functionName, argumentName) => {
+ return functionBuilder.lookupFunctionArgumentBitRatio(functionName, argumentName);
+ };
+
+ const triggerImplyArgumentType = (functionName, i, argumentType, requestingNode) => {
+ functionBuilder.assignArgumentType(functionName, i, argumentType, requestingNode);
+ };
+
+ const triggerImplyArgumentBitRatio = (functionName, argumentName, calleeFunctionName, argumentIndex) => {
+ functionBuilder.assignArgumentBitRatio(functionName, argumentName, calleeFunctionName, argumentIndex);
+ };
+
+ const onFunctionCall = (functionName, calleeFunctionName, args) => {
+ functionBuilder.trackFunctionCall(functionName, calleeFunctionName, args);
+ };
+
+ const onNestedFunction = (ast, source) => {
+ const argumentNames = [];
+ for (let i = 0; i < ast.params.length; i++) {
+ argumentNames.push(ast.params[i].name);
+ }
+ const nestedFunction = new FunctionNode(source, Object.assign({}, nodeOptions, {
+ returnType: null,
+ ast,
+ name: ast.id.name,
+ argumentNames,
+ lookupReturnType,
+ lookupFunctionArgumentTypes,
+ lookupFunctionArgumentName,
+ lookupFunctionArgumentBitRatio,
+ needsArgumentType,
+ assignArgumentType,
+ triggerImplyArgumentType,
+ triggerImplyArgumentBitRatio,
+ onFunctionCall,
+ }));
+ nestedFunction.traceFunctionAST(ast);
+ functionBuilder.addFunctionNode(nestedFunction);
+ };
+
+ const nodeOptions = Object.assign({
+ isRootKernel: false,
+ onNestedFunction,
+ lookupReturnType,
+ lookupFunctionArgumentTypes,
+ lookupFunctionArgumentName,
+ lookupFunctionArgumentBitRatio,
+ needsArgumentType,
+ assignArgumentType,
+ triggerImplyArgumentType,
+ triggerImplyArgumentBitRatio,
+ onFunctionCall,
+ optimizeFloatMemory,
+ precision,
+ constants,
+ constantTypes,
+ constantBitRatios,
+ debug,
+ loopMaxIterations,
+ output,
+ plugins,
+ dynamicArguments,
+ dynamicOutput,
+ }, extraNodeOptions || {});
+
+ const rootNodeOptions = Object.assign({}, nodeOptions, {
+ isRootKernel: true,
+ name: 'kernel',
+ argumentNames,
+ argumentTypes,
+ argumentSizes,
+ argumentBitRatios,
+ leadingReturnStatement,
+ followingReturnStatement,
+ });
+
+ if (typeof source === 'object' && source.functionNodes) {
+ return new FunctionBuilder().fromJSON(source.functionNodes, FunctionNode);
+ }
+
+ const rootNode = new FunctionNode(source, rootNodeOptions);
+
+ let functionNodes = null;
+ if (functions) {
+ functionNodes = functions.map((fn) => new FunctionNode(fn.source, {
+ returnType: fn.returnType,
+ argumentTypes: fn.argumentTypes,
+ output,
+ plugins,
+ constants,
+ constantTypes,
+ constantBitRatios,
+ optimizeFloatMemory,
+ precision,
+ lookupReturnType,
+ lookupFunctionArgumentTypes,
+ lookupFunctionArgumentName,
+ lookupFunctionArgumentBitRatio,
+ needsArgumentType,
+ assignArgumentType,
+ triggerImplyArgumentType,
+ triggerImplyArgumentBitRatio,
+ onFunctionCall,
+ onNestedFunction,
+ }));
+ }
+
+ let subKernelNodes = null;
+ if (subKernels) {
+ subKernelNodes = subKernels.map((subKernel) => {
+ const { name, source } = subKernel;
+ return new FunctionNode(source, Object.assign({}, nodeOptions, {
+ name,
+ isSubKernel: true,
+ isRootKernel: false,
+ }));
+ });
+ }
+
+ const functionBuilder = new FunctionBuilder({
+ kernel,
+ rootNode,
+ functionNodes,
+ nativeFunctions,
+ subKernelNodes
+ });
+
+ return functionBuilder;
+ }
+
+ /**
+ *
+ * @param {IFunctionBuilderSettings} [settings]
+ */
+ constructor(settings) {
+ settings = settings || {};
+ this.kernel = settings.kernel;
+ this.rootNode = settings.rootNode;
+ this.functionNodes = settings.functionNodes || [];
+ this.subKernelNodes = settings.subKernelNodes || [];
+ this.nativeFunctions = settings.nativeFunctions || [];
+ this.functionMap = {};
+ this.nativeFunctionNames = [];
+ this.lookupChain = [];
+ this.functionNodeDependencies = {};
+ this.functionCalls = {};
+
+ if (this.rootNode) {
+ this.functionMap['kernel'] = this.rootNode;
+ }
+
+ if (this.functionNodes) {
+ for (let i = 0; i < this.functionNodes.length; i++) {
+ this.functionMap[this.functionNodes[i].name] = this.functionNodes[i];
+ }
+ }
+
+ if (this.subKernelNodes) {
+ for (let i = 0; i < this.subKernelNodes.length; i++) {
+ this.functionMap[this.subKernelNodes[i].name] = this.subKernelNodes[i];
+ }
+ }
+
+ if (this.nativeFunctions) {
+ for (let i = 0; i < this.nativeFunctions.length; i++) {
+ const nativeFunction = this.nativeFunctions[i];
+ this.nativeFunctionNames.push(nativeFunction.name);
+ }
+ }
+ }
+
+ /**
+ * @desc Add the function node directly
+ *
+ * @param {FunctionNode} functionNode - functionNode to add
+ *
+ */
+ addFunctionNode(functionNode) {
+ if (!functionNode.name) throw new Error('functionNode.name needs set');
+ this.functionMap[functionNode.name] = functionNode;
+ if (functionNode.isRootKernel) {
+ this.rootNode = functionNode;
+ }
+ }
+
+ /**
+ * @desc Trace all the depending functions being called, from a single function
+ *
+ * This allow for 'unneeded' functions to be automatically optimized out.
+ * Note that the 0-index, is the starting function trace.
+ *
+ * @param {String} functionName - Function name to trace from, default to 'kernel'
+ * @param {String[]} [retList] - Returning list of function names that is traced. Including itself.
+ *
+ * @returns {String[]} Returning list of function names that is traced. Including itself.
+ */
+ traceFunctionCalls(functionName, retList) {
+ functionName = functionName || 'kernel';
+ retList = retList || [];
+
+ if (this.nativeFunctionNames.indexOf(functionName) > -1) {
+ const nativeFunctionIndex = retList.indexOf(functionName);
+ if (nativeFunctionIndex === -1) {
+ retList.push(functionName);
+ } else {
+ /**
+ * https://github.com/gpujs/gpu.js/issues/207
+ * if dependent function is already in the list, because a function depends on it, and because it has
+ * already been traced, we know that we must move the dependent function to the end of the the retList.
+ * */
+ const dependantNativeFunctionName = retList.splice(nativeFunctionIndex, 1)[0];
+ retList.push(dependantNativeFunctionName);
+ }
+ return retList;
+ }
+
+ const functionNode = this.functionMap[functionName];
+ if (functionNode) {
+ // Check if function already exists
+ const functionIndex = retList.indexOf(functionName);
+ if (functionIndex === -1) {
+ retList.push(functionName);
+ functionNode.toString(); //ensure JS trace is done
+ for (let i = 0; i < functionNode.calledFunctions.length; ++i) {
+ this.traceFunctionCalls(functionNode.calledFunctions[i], retList);
+ }
+ } else {
+ /**
+ * https://github.com/gpujs/gpu.js/issues/207
+ * if dependent function is already in the list, because a function depends on it, and because it has
+ * already been traced, we know that we must move the dependent function to the end of the the retList.
+ * */
+ const dependantFunctionName = retList.splice(functionIndex, 1)[0];
+ retList.push(dependantFunctionName);
+ }
+ }
+
+ return retList;
+ }
+
+ /**
+ * @desc Return the string for a function
+ * @param {String} functionName - Function name to trace from. If null, it returns the WHOLE builder stack
+ * @returns {String} The full string, of all the various functions. Trace optimized if functionName given
+ */
+ getPrototypeString(functionName) {
+ return this.getPrototypes(functionName).join('\n');
+ }
+
+ /**
+ * @desc Return the string for a function
+ * @param {String} [functionName] - Function name to trace from. If null, it returns the WHOLE builder stack
+ * @returns {Array} The full string, of all the various functions. Trace optimized if functionName given
+ */
+ getPrototypes(functionName) {
+ if (this.rootNode) {
+ this.rootNode.toString();
+ }
+ if (functionName) {
+ return this.getPrototypesFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse());
+ }
+ return this.getPrototypesFromFunctionNames(Object.keys(this.functionMap));
+ }
+
+ /**
+ * @desc Get string from function names
+ * @param {String[]} functionList - List of function to build string
+ * @returns {String} The string, of all the various functions. Trace optimized if functionName given
+ */
+ getStringFromFunctionNames(functionList) {
+ const ret = [];
+ for (let i = 0; i < functionList.length; ++i) {
+ const node = this.functionMap[functionList[i]];
+ if (node) {
+ ret.push(this.functionMap[functionList[i]].toString());
+ }
+ }
+ return ret.join('\n');
+ }
+
+ /**
+ * @desc Return string of all functions converted
+ * @param {String[]} functionList - List of function names to build the string.
+ * @returns {Array} Prototypes of all functions converted
+ */
+ getPrototypesFromFunctionNames(functionList) {
+ const ret = [];
+ for (let i = 0; i < functionList.length; ++i) {
+ const functionName = functionList[i];
+ const functionIndex = this.nativeFunctionNames.indexOf(functionName);
+ if (functionIndex > -1) {
+ ret.push(this.nativeFunctions[functionIndex].source);
+ continue;
+ }
+ const node = this.functionMap[functionName];
+ if (node) {
+ ret.push(node.toString());
+ }
+ }
+ return ret;
+ }
+
+ toJSON() {
+ return this.traceFunctionCalls(this.rootNode.name).reverse().map(name => {
+ const nativeIndex = this.nativeFunctions.indexOf(name);
+ if (nativeIndex > -1) {
+ return {
+ name,
+ source: this.nativeFunctions[nativeIndex].source
+ };
+ } else if (this.functionMap[name]) {
+ return this.functionMap[name].toJSON();
+ } else {
+ throw new Error(`function ${ name } not found`);
+ }
+ });
+ }
+
+ fromJSON(jsonFunctionNodes, FunctionNode) {
+ this.functionMap = {};
+ for (let i = 0; i < jsonFunctionNodes.length; i++) {
+ const jsonFunctionNode = jsonFunctionNodes[i];
+ this.functionMap[jsonFunctionNode.settings.name] = new FunctionNode(jsonFunctionNode.ast, jsonFunctionNode.settings);
+ }
+ return this;
+ }
+
+ /**
+ * @desc Get string for a particular function name
+ * @param {String} functionName - Function name to trace from. If null, it returns the WHOLE builder stack
+ * @returns {String} settings - The string, of all the various functions. Trace optimized if functionName given
+ */
+ getString(functionName) {
+ if (functionName) {
+ return this.getStringFromFunctionNames(this.traceFunctionCalls(functionName).reverse());
+ }
+ return this.getStringFromFunctionNames(Object.keys(this.functionMap));
+ }
+
+ lookupReturnType(functionName, ast, requestingNode) {
+ if (ast.type !== 'CallExpression') {
+ throw new Error(`expected ast type of "CallExpression", but is ${ ast.type }`);
+ }
+ if (this._isNativeFunction(functionName)) {
+ return this._lookupNativeFunctionReturnType(functionName);
+ } else if (this._isFunction(functionName)) {
+ const node = this._getFunction(functionName);
+ if (node.returnType) {
+ return node.returnType;
+ } else {
+ for (let i = 0; i < this.lookupChain.length; i++) {
+ // detect circlical logic
+ if (this.lookupChain[i].ast === ast) {
+ // detect if arguments have not resolved, preventing a return type
+ // if so, go ahead and resolve them, so we can resolve the return type
+ if (node.argumentTypes.length === 0 && ast.arguments.length > 0) {
+ const args = ast.arguments;
+ for (let j = 0; j < args.length; j++) {
+ this.lookupChain.push({
+ name: requestingNode.name,
+ ast: args[i],
+ requestingNode
+ });
+ node.argumentTypes[j] = requestingNode.getType(args[j]);
+ this.lookupChain.pop();
+ }
+ return node.returnType = node.getType(node.getJsAST());
+ }
+
+ throw new Error('circlical logic detected!');
+ }
+ }
+ // get ready for a ride!
+ this.lookupChain.push({
+ name: requestingNode.name,
+ ast,
+ requestingNode
+ });
+ const type = node.getType(node.getJsAST());
+ this.lookupChain.pop();
+ return node.returnType = type;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ *
+ * @param {String} functionName
+ * @return {FunctionNode}
+ * @private
+ */
+ _getFunction(functionName) {
+ if (!this._isFunction(functionName)) {
+ new Error(`Function ${functionName} not found`);
+ }
+ return this.functionMap[functionName];
+ }
+
+ _isFunction(functionName) {
+ return Boolean(this.functionMap[functionName]);
+ }
+
+ _getNativeFunction(functionName) {
+ for (let i = 0; i < this.nativeFunctions.length; i++) {
+ if (this.nativeFunctions[i].name === functionName) return this.nativeFunctions[i];
+ }
+ return null;
+ }
+
+ _isNativeFunction(functionName) {
+ return Boolean(this._getNativeFunction(functionName));
+ }
+
+ _lookupNativeFunctionReturnType(functionName) {
+ let nativeFunction = this._getNativeFunction(functionName);
+ if (nativeFunction) {
+ return nativeFunction.returnType;
+ }
+ throw new Error(`Native function ${ functionName } not found`);
+ }
+
+ lookupFunctionArgumentTypes(functionName) {
+ if (this._isNativeFunction(functionName)) {
+ return this._getNativeFunction(functionName).argumentTypes;
+ } else if (this._isFunction(functionName)) {
+ return this._getFunction(functionName).argumentTypes;
+ }
+ return null;
+ }
+
+ lookupFunctionArgumentName(functionName, argumentIndex) {
+ return this._getFunction(functionName).argumentNames[argumentIndex];
+ }
+
+ /**
+ *
+ * @param {string} functionName
+ * @param {string} argumentName
+ * @return {number}
+ */
+ lookupFunctionArgumentBitRatio(functionName, argumentName) {
+ if (!this._isFunction(functionName)) {
+ throw new Error('function not found');
+ }
+ if (this.rootNode.name === functionName) {
+ const i = this.rootNode.argumentNames.indexOf(argumentName);
+ if (i !== -1) {
+ return this.rootNode.argumentBitRatios[i];
+ }
+ }
+ const node = this._getFunction(functionName);
+ const i = node.argumentNames.indexOf(argumentName);
+ if (i === -1) {
+ throw new Error('argument not found');
+ }
+ const bitRatio = node.argumentBitRatios[i];
+ if (typeof bitRatio !== 'number') {
+ throw new Error('argument bit ratio not found');
+ }
+ return bitRatio;
+ }
+
+ needsArgumentType(functionName, i) {
+ if (!this._isFunction(functionName)) return false;
+ const fnNode = this._getFunction(functionName);
+ return !fnNode.argumentTypes[i];
+ }
+
+ assignArgumentType(functionName, i, argumentType, requestingNode) {
+ if (!this._isFunction(functionName)) return;
+ const fnNode = this._getFunction(functionName);
+ if (!fnNode.argumentTypes[i]) {
+ fnNode.argumentTypes[i] = argumentType;
+ }
+ }
+
+ /**
+ * @param {string} functionName
+ * @param {string} argumentName
+ * @param {string} calleeFunctionName
+ * @param {number} argumentIndex
+ * @return {number|null}
+ */
+ assignArgumentBitRatio(functionName, argumentName, calleeFunctionName, argumentIndex) {
+ const node = this._getFunction(functionName);
+ if (this._isNativeFunction(calleeFunctionName)) return null;
+ const calleeNode = this._getFunction(calleeFunctionName);
+ const i = node.argumentNames.indexOf(argumentName);
+ if (i === -1) {
+ throw new Error(`Argument ${argumentName} not found in arguments from function ${functionName}`);
+ }
+ const bitRatio = node.argumentBitRatios[i];
+ if (typeof bitRatio !== 'number') {
+ throw new Error(`Bit ratio for argument ${argumentName} not found in function ${functionName}`);
+ }
+ if (!calleeNode.argumentBitRatios) {
+ calleeNode.argumentBitRatios = new Array(calleeNode.argumentNames.length);
+ }
+ const calleeBitRatio = calleeNode.argumentBitRatios[i];
+ if (typeof calleeBitRatio === 'number') {
+ if (calleeBitRatio !== bitRatio) {
+ throw new Error(`Incompatible bit ratio found at function ${functionName} at argument ${argumentName}`);
+ }
+ return calleeBitRatio;
+ }
+ calleeNode.argumentBitRatios[i] = bitRatio;
+ return bitRatio;
+ }
+
+ trackFunctionCall(functionName, calleeFunctionName, args) {
+ if (!this.functionNodeDependencies[functionName]) {
+ this.functionNodeDependencies[functionName] = new Set();
+ this.functionCalls[functionName] = [];
+ }
+ this.functionNodeDependencies[functionName].add(calleeFunctionName);
+ this.functionCalls[functionName].push(args);
+ }
+
+ getKernelResultType() {
+ return this.rootNode.returnType || this.rootNode.getType(this.rootNode.ast);
+ }
+
+ getSubKernelResultType(index) {
+ const subKernelNode = this.subKernelNodes[index];
+ let called = false;
+ for (let functionCallIndex = 0; functionCallIndex < this.rootNode.functionCalls.length; functionCallIndex++) {
+ const functionCall = this.rootNode.functionCalls[functionCallIndex];
+ if (functionCall.ast.callee.name === subKernelNode.name) {
+ called = true;
+ }
+ }
+ if (!called) {
+ throw new Error(`SubKernel ${ subKernelNode.name } never called by kernel`);
+ }
+ return subKernelNode.returnType || subKernelNode.getType(subKernelNode.getJsAST());
+ }
+
+ getReturnTypes() {
+ const result = {
+ [this.rootNode.name]: this.rootNode.getType(this.rootNode.ast),
+ };
+ const list = this.traceFunctionCalls(this.rootNode.name);
+ for (let i = 0; i < list.length; i++) {
+ const functionName = list[i];
+ const functionNode = this.functionMap[functionName];
+ result[functionName] = functionNode.getType(functionNode.ast);
+ }
+ return result;
+ }
+}
+
+module.exports = {
+ FunctionBuilder
+};
\ No newline at end of file
diff --git a/src/backend/function-node-base.js b/src/backend/function-node-base.js
deleted file mode 100644
index 04c741f1..00000000
--- a/src/backend/function-node-base.js
+++ /dev/null
@@ -1,391 +0,0 @@
-'use strict';
-
-const utils = require('../core/utils');
-const acorn = require('acorn');
-
-module.exports = class BaseFunctionNode {
-
- /**
- * @constructor FunctionNodeBase
- *
- * @desc Represents a single function, inside JS, webGL, or openGL.
- *
- * This handles all the raw state, converted state, etc. Of a single function.
- *
- * @prop {String} functionName - Name of the function
- * @prop {Function} jsFunction - The JS Function the node represents
- * @prop {String} jsFunctionString - jsFunction.toString()
- * @prop {String[]} paramNames - Parameter names of the function
- * @prop {String[]} paramTypes - Shader land parameters type assumption
- * @prop {Boolean} isRootKernel - Special indicator, for kernel function
- * @prop {String} webglFunctionString - webgl converted function string
- * @prop {String} openglFunctionString - opengl converted function string
- * @prop {String[]} calledFunctions - List of all the functions called
- * @prop {String[]} initVariables - List of variables initialized in the function
- * @prop {String[]} readVariables - List of variables read operations occur
- * @prop {String[]} writeVariables - List of variables write operations occur
- *
- * @param {GPU} gpu - The GPU instance
- * @param {String} functionName - Function name to assume, if its null, it attempts to extract from the function
- * @param {Function|String} jsFunction - JS Function to do conversion
- * @param {String[]|Object} paramTypes - Parameter type array, assumes all parameters are 'float' if null
- * @param {String} returnType - The return type, assumes 'float' if null
- *
- */
- constructor(functionName, jsFunction, options, paramTypes, returnType) {
- //
- // Internal vars setup
- //
- this.calledFunctions = [];
- this.calledFunctionsArguments = {};
- this.initVariables = [];
- this.readVariables = [];
- this.writeVariables = [];
- this.addFunction = null;
- this.isRootKernel = false;
- this.isSubKernel = false;
- this.parent = null;
- this.debug = null;
- this.prototypeOnly = null;
- this.constants = null;
- this.output = null;
-
- if (options) {
- if (options.hasOwnProperty('debug')) {
- this.debug = options.debug;
- }
- if (options.hasOwnProperty('prototypeOnly')) {
- this.prototypeOnly = options.prototypeOnly;
- }
- if (options.hasOwnProperty('constants')) {
- this.constants = options.constants;
- }
- if (options.hasOwnProperty('output')) {
- this.output = options.output;
- }
- if (options.hasOwnProperty('loopMaxIterations')) {
- this.loopMaxIterations = options.loopMaxIterations;
- }
- }
-
- //
- // Missing jsFunction object exception
- //
- if (!jsFunction) {
- throw 'jsFunction, parameter is missing';
- }
-
- //
- // Setup jsFunction and its string property + validate them
- //
- this.jsFunctionString = jsFunction.toString();
- if (!utils.isFunctionString(this.jsFunctionString)) {
- console.error('jsFunction, to string conversion check failed: not a function?', this.jsFunctionString);
- throw 'jsFunction, to string conversion check failed: not a function?';
- }
-
- if (!utils.isFunction(jsFunction)) {
- //throw 'jsFunction, is not a valid JS Function';
- this.jsFunction = null;
- } else {
- this.jsFunction = jsFunction;
- }
-
- //
- // Setup the function name property
- //
- this.functionName = functionName ||
- (jsFunction && jsFunction.name) ||
- utils.getFunctionNameFromString(this.jsFunctionString);
-
- if (!(this.functionName)) {
- throw 'jsFunction, missing name argument or value';
- }
-
- //
- // Extract parameter name, and its argument types
- //
- this.paramNames = utils.getParamNamesFromString(this.jsFunctionString);
- if (paramTypes) {
- if (Array.isArray(paramTypes)) {
- if (paramTypes.length !== this.paramNames.length) {
- throw 'Invalid argument type array length, against function length -> (' +
- paramTypes.length + ',' +
- this.paramNames.length +
- ')';
- }
- this.paramTypes = paramTypes;
- } else if (typeof paramTypes === 'object') {
- const paramVariableNames = Object.keys(paramTypes);
- if (paramTypes.hasOwnProperty('returns')) {
- this.returnType = paramTypes.returns;
- paramVariableNames.splice(paramVariableNames.indexOf('returns'), 1);
- }
- if (paramVariableNames.length > 0 && paramVariableNames.length !== this.paramNames.length) {
- throw 'Invalid argument type array length, against function length -> (' +
- paramVariableNames.length + ',' +
- this.paramNames.length +
- ')';
- } else {
- this.paramTypes = this.paramNames.map((key) => {
- if (paramTypes.hasOwnProperty(key)) {
- return paramTypes[key];
- } else {
- return 'float';
- }
- });
- }
- }
- } else {
- this.paramTypes = [];
- //TODO: Remove when we have proper type detection
- // for (let a = 0; a < this.paramNames.length; ++a) {
- // this.paramTypes.push();
- // }
- }
-
- //
- // Return type handling
- //
- if (!this.returnType) {
- this.returnType = returnType || 'float';
- }
- }
-
- isIdentifierConstant(paramName) {
- if (!this.constants) return false;
- return this.constants.hasOwnProperty(paramName);
- }
-
- setAddFunction(fn) {
- this.addFunction = fn;
- return this;
- }
- /**
- *
- * Core Functions
- *
- */
-
- /**
- * @memberOf FunctionNodeBase#
- * @function
- * @name getJSFunction
- *
- * @desc Gets and return the stored JS Function.
- * Note: that this internally eval the function, if only the string was provided on construction
- *
- * @returns {Function} The function object
- *
- */
- getJsFunction() {
- if (this.jsFunction) {
- return this.jsFunction;
- }
-
- if (this.jsFunctionString) {
- this.jsFunction = eval(this.jsFunctionString);
- return this.jsFunction;
- }
-
- throw 'Missing jsFunction, and jsFunctionString parameter';
- }
-
- /**
- * @memberOf FunctionNodeBase#
- * @function
- * @name astMemberExpressionUnroll
- * @desc Parses the abstract syntax tree for binary expression.
- *
- * Utility function for astCallExpression.
- *
- * @param {Object} ast - the AST object to parse
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {String} the function namespace call, unrolled
- */
- astMemberExpressionUnroll(ast, funcParam) {
- if (ast.type === 'Identifier') {
- return ast.name;
- } else if (ast.type === 'ThisExpression') {
- return 'this';
- }
-
- if (ast.type === 'MemberExpression') {
- if (ast.object && ast.property) {
- //babel sniffing
- if (ast.object.hasOwnProperty('name') && ast.object.name[0] === '_') {
- return this.astMemberExpressionUnroll(ast.property, funcParam);
- }
-
- return (
- this.astMemberExpressionUnroll(ast.object, funcParam) +
- '.' +
- this.astMemberExpressionUnroll(ast.property, funcParam)
- );
- }
- }
-
- //babel sniffing
- if (ast.hasOwnProperty('expressions')) {
- const firstExpression = ast.expressions[0];
- if (firstExpression.type === 'Literal' && firstExpression.value === 0 && ast.expressions.length === 2) {
- return this.astMemberExpressionUnroll(ast.expressions[1]);
- }
- }
-
- // Failure, unknown expression
- throw this.astErrorOutput(
- 'Unknown CallExpression_unroll',
- ast, funcParam
- );
- }
-
- /**
- * @memberOf FunctionNodeBase#
- * @function
- * @name getJsAST
- *
- * @desc Parses the class function JS, and returns its Abstract Syntax Tree object.
- *
- * This is used internally to convert to shader code
- *
- * @param {JISONParser} inParser - Parser to use, assumes in scope 'parser' if null
- *
- * @returns {ASTObject} The function AST Object, note that result is cached under this.jsFunctionAST;
- *
- */
- getJsAST(inParser) {
- if (this.jsFunctionAST) {
- return this.jsFunctionAST;
- }
-
- inParser = inParser || acorn;
- if (inParser === null) {
- throw 'Missing JS to AST parser';
- }
-
- const ast = inParser.parse('var ' + this.functionName + ' = ' + this.jsFunctionString + ';', {
- locations: true
- });
- if (ast === null) {
- throw 'Failed to parse JS code';
- }
-
- // take out the function object, outside the var declarations
- const funcAST = ast.body[0].declarations[0].init;
- this.jsFunctionAST = funcAST;
-
- return funcAST;
- }
-
-
- /**
- * @memberOf FunctionNodeBase#
- * @function
- * @name getFunctionString
- *
- * @desc Returns the converted webgl shader function equivalent of the JS function
- *
- * @returns {String} webgl function string, result is cached under this.webGlFunctionString
- *
- */
- getFunctionString() {
- this.generate();
- return this.functionString;
- }
-
- /**
- * @memberOf FunctionNodeBase#
- * @function
- * @name setFunctionString
- *
- * @desc Set the functionString value, overwriting it
- *
- * @param {String} functionString - Shader code string, representing the function
- *
- */
- setFunctionString(functionString) {
- this.functionString = functionString;
- }
-
- /**
- * @memberOf FunctionNodeBase#
- * @function
- * @name getParamType
- *
- * @desc Return the type of parameter sent to subKernel/Kernel.
- *
- * @param {String} paramName - Name of the parameter
- *
- * @returns {String} Type of the parameter
- *
- */
- getParamType(paramName) {
- const paramIndex = this.paramNames.indexOf(paramName);
- if (paramIndex === -1) return null;
- if (!this.parent) return null;
- if (this.paramTypes[paramIndex]) return this.paramTypes[paramIndex];
- const calledFunctionArguments = this.parent.calledFunctionsArguments[this.functionName];
- for (let i = 0; i < calledFunctionArguments.length; i++) {
- const calledFunctionArgument = calledFunctionArguments[i];
- if (calledFunctionArgument[paramIndex] !== null) {
- return this.paramTypes[paramIndex] = calledFunctionArgument[paramIndex].type;
- }
- }
- return null;
- }
-
- /**
- * @memberOf FunctionNodeBase#
- * @function
- * @name getUserParamName
- *
- * @desc Return the name of the *user parameter*(subKernel parameter) corresponding
- * to the parameter supplied to the kernel
- *
- * @param {String} paramName - Name of the parameter
- *
- * @returns {String} Name of the parameter
- *
- */
- getUserParamName(paramName) {
- const paramIndex = this.paramNames.indexOf(paramName);
- if (paramIndex === -1) return null;
- if (!this.parent) return null;
- const calledFunctionArguments = this.parent.calledFunctionsArguments[this.functionName];
- for (let i = 0; i < calledFunctionArguments.length; i++) {
- const calledFunctionArgument = calledFunctionArguments[i];
- if (calledFunctionArgument[paramIndex] !== null) {
- return calledFunctionArgument[paramIndex].name;
- }
- }
- return null;
- }
-
- generate(options) {
- throw new Error('generate not defined on BaseFunctionNode');
- }
-
- /**
- * @function
- * @name astErrorOutput
- * @ignore
- * @desc To throw the AST error, with its location.
- *
- * @todo add location support fpr the AST error
- *
- * @param {Object} error - the error message output
- * @param {Object} ast - the AST object where the error is
- * @param {Object} funcParam - FunctionNode, that tracks compilation state
- */
- astErrorOutput(error, ast, funcParam) {
- console.error(utils.getAstString(this.jsFunctionString, ast));
- console.error(error, ast, funcParam);
- return error;
- }
-
- astDebuggerStatement(arrNode, retArr, funcParam) {
- return retArr;
- }
-};
\ No newline at end of file
diff --git a/src/backend/function-node.js b/src/backend/function-node.js
new file mode 100644
index 00000000..3946b1a3
--- /dev/null
+++ b/src/backend/function-node.js
@@ -0,0 +1,1498 @@
+const acorn = require('acorn');
+const { utils } = require('../utils');
+const { FunctionTracer } = require('./function-tracer');
+
+/**
+ *
+ * @desc Represents a single function, inside JS, webGL, or openGL.
+ * This handles all the raw state, converted state, etc. Of a single function.
+ */
+class FunctionNode {
+ /**
+ *
+ * @param {string|object} source
+ * @param {IFunctionSettings} [settings]
+ */
+ constructor(source, settings) {
+ if (!source && !settings.ast) {
+ throw new Error('source parameter is missing');
+ }
+ settings = settings || {};
+ this.source = source;
+ this.ast = null;
+ this.name = typeof source === 'string' ? settings.isRootKernel ?
+ 'kernel' :
+ (settings.name || utils.getFunctionNameFromString(source)) : null;
+ this.calledFunctions = [];
+ this.constants = {};
+ this.constantTypes = {};
+ this.constantBitRatios = {};
+ this.isRootKernel = false;
+ this.isSubKernel = false;
+ 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 = (typeof this.source === 'string' ? utils.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 = false;
+ this.fixIntegerDivisionAccuracy = null;
+
+ if (settings) {
+ for (const p in settings) {
+ if (!settings.hasOwnProperty(p)) continue;
+ if (!this.hasOwnProperty(p)) continue;
+ this[p] = settings[p];
+ }
+ }
+
+ this.literalTypes = {};
+
+ this.validate();
+ this._string = null;
+ this._internalVariableNames = {};
+ }
+
+ validate() {
+ if (typeof this.source !== 'string' && !this.ast) {
+ throw new Error('this.source not a string');
+ }
+
+ if (!this.ast && !utils.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');
+ }
+ }
+
+ /**
+ * @param {String} name
+ * @returns {boolean}
+ */
+ isIdentifierConstant(name) {
+ if (!this.constants) return false;
+ return this.constants.hasOwnProperty(name);
+ }
+
+ isInput(argumentName) {
+ return this.argumentTypes[this.argumentNames.indexOf(argumentName)] === 'Input';
+ }
+
+ pushState(state) {
+ this.states.push(state);
+ }
+
+ popState(state) {
+ if (this.state !== state) {
+ throw new Error(`Cannot popState ${ state } when in ${ this.state }`);
+ }
+ this.states.pop();
+ }
+
+ isState(state) {
+ return this.state === state;
+ }
+
+ get state() {
+ return this.states[this.states.length - 1];
+ }
+
+ /**
+ * @function
+ * @name astMemberExpressionUnroll
+ * @desc Parses the abstract syntax tree for binary expression.
+ *
+ * Utility function for astCallExpression.
+ *
+ * @param {Object} ast - the AST object to parse
+ *
+ * @returns {String} the function namespace call, unrolled
+ */
+ astMemberExpressionUnroll(ast) {
+ if (ast.type === 'Identifier') {
+ return ast.name;
+ } else if (ast.type === 'ThisExpression') {
+ return 'this';
+ }
+
+ if (ast.type === 'MemberExpression') {
+ if (ast.object && ast.property) {
+ //babel sniffing
+ if (ast.object.hasOwnProperty('name') && ast.object.name !== 'Math') {
+ return this.astMemberExpressionUnroll(ast.property);
+ }
+
+ return (
+ this.astMemberExpressionUnroll(ast.object) +
+ '.' +
+ this.astMemberExpressionUnroll(ast.property)
+ );
+ }
+ }
+
+ //babel sniffing
+ if (ast.hasOwnProperty('expressions')) {
+ const firstExpression = ast.expressions[0];
+ if (firstExpression.type === 'Literal' && firstExpression.value === 0 && ast.expressions.length === 2) {
+ return this.astMemberExpressionUnroll(ast.expressions[1]);
+ }
+ }
+
+ // Failure, unknown expression
+ throw this.astErrorOutput('Unknown astMemberExpressionUnroll', ast);
+ }
+
+ /**
+ * @desc Parses the class function JS, and returns its Abstract Syntax Tree object.
+ * This is used internally to convert to shader code
+ *
+ * @param {Object} [inParser] - Parser to use, assumes in scope 'parser' if null or undefined
+ *
+ * @returns {Object} The function AST Object, note that result is cached under this.ast;
+ */
+ getJsAST(inParser) {
+ if (this.ast) {
+ return this.ast;
+ }
+ if (typeof this.source === 'object') {
+ this.traceFunctionAST(this.source);
+ return this.ast = this.source;
+ }
+
+ inParser = inParser || acorn;
+ if (inParser === null) {
+ throw new Error('Missing JS to AST parser');
+ }
+
+ const ast = Object.freeze(inParser.parse(`const parser_${ this.name } = ${ this.source };`, {
+ locations: true
+ }));
+ // take out the function object, outside the var declarations
+ const functionAST = ast.body[0].declarations[0].init;
+ this.traceFunctionAST(functionAST);
+
+ if (!ast) {
+ throw new Error('Failed to parse JS code');
+ }
+
+ return this.ast = functionAST;
+ }
+
+ traceFunctionAST(ast) {
+ const { contexts, declarations, functions, identifiers, functionCalls } = new FunctionTracer(ast);
+ this.contexts = contexts;
+ this.identifiers = identifiers;
+ this.functionCalls = functionCalls;
+ this.functions = functions;
+ for (let i = 0; i < declarations.length; i++) {
+ const declaration = declarations[i];
+ const { ast, inForLoopInit, inForLoopTest } = declaration;
+ const { init } = ast;
+ const dependencies = this.getDependencies(init);
+ let valueType = null;
+
+ if (inForLoopInit && inForLoopTest) {
+ valueType = 'Integer';
+ } else {
+ if (init) {
+ const realType = this.getType(init);
+ switch (realType) {
+ case 'Integer':
+ case 'Float':
+ case 'Number':
+ if (init.type === 'MemberExpression') {
+ valueType = realType;
+ } else {
+ valueType = 'Number';
+ }
+ break;
+ case 'LiteralInteger':
+ valueType = 'Number';
+ break;
+ default:
+ valueType = realType;
+ }
+ }
+ }
+ declaration.valueType = valueType;
+ declaration.dependencies = dependencies;
+ declaration.isSafe = this.isSafeDependencies(dependencies);
+ }
+
+ for (let i = 0; i < functions.length; i++) {
+ this.onNestedFunction(functions[i], this.source);
+ }
+ }
+
+ getDeclaration(ast) {
+ for (let i = 0; i < this.identifiers.length; i++) {
+ const identifier = this.identifiers[i];
+ if (ast === identifier.ast) {
+ return identifier.declaration;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @desc Return the type of parameter sent to subKernel/Kernel.
+ * @param {Object} ast - Identifier
+ * @returns {String} Type of the parameter
+ */
+ getVariableType(ast) {
+ if (ast.type !== 'Identifier') {
+ throw new Error(`ast of ${ast.type} not "Identifier"`);
+ }
+ let type = null;
+ const argumentIndex = this.argumentNames.indexOf(ast.name);
+ if (argumentIndex === -1) {
+ const declaration = this.getDeclaration(ast);
+ if (declaration) {
+ return declaration.valueType;
+ }
+ } else {
+ const argumentType = this.argumentTypes[argumentIndex];
+ if (argumentType) {
+ type = argumentType;
+ }
+ }
+ if (!type && this.strictTypingChecking) {
+ throw new Error(`Declaration of ${name} not found`);
+ }
+ return type;
+ }
+
+ /**
+ * Generally used to lookup the value type returned from a member expressions
+ * @param {String} type
+ * @return {String}
+ */
+ getLookupType(type) {
+ if (!typeLookupMap.hasOwnProperty(type)) {
+ throw new Error(`unknown typeLookupMap ${ type }`);
+ }
+ return typeLookupMap[type];
+ }
+
+ getConstantType(constantName) {
+ if (this.constantTypes[constantName]) {
+ const type = this.constantTypes[constantName];
+ if (type === 'Float') {
+ return 'Number';
+ } else {
+ return type;
+ }
+ }
+ throw new Error(`Type for constant "${ constantName }" not declared`);
+ }
+
+ toString() {
+ if (this._string) return this._string;
+ return this._string = this.astGeneric(this.getJsAST(), []).join('').trim();
+ }
+
+ toJSON() {
+ const settings = {
+ source: this.source,
+ name: this.name,
+ constants: this.constants,
+ constantTypes: this.constantTypes,
+ isRootKernel: this.isRootKernel,
+ isSubKernel: this.isSubKernel,
+ debug: this.debug,
+ output: this.output,
+ loopMaxIterations: this.loopMaxIterations,
+ argumentNames: this.argumentNames,
+ argumentTypes: this.argumentTypes,
+ argumentSizes: this.argumentSizes,
+ returnType: this.returnType,
+ leadingReturnStatement: this.leadingReturnStatement,
+ followingReturnStatement: this.followingReturnStatement,
+ };
+
+ return {
+ ast: this.ast,
+ settings
+ };
+ }
+
+ /**
+ * Recursively looks up type for ast expression until it's found
+ * @param ast
+ * @returns {String|null}
+ */
+ getType(ast) {
+ if (Array.isArray(ast)) {
+ return this.getType(ast[ast.length - 1]);
+ }
+ switch (ast.type) {
+ case 'BlockStatement':
+ return this.getType(ast.body);
+ case 'ArrayExpression':
+ const childType = this.getType(ast.elements[0]);
+ switch (childType) {
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ return `Matrix(${ast.elements.length})`;
+ }
+ return `Array(${ ast.elements.length })`;
+ case 'Literal':
+ const literalKey = this.astKey(ast);
+ if (this.literalTypes[literalKey]) {
+ return this.literalTypes[literalKey];
+ }
+ if (Number.isInteger(ast.value)) {
+ return 'LiteralInteger';
+ } else if (ast.value === true || ast.value === false) {
+ return 'Boolean';
+ } else {
+ return 'Number';
+ }
+ case 'AssignmentExpression':
+ return this.getType(ast.left);
+ case 'CallExpression':
+ if (this.isAstMathFunction(ast)) {
+ return 'Number';
+ }
+ if (!ast.callee || !ast.callee.name) {
+ if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[ast.callee.expressions.length - 1].property.name) {
+ const functionName = ast.callee.expressions[ast.callee.expressions.length - 1].property.name;
+ this.inferArgumentTypesIfNeeded(functionName, ast.arguments);
+ return this.lookupReturnType(functionName, ast, this);
+ }
+ if (this.getVariableSignature(ast.callee, true) === 'this.color') {
+ return null;
+ }
+ if (ast.callee.type === 'MemberExpression' && ast.callee.object && ast.callee.property && ast.callee.property.name && ast.arguments) {
+ const functionName = ast.callee.property.name;
+ this.inferArgumentTypesIfNeeded(functionName, ast.arguments);
+ return this.lookupReturnType(functionName, ast, this);
+ }
+ throw this.astErrorOutput('Unknown call expression', ast);
+ }
+ if (ast.callee && ast.callee.name) {
+ const functionName = ast.callee.name;
+ this.inferArgumentTypesIfNeeded(functionName, ast.arguments);
+ return this.lookupReturnType(functionName, ast, this);
+ }
+ throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast);
+ case 'LogicalExpression':
+ return 'Boolean';
+ case 'BinaryExpression':
+ // modulos is Number
+ switch (ast.operator) {
+ case '%':
+ case '/':
+ if (this.fixIntegerDivisionAccuracy) {
+ return 'Number';
+ } else {
+ break;
+ }
+ case '>':
+ case '<':
+ return 'Boolean';
+ case '&':
+ case '|':
+ case '^':
+ case '<<':
+ case '>>':
+ case '>>>':
+ return 'Integer';
+ }
+ const type = this.getType(ast.left);
+ if (this.isState('skip-literal-correction')) return type;
+ if (type === 'LiteralInteger') {
+ const rightType = this.getType(ast.right);
+ if (rightType === 'LiteralInteger') {
+ if (ast.left.value % 1 === 0) {
+ return 'Integer';
+ } else {
+ return 'Float';
+ }
+ }
+ return rightType;
+ }
+ return typeLookupMap[type] || type;
+ case 'UpdateExpression':
+ return this.getType(ast.argument);
+ case 'UnaryExpression':
+ if (ast.operator === '~') {
+ return 'Integer';
+ }
+ return this.getType(ast.argument);
+ case 'VariableDeclaration': {
+ const declarations = ast.declarations;
+ let lastType;
+ for (let i = 0; i < declarations.length; i++) {
+ const declaration = declarations[i];
+ lastType = this.getType(declaration);
+ }
+ if (!lastType) {
+ throw this.astErrorOutput(`Unable to find type for declaration`, ast);
+ }
+ return lastType;
+ }
+ case 'VariableDeclarator':
+ const declaration = this.getDeclaration(ast.id);
+ if (!declaration) {
+ throw this.astErrorOutput(`Unable to find declarator`, ast);
+ }
+
+ if (!declaration.valueType) {
+ throw this.astErrorOutput(`Unable to find declarator valueType`, ast);
+ }
+
+ return declaration.valueType;
+ case 'Identifier':
+ if (ast.name === 'Infinity') {
+ return 'Number';
+ }
+ if (this.isAstVariable(ast)) {
+ const signature = this.getVariableSignature(ast);
+ if (signature === 'value') {
+ return this.getCheckVariableType(ast);
+ }
+ }
+ const origin = this.findIdentifierOrigin(ast);
+ if (origin && origin.init) {
+ return this.getType(origin.init);
+ }
+ return null;
+ case 'ReturnStatement':
+ return this.getType(ast.argument);
+ case 'MemberExpression':
+ if (this.isAstMathFunction(ast)) {
+ switch (ast.property.name) {
+ case 'ceil':
+ return 'Integer';
+ case 'floor':
+ return 'Integer';
+ case 'round':
+ return 'Integer';
+ }
+ return 'Number';
+ }
+ if (this.isAstVariable(ast)) {
+ const variableSignature = this.getVariableSignature(ast);
+ switch (variableSignature) {
+ case 'value[]':
+ return this.getLookupType(this.getCheckVariableType(ast.object));
+ case 'value[][]':
+ return this.getLookupType(this.getCheckVariableType(ast.object.object));
+ case 'value[][][]':
+ return this.getLookupType(this.getCheckVariableType(ast.object.object.object));
+ case 'value[][][][]':
+ return this.getLookupType(this.getCheckVariableType(ast.object.object.object.object));
+ case 'value.thread.value':
+ case 'this.thread.value':
+ return 'Integer';
+ case 'this.output.value':
+ return this.dynamicOutput ? 'Integer' : 'LiteralInteger';
+ case 'this.constants.value':
+ return this.getConstantType(ast.property.name);
+ case 'this.constants.value[]':
+ return this.getLookupType(this.getConstantType(ast.object.property.name));
+ case 'this.constants.value[][]':
+ return this.getLookupType(this.getConstantType(ast.object.object.property.name));
+ case 'this.constants.value[][][]':
+ return this.getLookupType(this.getConstantType(ast.object.object.object.property.name));
+ case 'this.constants.value[][][][]':
+ return this.getLookupType(this.getConstantType(ast.object.object.object.object.property.name));
+ case 'fn()[]':
+ case 'fn()[][]':
+ case 'fn()[][][]':
+ return this.getLookupType(this.getType(ast.object));
+ case 'value.value':
+ if (this.isAstMathVariable(ast)) {
+ return 'Number';
+ }
+ switch (ast.property.name) {
+ case 'r':
+ case 'g':
+ case 'b':
+ case 'a':
+ return this.getLookupType(this.getCheckVariableType(ast.object));
+ }
+ case '[][]':
+ return 'Number';
+ }
+ throw this.astErrorOutput('Unhandled getType MemberExpression', ast);
+ }
+ throw this.astErrorOutput('Unhandled getType MemberExpression', ast);
+ case 'ConditionalExpression':
+ return this.getType(ast.consequent);
+ case 'FunctionDeclaration':
+ case 'FunctionExpression':
+ const lastReturn = this.findLastReturn(ast.body);
+ if (lastReturn) {
+ return this.getType(lastReturn);
+ }
+ return null;
+ case 'IfStatement':
+ return this.getType(ast.consequent);
+ case 'SequenceExpression':
+ return this.getType(ast.expressions[ast.expressions.length - 1]);
+ default:
+ throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast);
+ }
+ }
+
+ getCheckVariableType(ast) {
+ const type = this.getVariableType(ast);
+ if (!type) {
+ throw this.astErrorOutput(`${ast.type} is not defined`, ast);
+ }
+ return type;
+ }
+
+ inferArgumentTypesIfNeeded(functionName, args) {
+ // ensure arguments are filled in, so when we lookup return type, we already can infer it
+ for (let i = 0; i < args.length; i++) {
+ if (!this.needsArgumentType(functionName, i)) continue;
+ const type = this.getType(args[i]);
+ if (!type) {
+ throw this.astErrorOutput(`Unable to infer argument ${i}`, args[i]);
+ }
+ this.assignArgumentType(functionName, i, type);
+ }
+ }
+
+ isAstMathVariable(ast) {
+ const mathProperties = [
+ 'E',
+ 'PI',
+ 'SQRT2',
+ 'SQRT1_2',
+ 'LN2',
+ 'LN10',
+ 'LOG2E',
+ 'LOG10E',
+ ];
+ return ast.type === 'MemberExpression' &&
+ ast.object && ast.object.type === 'Identifier' &&
+ ast.object.name === 'Math' &&
+ ast.property &&
+ ast.property.type === 'Identifier' &&
+ mathProperties.indexOf(ast.property.name) > -1;
+ }
+
+ isAstMathFunction(ast) {
+ const mathFunctions = [
+ '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',
+ ];
+ return ast.type === 'CallExpression' &&
+ ast.callee &&
+ ast.callee.type === 'MemberExpression' &&
+ ast.callee.object &&
+ ast.callee.object.type === 'Identifier' &&
+ ast.callee.object.name === 'Math' &&
+ ast.callee.property &&
+ ast.callee.property.type === 'Identifier' &&
+ mathFunctions.indexOf(ast.callee.property.name) > -1;
+ }
+
+ isAstVariable(ast) {
+ return ast.type === 'Identifier' || ast.type === 'MemberExpression';
+ }
+
+ isSafe(ast) {
+ return this.isSafeDependencies(this.getDependencies(ast));
+ }
+
+ isSafeDependencies(dependencies) {
+ return dependencies && dependencies.every ? dependencies.every(dependency => dependency.isSafe) : true;
+ }
+
+ /**
+ *
+ * @param ast
+ * @param dependencies
+ * @param isNotSafe
+ * @return {Array}
+ */
+ getDependencies(ast, dependencies, isNotSafe) {
+ if (!dependencies) {
+ dependencies = [];
+ }
+ if (!ast) return null;
+ if (Array.isArray(ast)) {
+ for (let i = 0; i < ast.length; i++) {
+ this.getDependencies(ast[i], dependencies, isNotSafe);
+ }
+ return dependencies;
+ }
+ switch (ast.type) {
+ case 'AssignmentExpression':
+ this.getDependencies(ast.left, dependencies, isNotSafe);
+ this.getDependencies(ast.right, dependencies, isNotSafe);
+ return dependencies;
+ case 'ConditionalExpression':
+ this.getDependencies(ast.test, dependencies, isNotSafe);
+ this.getDependencies(ast.alternate, dependencies, isNotSafe);
+ this.getDependencies(ast.consequent, dependencies, isNotSafe);
+ return dependencies;
+ case 'Literal':
+ dependencies.push({
+ origin: 'literal',
+ value: ast.value,
+ isSafe: isNotSafe === true ? false : ast.value > -Infinity && ast.value < Infinity && !isNaN(ast.value)
+ });
+ break;
+ case 'VariableDeclarator':
+ return this.getDependencies(ast.init, dependencies, isNotSafe);
+ case 'Identifier':
+ const declaration = this.getDeclaration(ast);
+ if (declaration) {
+ dependencies.push({
+ name: ast.name,
+ origin: 'declaration',
+ isSafe: isNotSafe ? false : this.isSafeDependencies(declaration.dependencies),
+ });
+ } else if (this.argumentNames.indexOf(ast.name) > -1) {
+ dependencies.push({
+ name: ast.name,
+ origin: 'argument',
+ isSafe: false,
+ });
+ } else if (this.strictTypingChecking) {
+ throw new Error(`Cannot find identifier origin "${ast.name}"`);
+ }
+ break;
+ case 'FunctionDeclaration':
+ return this.getDependencies(ast.body.body[ast.body.body.length - 1], dependencies, isNotSafe);
+ case 'ReturnStatement':
+ return this.getDependencies(ast.argument, dependencies);
+ case 'BinaryExpression':
+ case 'LogicalExpression':
+ isNotSafe = (ast.operator === '/' || ast.operator === '*');
+ this.getDependencies(ast.left, dependencies, isNotSafe);
+ this.getDependencies(ast.right, dependencies, isNotSafe);
+ return dependencies;
+ case 'UnaryExpression':
+ case 'UpdateExpression':
+ return this.getDependencies(ast.argument, dependencies, isNotSafe);
+ case 'VariableDeclaration':
+ return this.getDependencies(ast.declarations, dependencies, isNotSafe);
+ case 'ArrayExpression':
+ dependencies.push({
+ origin: 'declaration',
+ isSafe: true,
+ });
+ return dependencies;
+ case 'CallExpression':
+ dependencies.push({
+ origin: 'function',
+ isSafe: true,
+ });
+ return dependencies;
+ case 'MemberExpression':
+ const details = this.getMemberExpressionDetails(ast);
+ switch (details.signature) {
+ case 'value[]':
+ this.getDependencies(ast.object, dependencies, isNotSafe);
+ break;
+ case 'value[][]':
+ this.getDependencies(ast.object.object, dependencies, isNotSafe);
+ break;
+ case 'value[][][]':
+ this.getDependencies(ast.object.object.object, dependencies, isNotSafe);
+ break;
+ case 'this.output.value':
+ if (this.dynamicOutput) {
+ dependencies.push({
+ name: details.name,
+ origin: 'output',
+ isSafe: false,
+ });
+ }
+ break;
+ }
+ if (details) {
+ if (details.property) {
+ this.getDependencies(details.property, dependencies, isNotSafe);
+ }
+ if (details.xProperty) {
+ this.getDependencies(details.xProperty, dependencies, isNotSafe);
+ }
+ if (details.yProperty) {
+ this.getDependencies(details.yProperty, dependencies, isNotSafe);
+ }
+ if (details.zProperty) {
+ this.getDependencies(details.zProperty, dependencies, isNotSafe);
+ }
+ return dependencies;
+ }
+ case 'SequenceExpression':
+ return this.getDependencies(ast.expressions, dependencies, isNotSafe);
+ default:
+ throw this.astErrorOutput(`Unhandled type ${ ast.type } in getDependencies`, ast);
+ }
+ return dependencies;
+ }
+
+ getVariableSignature(ast, returnRawValue) {
+ if (!this.isAstVariable(ast)) {
+ throw new Error(`ast of type "${ ast.type }" is not a variable signature`);
+ }
+ if (ast.type === 'Identifier') {
+ return 'value';
+ }
+ const signature = [];
+ while (true) {
+ if (!ast) break;
+ if (ast.computed) {
+ signature.push('[]');
+ } else if (ast.type === 'ThisExpression') {
+ signature.unshift('this');
+ } else if (ast.property && ast.property.name) {
+ if (
+ ast.property.name === 'x' ||
+ ast.property.name === 'y' ||
+ ast.property.name === 'z'
+ ) {
+ signature.unshift(returnRawValue ? '.' + ast.property.name : '.value');
+ } else if (
+ ast.property.name === 'constants' ||
+ ast.property.name === 'thread' ||
+ ast.property.name === 'output'
+ ) {
+ signature.unshift('.' + ast.property.name);
+ } else {
+ signature.unshift(returnRawValue ? '.' + ast.property.name : '.value');
+ }
+ } else if (ast.name) {
+ signature.unshift(returnRawValue ? ast.name : 'value');
+ } else if (ast.callee && ast.callee.name) {
+ signature.unshift(returnRawValue ? ast.callee.name + '()' : 'fn()');
+ } else if (ast.elements) {
+ signature.unshift('[]');
+ } else {
+ signature.unshift('unknown');
+ }
+ ast = ast.object;
+ }
+
+ const signatureString = signature.join('');
+ if (returnRawValue) {
+ return signatureString;
+ }
+
+ const allowedExpressions = [
+ '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()[][][]',
+ '[][]',
+ ];
+ if (allowedExpressions.indexOf(signatureString) > -1) {
+ return signatureString;
+ }
+ return null;
+ }
+
+ build() {
+ return this.toString().length > 0;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for generically to its respective function
+ * @param {Object} ast - the AST object to parse
+ * @param {Array} retArr - return array string
+ * @returns {Array} the parsed string array
+ */
+ astGeneric(ast, retArr) {
+ if (ast === null) {
+ throw this.astErrorOutput('NULL ast', ast);
+ } else {
+ if (Array.isArray(ast)) {
+ for (let i = 0; i < ast.length; i++) {
+ this.astGeneric(ast[i], retArr);
+ }
+ return retArr;
+ }
+
+ switch (ast.type) {
+ case 'FunctionDeclaration':
+ return this.astFunctionDeclaration(ast, retArr);
+ case 'FunctionExpression':
+ return this.astFunctionExpression(ast, retArr);
+ case 'ReturnStatement':
+ return this.astReturnStatement(ast, retArr);
+ case 'Literal':
+ return this.astLiteral(ast, retArr);
+ case 'BinaryExpression':
+ return this.astBinaryExpression(ast, retArr);
+ case 'Identifier':
+ return this.astIdentifierExpression(ast, retArr);
+ case 'AssignmentExpression':
+ return this.astAssignmentExpression(ast, retArr);
+ case 'ExpressionStatement':
+ return this.astExpressionStatement(ast, retArr);
+ case 'EmptyStatement':
+ return this.astEmptyStatement(ast, retArr);
+ case 'BlockStatement':
+ return this.astBlockStatement(ast, retArr);
+ case 'IfStatement':
+ return this.astIfStatement(ast, retArr);
+ case 'SwitchStatement':
+ return this.astSwitchStatement(ast, retArr);
+ case 'BreakStatement':
+ return this.astBreakStatement(ast, retArr);
+ case 'ContinueStatement':
+ return this.astContinueStatement(ast, retArr);
+ case 'ForStatement':
+ return this.astForStatement(ast, retArr);
+ case 'WhileStatement':
+ return this.astWhileStatement(ast, retArr);
+ case 'DoWhileStatement':
+ return this.astDoWhileStatement(ast, retArr);
+ case 'VariableDeclaration':
+ return this.astVariableDeclaration(ast, retArr);
+ case 'VariableDeclarator':
+ return this.astVariableDeclarator(ast, retArr);
+ case 'ThisExpression':
+ return this.astThisExpression(ast, retArr);
+ case 'SequenceExpression':
+ return this.astSequenceExpression(ast, retArr);
+ case 'UnaryExpression':
+ return this.astUnaryExpression(ast, retArr);
+ case 'UpdateExpression':
+ return this.astUpdateExpression(ast, retArr);
+ case 'LogicalExpression':
+ return this.astLogicalExpression(ast, retArr);
+ case 'MemberExpression':
+ return this.astMemberExpression(ast, retArr);
+ case 'CallExpression':
+ return this.astCallExpression(ast, retArr);
+ case 'ArrayExpression':
+ return this.astArrayExpression(ast, retArr);
+ case 'DebuggerStatement':
+ return this.astDebuggerStatement(ast, retArr);
+ case 'ConditionalExpression':
+ return this.astConditionalExpression(ast, retArr);
+ }
+
+ throw this.astErrorOutput('Unknown ast type : ' + ast.type, ast);
+ }
+ }
+ /**
+ * @desc To throw the AST error, with its location.
+ * @param {string} error - the error message output
+ * @param {Object} ast - the AST object where the error is
+ */
+ astErrorOutput(error, ast) {
+ if (typeof this.source !== 'string') {
+ return new Error(error);
+ }
+
+ const debugString = utils.getAstString(this.source, ast);
+ const leadingSource = this.source.substr(ast.start);
+ const splitLines = leadingSource.split(/\n/);
+ const lineBefore = splitLines.length > 0 ? splitLines[splitLines.length - 1] : 0;
+ return new Error(`${error} on line ${ splitLines.length }, position ${ lineBefore.length }:\n ${ debugString }`);
+ }
+
+ astDebuggerStatement(arrNode, retArr) {
+ return retArr;
+ }
+
+ astConditionalExpression(ast, retArr) {
+ if (ast.type !== 'ConditionalExpression') {
+ throw this.astErrorOutput('Not a conditional expression', ast);
+ }
+ retArr.push('(');
+ this.astGeneric(ast.test, retArr);
+ retArr.push('?');
+ this.astGeneric(ast.consequent, retArr);
+ retArr.push(':');
+ this.astGeneric(ast.alternate, retArr);
+ retArr.push(')');
+ return retArr;
+ }
+
+ /**
+ * @abstract
+ * @param {Object} ast
+ * @param {String[]} retArr
+ * @returns {String[]}
+ */
+ astFunction(ast, retArr) {
+ throw new Error(`"astFunction" not defined on ${ this.constructor.name }`);
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for to its *named function declaration*
+ * @param {Object} ast - the AST object to parse
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astFunctionDeclaration(ast, retArr) {
+ if (this.isChildFunction(ast)) {
+ return retArr;
+ }
+ return this.astFunction(ast, retArr);
+ }
+ astFunctionExpression(ast, retArr) {
+ if (this.isChildFunction(ast)) {
+ return retArr;
+ }
+ return this.astFunction(ast, retArr);
+ }
+ isChildFunction(ast) {
+ for (let i = 0; i < this.functions.length; i++) {
+ if (this.functions[i] === ast) {
+ return true;
+ }
+ }
+ return false;
+ }
+ astReturnStatement(ast, retArr) {
+ return retArr;
+ }
+ astLiteral(ast, retArr) {
+ this.literalTypes[this.astKey(ast)] = 'Number';
+ return retArr;
+ }
+ astBinaryExpression(ast, retArr) {
+ return retArr;
+ }
+ astIdentifierExpression(ast, retArr) {
+ return retArr;
+ }
+ astAssignmentExpression(ast, retArr) {
+ return retArr;
+ }
+ /**
+ * @desc Parses the abstract syntax tree for *generic expression* statement
+ * @param {Object} esNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astExpressionStatement(esNode, retArr) {
+ this.astGeneric(esNode.expression, retArr);
+ retArr.push(';');
+ return retArr;
+ }
+ /**
+ * @desc Parses the abstract syntax tree for an *Empty* Statement
+ * @param {Object} eNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astEmptyStatement(eNode, retArr) {
+ return retArr;
+ }
+ astBlockStatement(ast, retArr) {
+ return retArr;
+ }
+ astIfStatement(ast, retArr) {
+ return retArr;
+ }
+ astSwitchStatement(ast, retArr) {
+ return retArr;
+ }
+ /**
+ * @desc Parses the abstract syntax tree for *Break* Statement
+ * @param {Object} brNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astBreakStatement(brNode, retArr) {
+ retArr.push('break;');
+ return retArr;
+ }
+ /**
+ * @desc Parses the abstract syntax tree for *Continue* Statement
+ * @param {Object} crNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astContinueStatement(crNode, retArr) {
+ retArr.push('continue;\n');
+ return retArr;
+ }
+ astForStatement(ast, retArr) {
+ return retArr;
+ }
+ astWhileStatement(ast, retArr) {
+ return retArr;
+ }
+ astDoWhileStatement(ast, retArr) {
+ return retArr;
+ }
+ /**
+ * @desc Parses the abstract syntax tree for *Variable Declarator*
+ * @param {Object} iVarDecNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astVariableDeclarator(iVarDecNode, retArr) {
+ this.astGeneric(iVarDecNode.id, retArr);
+ if (iVarDecNode.init !== null) {
+ retArr.push('=');
+ this.astGeneric(iVarDecNode.init, retArr);
+ }
+ return retArr;
+ }
+ astThisExpression(ast, retArr) {
+ return retArr;
+ }
+ astSequenceExpression(sNode, retArr) {
+ const { expressions } = sNode;
+ const sequenceResult = [];
+ for (let i = 0; i < expressions.length; i++) {
+ const expression = expressions[i];
+ const expressionResult = [];
+ this.astGeneric(expression, expressionResult);
+ sequenceResult.push(expressionResult.join(''));
+ }
+ if (sequenceResult.length > 1) {
+ retArr.push('(', sequenceResult.join(','), ')');
+ } else {
+ retArr.push(sequenceResult[0]);
+ }
+ return retArr;
+ }
+ /**
+ * @desc Parses the abstract syntax tree for *Unary* Expression
+ * @param {Object} uNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astUnaryExpression(uNode, retArr) {
+ const unaryResult = this.checkAndUpconvertBitwiseUnary(uNode, retArr);
+ if (unaryResult) {
+ 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;
+ }
+
+ checkAndUpconvertBitwiseUnary(uNode, retArr) {}
+
+ /**
+ * @desc Parses the abstract syntax tree for *Update* Expression
+ * @param {Object} uNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astUpdateExpression(uNode, 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;
+ }
+ /**
+ * @desc Parses the abstract syntax tree for *Logical* Expression
+ * @param {Object} logNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astLogicalExpression(logNode, retArr) {
+ retArr.push('(');
+ this.astGeneric(logNode.left, retArr);
+ retArr.push(logNode.operator);
+ this.astGeneric(logNode.right, retArr);
+ retArr.push(')');
+ return retArr;
+ }
+ astMemberExpression(ast, retArr) {
+ return retArr;
+ }
+ astCallExpression(ast, retArr) {
+ return retArr;
+ }
+ astArrayExpression(ast, retArr) {
+ return retArr;
+ }
+
+ /**
+ *
+ * @param ast
+ * @return {IFunctionNodeMemberExpressionDetails}
+ */
+ getMemberExpressionDetails(ast) {
+ if (ast.type !== 'MemberExpression') {
+ throw this.astErrorOutput(`Expression ${ ast.type } not a MemberExpression`, ast);
+ }
+ let name = null;
+ let type = null;
+ const variableSignature = this.getVariableSignature(ast);
+ switch (variableSignature) {
+ case 'value':
+ return null;
+ case 'value.thread.value':
+ case 'this.thread.value':
+ case 'this.output.value':
+ return {
+ signature: variableSignature,
+ type: 'Integer',
+ name: ast.property.name
+ };
+ case 'value[]':
+ if (typeof ast.object.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.object.name;
+ return {
+ name,
+ origin: 'user',
+ signature: variableSignature,
+ type: this.getVariableType(ast.object),
+ xProperty: ast.property
+ };
+ case 'value[][]':
+ if (typeof ast.object.object.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.object.object.name;
+ return {
+ name,
+ origin: 'user',
+ signature: variableSignature,
+ type: this.getVariableType(ast.object.object),
+ yProperty: ast.object.property,
+ xProperty: ast.property,
+ };
+ case 'value[][][]':
+ if (typeof ast.object.object.object.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.object.object.object.name;
+ return {
+ name,
+ origin: 'user',
+ signature: variableSignature,
+ type: this.getVariableType(ast.object.object.object),
+ zProperty: ast.object.object.property,
+ yProperty: ast.object.property,
+ xProperty: ast.property,
+ };
+ case 'value[][][][]':
+ if (typeof ast.object.object.object.object.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.object.object.object.object.name;
+ return {
+ name,
+ origin: 'user',
+ signature: variableSignature,
+ type: this.getVariableType(ast.object.object.object.object),
+ zProperty: ast.object.object.property,
+ yProperty: ast.object.property,
+ xProperty: ast.property,
+ };
+ case 'value.value':
+ if (typeof ast.property.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ if (this.isAstMathVariable(ast)) {
+ name = ast.property.name;
+ return {
+ name,
+ origin: 'Math',
+ type: 'Number',
+ signature: variableSignature,
+ };
+ }
+ switch (ast.property.name) {
+ case 'r':
+ case 'g':
+ case 'b':
+ case 'a':
+ name = ast.object.name;
+ return {
+ name,
+ property: ast.property.name,
+ origin: 'user',
+ signature: variableSignature,
+ type: 'Number'
+ };
+ default:
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ case 'this.constants.value':
+ if (typeof ast.property.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.property.name;
+ type = this.getConstantType(name);
+ if (!type) {
+ throw this.astErrorOutput('Constant has no type', ast);
+ }
+ return {
+ name,
+ type,
+ origin: 'constants',
+ signature: variableSignature,
+ };
+ case 'this.constants.value[]':
+ if (typeof ast.object.property.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.object.property.name;
+ type = this.getConstantType(name);
+ if (!type) {
+ throw this.astErrorOutput('Constant has no type', ast);
+ }
+ return {
+ name,
+ type,
+ origin: 'constants',
+ signature: variableSignature,
+ xProperty: ast.property,
+ };
+ case 'this.constants.value[][]': {
+ if (typeof ast.object.object.property.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.object.object.property.name;
+ type = this.getConstantType(name);
+ if (!type) {
+ throw this.astErrorOutput('Constant has no type', ast);
+ }
+ return {
+ name,
+ type,
+ origin: 'constants',
+ signature: variableSignature,
+ yProperty: ast.object.property,
+ xProperty: ast.property,
+ };
+ }
+ case 'this.constants.value[][][]': {
+ if (typeof ast.object.object.object.property.name !== 'string') {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ name = ast.object.object.object.property.name;
+ type = this.getConstantType(name);
+ if (!type) {
+ throw this.astErrorOutput('Constant has no type', ast);
+ }
+ return {
+ name,
+ type,
+ origin: 'constants',
+ signature: variableSignature,
+ zProperty: ast.object.object.property,
+ yProperty: ast.object.property,
+ xProperty: ast.property,
+ };
+ }
+ case 'fn()[]':
+ case 'fn()[][]':
+ case '[][]':
+ return {
+ signature: variableSignature,
+ property: ast.property,
+ };
+ default:
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ }
+
+ findIdentifierOrigin(astToFind) {
+ const stack = [this.ast];
+
+ while (stack.length > 0) {
+ const atNode = stack[0];
+ if (atNode.type === 'VariableDeclarator' && atNode.id && atNode.id.name && atNode.id.name === astToFind.name) {
+ return atNode;
+ }
+ stack.shift();
+ if (atNode.argument) {
+ stack.push(atNode.argument);
+ } else if (atNode.body) {
+ stack.push(atNode.body);
+ } else if (atNode.declarations) {
+ stack.push(atNode.declarations);
+ } else if (Array.isArray(atNode)) {
+ for (let i = 0; i < atNode.length; i++) {
+ stack.push(atNode[i]);
+ }
+ }
+ }
+ return null;
+ }
+
+ findLastReturn(ast) {
+ const stack = [ast || this.ast];
+
+ while (stack.length > 0) {
+ const atNode = stack.pop();
+ if (atNode.type === 'ReturnStatement') {
+ return atNode;
+ }
+ if (atNode.type === 'FunctionDeclaration') {
+ continue;
+ }
+ if (atNode.argument) {
+ stack.push(atNode.argument);
+ } else if (atNode.body) {
+ stack.push(atNode.body);
+ } else if (atNode.declarations) {
+ stack.push(atNode.declarations);
+ } else if (Array.isArray(atNode)) {
+ for (let i = 0; i < atNode.length; i++) {
+ stack.push(atNode[i]);
+ }
+ } else if (atNode.consequent) {
+ stack.push(atNode.consequent);
+ } else if (atNode.cases) {
+ stack.push(atNode.cases);
+ }
+ }
+ return null;
+ }
+
+ getInternalVariableName(name) {
+ if (!this._internalVariableNames.hasOwnProperty(name)) {
+ this._internalVariableNames[name] = 0;
+ }
+ this._internalVariableNames[name]++;
+ if (this._internalVariableNames[name] === 1) {
+ return name;
+ }
+ return name + this._internalVariableNames[name];
+ }
+
+ astKey(ast, separator = ',') {
+ if (!ast.start || !ast.end) throw new Error('AST start and end needed');
+ return `${ast.start}${separator}${ast.end}`;
+ }
+}
+
+const typeLookupMap = {
+ '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)',
+};
+
+module.exports = {
+ FunctionNode
+};
\ No newline at end of file
diff --git a/src/backend/function-tracer.js b/src/backend/function-tracer.js
new file mode 100644
index 00000000..f9779867
--- /dev/null
+++ b/src/backend/function-tracer.js
@@ -0,0 +1,311 @@
+const { utils } = require('../utils');
+
+function last(array) {
+ return array.length > 0 ? array[array.length - 1] : null;
+}
+
+const states = {
+ trackIdentifiers: 'trackIdentifiers',
+ memberExpression: 'memberExpression',
+ inForLoopInit: 'inForLoopInit'
+};
+
+class FunctionTracer {
+ constructor(ast) {
+ this.runningContexts = [];
+ this.functionContexts = [];
+ this.contexts = [];
+ this.functionCalls = [];
+ /**
+ *
+ * @type {IDeclaration[]}
+ */
+ this.declarations = [];
+ this.identifiers = [];
+ this.functions = [];
+ this.returnStatements = [];
+ this.trackedIdentifiers = null;
+ this.states = [];
+ this.newFunctionContext();
+ this.scan(ast);
+ }
+
+ isState(state) {
+ return this.states[this.states.length - 1] === state;
+ }
+
+ hasState(state) {
+ return this.states.indexOf(state) > -1;
+ }
+
+ pushState(state) {
+ this.states.push(state);
+ }
+
+ popState(state) {
+ if (this.isState(state)) {
+ this.states.pop();
+ } else {
+ throw new Error(`Cannot pop the non-active state "${state}"`);
+ }
+ }
+
+ get currentFunctionContext() {
+ return last(this.functionContexts);
+ }
+
+ get currentContext() {
+ return last(this.runningContexts);
+ }
+
+ newFunctionContext() {
+ const newContext = { '@contextType': 'function' };
+ this.contexts.push(newContext);
+ this.functionContexts.push(newContext);
+ }
+
+ newContext(run) {
+ const newContext = Object.assign({ '@contextType': 'const/let' }, this.currentContext);
+ this.contexts.push(newContext);
+ this.runningContexts.push(newContext);
+ run();
+ const { currentFunctionContext } = this;
+ for (const p in currentFunctionContext) {
+ if (!currentFunctionContext.hasOwnProperty(p) || newContext.hasOwnProperty(p)) continue;
+ newContext[p] = currentFunctionContext[p];
+ }
+ this.runningContexts.pop();
+ return newContext;
+ }
+
+ useFunctionContext(run) {
+ const functionContext = last(this.functionContexts);
+ this.runningContexts.push(functionContext);
+ run();
+ this.runningContexts.pop();
+ }
+
+ getIdentifiers(run) {
+ const trackedIdentifiers = this.trackedIdentifiers = [];
+ this.pushState(states.trackIdentifiers);
+ run();
+ this.trackedIdentifiers = null;
+ this.popState(states.trackIdentifiers);
+ return trackedIdentifiers;
+ }
+
+ /**
+ * @param {string} name
+ * @returns {IDeclaration}
+ */
+ getDeclaration(name) {
+ const { currentContext, currentFunctionContext, runningContexts } = this;
+ const declaration = currentContext[name] || currentFunctionContext[name] || null;
+
+ if (
+ !declaration &&
+ currentContext === currentFunctionContext &&
+ runningContexts.length > 0
+ ) {
+ const previousRunningContext = runningContexts[runningContexts.length - 2];
+ if (previousRunningContext[name]) {
+ return previousRunningContext[name];
+ }
+ }
+
+ return declaration;
+ }
+
+ /**
+ * Recursively scans AST for declarations and functions, and add them to their respective context
+ * @param ast
+ */
+ scan(ast) {
+ if (!ast) return;
+ if (Array.isArray(ast)) {
+ for (let i = 0; i < ast.length; i++) {
+ this.scan(ast[i]);
+ }
+ return;
+ }
+ switch (ast.type) {
+ case 'Program':
+ this.useFunctionContext(() => {
+ this.scan(ast.body);
+ });
+ break;
+ case 'BlockStatement':
+ this.newContext(() => {
+ this.scan(ast.body);
+ });
+ break;
+ case 'AssignmentExpression':
+ case 'LogicalExpression':
+ this.scan(ast.left);
+ this.scan(ast.right);
+ break;
+ case 'BinaryExpression':
+ this.scan(ast.left);
+ this.scan(ast.right);
+ break;
+ case 'UpdateExpression':
+ if (ast.operator === '++') {
+ const declaration = this.getDeclaration(ast.argument.name);
+ if (declaration) {
+ declaration.suggestedType = 'Integer';
+ }
+ }
+ this.scan(ast.argument);
+ break;
+ case 'UnaryExpression':
+ this.scan(ast.argument);
+ break;
+ case 'VariableDeclaration':
+ if (ast.kind === 'var') {
+ this.useFunctionContext(() => {
+ ast.declarations = utils.normalizeDeclarations(ast);
+ this.scan(ast.declarations);
+ });
+ } else {
+ ast.declarations = utils.normalizeDeclarations(ast);
+ this.scan(ast.declarations);
+ }
+ break;
+ case 'VariableDeclarator': {
+ const { currentContext } = this;
+ const inForLoopInit = this.hasState(states.inForLoopInit);
+ const declaration = {
+ ast: ast,
+ context: currentContext,
+ name: ast.id.name,
+ origin: 'declaration',
+ inForLoopInit,
+ inForLoopTest: null,
+ assignable: currentContext === this.currentFunctionContext || (!inForLoopInit && !currentContext.hasOwnProperty(ast.id.name)),
+ suggestedType: null,
+ valueType: null,
+ dependencies: null,
+ isSafe: null,
+ };
+ if (!currentContext[ast.id.name]) {
+ currentContext[ast.id.name] = declaration;
+ }
+ this.declarations.push(declaration);
+ this.scan(ast.id);
+ this.scan(ast.init);
+ break;
+ }
+ case 'FunctionExpression':
+ case 'FunctionDeclaration':
+ if (this.runningContexts.length === 0) {
+ this.scan(ast.body);
+ } else {
+ this.functions.push(ast);
+ }
+ break;
+ case 'IfStatement':
+ this.scan(ast.test);
+ this.scan(ast.consequent);
+ if (ast.alternate) this.scan(ast.alternate);
+ break;
+ case 'ForStatement': {
+ let testIdentifiers;
+ const context = this.newContext(() => {
+ this.pushState(states.inForLoopInit);
+ this.scan(ast.init);
+ this.popState(states.inForLoopInit);
+
+ testIdentifiers = this.getIdentifiers(() => {
+ this.scan(ast.test);
+ });
+
+ this.scan(ast.update);
+ this.newContext(() => {
+ this.scan(ast.body);
+ });
+ });
+
+ if (testIdentifiers) {
+ for (const p in context) {
+ if (p === '@contextType') continue;
+ if (testIdentifiers.indexOf(p) > -1) {
+ context[p].inForLoopTest = true;
+ }
+ }
+ }
+ break;
+ }
+ case 'DoWhileStatement':
+ case 'WhileStatement':
+ this.newContext(() => {
+ this.scan(ast.body);
+ this.scan(ast.test);
+ });
+ break;
+ case 'Identifier': {
+ if (this.isState(states.trackIdentifiers)) {
+ this.trackedIdentifiers.push(ast.name);
+ }
+ this.identifiers.push({
+ context: this.currentContext,
+ declaration: this.getDeclaration(ast.name),
+ ast,
+ });
+ break;
+ }
+ case 'ReturnStatement':
+ this.returnStatements.push(ast);
+ this.scan(ast.argument);
+ break;
+ case 'MemberExpression':
+ this.pushState(states.memberExpression);
+ this.scan(ast.object);
+ this.scan(ast.property);
+ this.popState(states.memberExpression);
+ break;
+ case 'ExpressionStatement':
+ this.scan(ast.expression);
+ break;
+ case 'SequenceExpression':
+ this.scan(ast.expressions);
+ break;
+ case 'CallExpression':
+ this.functionCalls.push({
+ context: this.currentContext,
+ ast,
+ });
+ this.scan(ast.arguments);
+ break;
+ case 'ArrayExpression':
+ this.scan(ast.elements);
+ break;
+ case 'ConditionalExpression':
+ this.scan(ast.test);
+ this.scan(ast.alternate);
+ this.scan(ast.consequent);
+ break;
+ case 'SwitchStatement':
+ this.scan(ast.discriminant);
+ this.scan(ast.cases);
+ break;
+ case 'SwitchCase':
+ this.scan(ast.test);
+ this.scan(ast.consequent);
+ break;
+
+ case 'ThisExpression':
+ case 'Literal':
+ case 'DebuggerStatement':
+ case 'EmptyStatement':
+ case 'BreakStatement':
+ case 'ContinueStatement':
+ break;
+ default:
+ throw new Error(`unhandled type "${ast.type}"`);
+ }
+ }
+}
+
+module.exports = {
+ FunctionTracer,
+};
\ No newline at end of file
diff --git a/src/backend/gl/kernel-string.js b/src/backend/gl/kernel-string.js
new file mode 100644
index 00000000..75ca4064
--- /dev/null
+++ b/src/backend/gl/kernel-string.js
@@ -0,0 +1,366 @@
+const { glWiretap } = require('gl-wiretap');
+const { utils } = require('../../utils');
+
+function toStringWithoutUtils(fn) {
+ return fn.toString()
+ .replace('=>', '')
+ .replace(/^function /, '')
+ .replace(/utils[.]/g, '/*utils.*/');
+}
+
+/**
+ *
+ * @param {GLKernel} Kernel
+ * @param {KernelVariable[]} args
+ * @param {Kernel} originKernel
+ * @param {string} [setupContextString]
+ * @param {string} [destroyContextString]
+ * @returns {string}
+ */
+function glKernelString(Kernel, args, originKernel, setupContextString, destroyContextString) {
+ if (!originKernel.built) {
+ originKernel.build.apply(originKernel, args);
+ }
+ args = args ? Array.from(args).map(arg => {
+ switch (typeof arg) {
+ case 'boolean':
+ return new Boolean(arg);
+ case 'number':
+ return new Number(arg);
+ default:
+ return arg;
+ }
+ }) : null;
+ const uploadedValues = [];
+ const postResult = [];
+ const context = glWiretap(originKernel.context, {
+ useTrackablePrimitives: true,
+ onReadPixels: (targetName) => {
+ if (kernel.subKernels) {
+ if (!subKernelsResultVariableSetup) {
+ postResult.push(` const result = { result: ${getRenderString(targetName, kernel)} };`);
+ subKernelsResultVariableSetup = true;
+ } else {
+ const property = kernel.subKernels[subKernelsResultIndex++].property;
+ postResult.push(` result${isNaN(property) ? '.' + property : `[${property}]`} = ${getRenderString(targetName, kernel)};`);
+ }
+ if (subKernelsResultIndex === kernel.subKernels.length) {
+ postResult.push(' return result;');
+ }
+ return;
+ }
+ if (targetName) {
+ postResult.push(` return ${getRenderString(targetName, kernel)};`);
+ } else {
+ postResult.push(` return null;`);
+ }
+ },
+ onUnrecognizedArgumentLookup: (argument) => {
+ const argumentName = findKernelValue(argument, kernel.kernelArguments, [], context, uploadedValues);
+ if (argumentName) {
+ return argumentName;
+ }
+ const constantName = findKernelValue(argument, kernel.kernelConstants, constants ? Object.keys(constants).map(key => constants[key]) : [], context, uploadedValues);
+ if (constantName) {
+ return constantName;
+ }
+ return null;
+ }
+ });
+ let subKernelsResultVariableSetup = false;
+ let subKernelsResultIndex = 0;
+ const {
+ source,
+ canvas,
+ output,
+ pipeline,
+ graphical,
+ loopMaxIterations,
+ constants,
+ optimizeFloatMemory,
+ precision,
+ fixIntegerDivisionAccuracy,
+ functions,
+ nativeFunctions,
+ subKernels,
+ immutable,
+ argumentTypes,
+ constantTypes,
+ kernelArguments,
+ kernelConstants,
+ tactic,
+ } = originKernel;
+ const kernel = new Kernel(source, {
+ canvas,
+ context,
+ checkContext: false,
+ output,
+ pipeline,
+ graphical,
+ loopMaxIterations,
+ constants,
+ optimizeFloatMemory,
+ precision,
+ fixIntegerDivisionAccuracy,
+ functions,
+ nativeFunctions,
+ subKernels,
+ immutable,
+ argumentTypes,
+ constantTypes,
+ tactic,
+ });
+ let result = [];
+ context.setIndent(2);
+ kernel.build.apply(kernel, args);
+ result.push(context.toString());
+ context.reset();
+
+ kernel.kernelArguments.forEach((kernelArgument, i) => {
+ switch (kernelArgument.type) {
+ // primitives
+ case 'Integer':
+ case 'Boolean':
+ case 'Number':
+ case 'Float':
+ // non-primitives
+ case 'Array':
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ case 'HTMLCanvas':
+ case 'HTMLImage':
+ case 'HTMLVideo':
+ context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue);
+ break;
+ case 'HTMLImageArray':
+ for (let imageIndex = 0; imageIndex < args[i].length; imageIndex++) {
+ const arg = args[i];
+ context.insertVariable(`uploadValue_${kernelArgument.name}[${imageIndex}]`, arg[imageIndex]);
+ }
+ break;
+ case 'Input':
+ context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue);
+ break;
+ case 'MemoryOptimizedNumberTexture':
+ case 'NumberTexture':
+ case 'Array1D(2)':
+ case 'Array1D(3)':
+ case 'Array1D(4)':
+ case 'Array2D(2)':
+ case 'Array2D(3)':
+ case 'Array2D(4)':
+ case 'Array3D(2)':
+ case 'Array3D(3)':
+ case 'Array3D(4)':
+ case 'ArrayTexture(1)':
+ case 'ArrayTexture(2)':
+ case 'ArrayTexture(3)':
+ case 'ArrayTexture(4)':
+ context.insertVariable(`uploadValue_${kernelArgument.name}`, args[i].texture);
+ break;
+ default:
+ throw new Error(`unhandled kernelArgumentType insertion for glWiretap of type ${kernelArgument.type}`);
+ }
+ });
+ result.push('/** start of injected functions **/');
+ result.push(`function ${toStringWithoutUtils(utils.flattenTo)}`);
+ result.push(`function ${toStringWithoutUtils(utils.flatten2dArrayTo)}`);
+ result.push(`function ${toStringWithoutUtils(utils.flatten3dArrayTo)}`);
+ result.push(`function ${toStringWithoutUtils(utils.flatten4dArrayTo)}`);
+ result.push(`function ${toStringWithoutUtils(utils.isArray)}`);
+ if (kernel.renderOutput !== kernel.renderTexture && kernel.formatValues) {
+ result.push(
+ ` const renderOutput = function ${toStringWithoutUtils(kernel.formatValues)};`
+ );
+ }
+ result.push('/** end of injected functions **/');
+ result.push(` const innerKernel = function (${kernel.kernelArguments.map(kernelArgument => kernelArgument.varName).join(', ')}) {`);
+ context.setIndent(4);
+ kernel.run.apply(kernel, args);
+ if (kernel.renderKernels) {
+ kernel.renderKernels();
+ } else if (kernel.renderOutput) {
+ kernel.renderOutput();
+ }
+ result.push(' /** start setup uploads for kernel values **/');
+ kernel.kernelArguments.forEach(kernelArgument => {
+ result.push(' ' + kernelArgument.getStringValueHandler().split('\n').join('\n '));
+ });
+ result.push(' /** end setup uploads for kernel values **/');
+ result.push(context.toString());
+ if (kernel.renderOutput === kernel.renderTexture) {
+ context.reset();
+ const framebufferName = context.getContextVariableName(kernel.framebuffer);
+ if (kernel.renderKernels) {
+ const results = kernel.renderKernels();
+ const textureName = context.getContextVariableName(kernel.texture.texture);
+ result.push(` return {
+ result: {
+ texture: ${ textureName },
+ type: '${ results.result.type }',
+ toArray: ${ getToArrayString(results.result, textureName, framebufferName) }
+ },`);
+ const { subKernels, mappedTextures } = kernel;
+ for (let i = 0; i < subKernels.length; i++) {
+ const texture = mappedTextures[i];
+ const subKernel = subKernels[i];
+ const subKernelResult = results[subKernel.property];
+ const subKernelTextureName = context.getContextVariableName(texture.texture);
+ result.push(`
+ ${subKernel.property}: {
+ texture: ${ subKernelTextureName },
+ type: '${ subKernelResult.type }',
+ toArray: ${ getToArrayString(subKernelResult, subKernelTextureName, framebufferName) }
+ },`);
+ }
+ result.push(` };`);
+ } else {
+ const rendered = kernel.renderOutput();
+ const textureName = context.getContextVariableName(kernel.texture.texture);
+ result.push(` return {
+ texture: ${ textureName },
+ type: '${ rendered.type }',
+ toArray: ${ getToArrayString(rendered, textureName, framebufferName) }
+ };`);
+ }
+ }
+ result.push(` ${destroyContextString ? '\n' + destroyContextString + ' ': ''}`);
+ result.push(postResult.join('\n'));
+ result.push(' };');
+ if (kernel.graphical) {
+ result.push(getGetPixelsString(kernel));
+ result.push(` innerKernel.getPixels = getPixels;`);
+ }
+ result.push(' return innerKernel;');
+
+ let constantsUpload = [];
+ kernelConstants.forEach((kernelConstant) => {
+ constantsUpload.push(`${kernelConstant.getStringValueHandler()}`);
+ });
+ return `function kernel(settings) {
+ const { context, constants } = settings;
+ ${constantsUpload.join('')}
+ ${setupContextString ? setupContextString : ''}
+${result.join('\n')}
+}`;
+}
+
+function getRenderString(targetName, kernel) {
+ const readBackValue = kernel.precision === 'single' ? targetName : `new Float32Array(${targetName}.buffer)`;
+ if (kernel.output[2]) {
+ return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]}, ${kernel.output[2]})`;
+ }
+ if (kernel.output[1]) {
+ return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]})`;
+ }
+
+ return `renderOutput(${readBackValue}, ${kernel.output[0]})`;
+}
+
+function getGetPixelsString(kernel) {
+ const getPixels = kernel.getPixels.toString();
+ const useFunctionKeyword = !/^function/.test(getPixels);
+ return utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ getPixels }`, {
+ findDependency: (object, name) => {
+ if (object === 'utils') {
+ return `const ${name} = ${utils[name].toString()};`;
+ }
+ return null;
+ },
+ thisLookup: (property) => {
+ if (property === 'context') {
+ return null;
+ }
+ if (kernel.hasOwnProperty(property)) {
+ return JSON.stringify(kernel[property]);
+ }
+ throw new Error(`unhandled thisLookup ${ property }`);
+ }
+ });
+}
+
+function getToArrayString(kernelResult, textureName, framebufferName) {
+ const toArray = kernelResult.toArray.toString();
+ const useFunctionKeyword = !/^function/.test(toArray);
+ const flattenedFunctions = utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ toArray }`, {
+ findDependency: (object, name) => {
+ if (object === 'utils') {
+ return `const ${name} = ${utils[name].toString()};`;
+ } else if (object === 'this') {
+ if (name === 'framebuffer') {
+ return '';
+ }
+ return `${useFunctionKeyword ? 'function ' : ''}${kernelResult[name].toString()}`;
+ } else {
+ throw new Error('unhandled fromObject');
+ }
+ },
+ thisLookup: (property, isDeclaration) => {
+ if (property === 'texture') {
+ return textureName;
+ }
+ if (property === 'context') {
+ if (isDeclaration) return null;
+ return 'gl';
+ }
+ if (kernelResult.hasOwnProperty(property)) {
+ return JSON.stringify(kernelResult[property]);
+ }
+ throw new Error(`unhandled thisLookup ${ property }`);
+ }
+ });
+ return `() => {
+ function framebuffer() { return ${framebufferName}; };
+ ${flattenedFunctions}
+ return toArray();
+ }`;
+}
+
+/**
+ *
+ * @param {KernelVariable} argument
+ * @param {KernelValue[]} kernelValues
+ * @param {KernelVariable[]} values
+ * @param context
+ * @param {KernelVariable[]} uploadedValues
+ * @return {string|null}
+ */
+function findKernelValue(argument, kernelValues, values, context, uploadedValues) {
+ if (argument === null) return null;
+ if (kernelValues === null) return null;
+ switch (typeof argument) {
+ case 'boolean':
+ case 'number':
+ return null;
+ }
+ if (
+ typeof HTMLImageElement !== 'undefined' &&
+ argument instanceof HTMLImageElement
+ ) {
+ for (let i = 0; i < kernelValues.length; i++) {
+ const kernelValue = kernelValues[i];
+ if (kernelValue.type !== 'HTMLImageArray' && kernelValue) continue;
+ if (kernelValue.uploadValue !== argument) continue;
+ // TODO: if we send two of the same image, the parser could get confused, and short circuit to the first, handle that here
+ const variableIndex = values[i].indexOf(argument);
+ if (variableIndex === -1) continue;
+ const variableName = `uploadValue_${kernelValue.name}[${variableIndex}]`;
+ context.insertVariable(variableName, argument);
+ return variableName;
+ }
+ }
+
+ for (let i = 0; i < kernelValues.length; i++) {
+ const kernelValue = kernelValues[i];
+ if (argument !== kernelValue.uploadValue) continue;
+ const variable = `uploadValue_${kernelValue.name}`;
+ context.insertVariable(variable, kernelValue);
+ return variable;
+ }
+ return null;
+}
+
+module.exports = {
+ glKernelString
+};
\ No newline at end of file
diff --git a/src/backend/gl/kernel.js b/src/backend/gl/kernel.js
new file mode 100644
index 00000000..e2e55478
--- /dev/null
+++ b/src/backend/gl/kernel.js
@@ -0,0 +1,1059 @@
+const { Kernel } = require('../kernel');
+const { utils } = require('../../utils');
+const { GLTextureArray2Float } = require('./texture/array-2-float');
+const { GLTextureArray2Float2D } = require('./texture/array-2-float-2d');
+const { GLTextureArray2Float3D } = require('./texture/array-2-float-3d');
+const { GLTextureArray3Float } = require('./texture/array-3-float');
+const { GLTextureArray3Float2D } = require('./texture/array-3-float-2d');
+const { GLTextureArray3Float3D } = require('./texture/array-3-float-3d');
+const { GLTextureArray4Float } = require('./texture/array-4-float');
+const { GLTextureArray4Float2D } = require('./texture/array-4-float-2d');
+const { GLTextureArray4Float3D } = require('./texture/array-4-float-3d');
+const { GLTextureFloat } = require('./texture/float');
+const { GLTextureFloat2D } = require('./texture/float-2d');
+const { GLTextureFloat3D } = require('./texture/float-3d');
+const { GLTextureMemoryOptimized } = require('./texture/memory-optimized');
+const { GLTextureMemoryOptimized2D } = require('./texture/memory-optimized-2d');
+const { GLTextureMemoryOptimized3D } = require('./texture/memory-optimized-3d');
+const { GLTextureUnsigned } = require('./texture/unsigned');
+const { GLTextureUnsigned2D } = require('./texture/unsigned-2d');
+const { GLTextureUnsigned3D } = require('./texture/unsigned-3d');
+const { GLTextureGraphical } = require('./texture/graphical');
+
+/**
+ * @abstract
+ * @extends Kernel
+ */
+class GLKernel extends Kernel {
+ static get mode() {
+ return 'gpu';
+ }
+
+ static getIsFloatRead() {
+ const kernelString = `function kernelFunction() {
+ return 1;
+ }`;
+ const kernel = new this(kernelString, {
+ context: this.testContext,
+ canvas: this.testCanvas,
+ validate: false,
+ output: [1],
+ precision: 'single',
+ returnType: 'Number',
+ tactic: 'speed',
+ });
+ kernel.build();
+ kernel.run();
+ const result = kernel.renderOutput();
+ kernel.destroy(true);
+ return result[0] === 1;
+ }
+
+ static getIsIntegerDivisionAccurate() {
+ function kernelFunction(v1, v2) {
+ return v1[this.thread.x] / v2[this.thread.x];
+ }
+ const kernel = new this(kernelFunction.toString(), {
+ context: this.testContext,
+ canvas: this.testCanvas,
+ validate: false,
+ output: [2],
+ returnType: 'Number',
+ precision: 'unsigned',
+ tactic: 'speed',
+ });
+ const args = [
+ [6, 6030401],
+ [3, 3991]
+ ];
+ kernel.build.apply(kernel, args);
+ kernel.run.apply(kernel, args);
+ const result = kernel.renderOutput();
+ kernel.destroy(true);
+ // have we not got whole numbers for 6/3 or 6030401/3991
+ // add more here if others see this problem
+ return result[0] === 2 && result[1] === 1511;
+ }
+
+ static getIsSpeedTacticSupported() {
+ function kernelFunction(value) {
+ return value[this.thread.x];
+ }
+ const kernel = new this(kernelFunction.toString(), {
+ context: this.testContext,
+ canvas: this.testCanvas,
+ validate: false,
+ output: [4],
+ returnType: 'Number',
+ precision: 'unsigned',
+ tactic: 'speed',
+ });
+ const args = [
+ [0, 1, 2, 3]
+ ];
+ kernel.build.apply(kernel, args);
+ kernel.run.apply(kernel, args);
+ const result = kernel.renderOutput();
+ kernel.destroy(true);
+ return Math.round(result[0]) === 0 && Math.round(result[1]) === 1 && Math.round(result[2]) === 2 && Math.round(result[3]) === 3;
+ }
+
+ /**
+ * @abstract
+ */
+ static get testCanvas() {
+ throw new Error(`"testCanvas" not defined on ${ this.name }`);
+ }
+
+ /**
+ * @abstract
+ */
+ static get testContext() {
+ throw new Error(`"testContext" not defined on ${ this.name }`);
+ }
+
+ static getFeatures() {
+ const gl = this.testContext;
+ const isDrawBuffers = this.getIsDrawBuffers();
+ return Object.freeze({
+ isFloatRead: this.getIsFloatRead(),
+ isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(),
+ isSpeedTacticSupported: this.getIsSpeedTacticSupported(),
+ isTextureFloat: this.getIsTextureFloat(),
+ isDrawBuffers,
+ kernelMap: isDrawBuffers,
+ channelCount: this.getChannelCount(),
+ maxTextureSize: this.getMaxTextureSize(),
+ lowIntPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_INT),
+ lowFloatPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_FLOAT),
+ mediumIntPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_INT),
+ mediumFloatPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT),
+ highIntPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_INT),
+ highFloatPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT),
+ });
+ }
+
+ /**
+ * @abstract
+ */
+ static setupFeatureChecks() {
+ throw new Error(`"setupFeatureChecks" not defined on ${ this.name }`);
+ }
+
+ static getSignature(kernel, argumentTypes) {
+ return kernel.getVariablePrecisionString() + (argumentTypes.length > 0 ? ':' + argumentTypes.join(',') : '');
+ }
+
+ /**
+ * @desc Fix division by factor of 3 FP accuracy bug
+ * @param {Boolean} fix - should fix
+ */
+ setFixIntegerDivisionAccuracy(fix) {
+ this.fixIntegerDivisionAccuracy = fix;
+ return this;
+ }
+
+ /**
+ * @desc Toggle output mode
+ * @param {String} flag - 'single' or 'unsigned'
+ */
+ setPrecision(flag) {
+ this.precision = flag;
+ return this;
+ }
+
+ /**
+ * @desc Toggle texture output mode
+ * @param {Boolean} flag - true to enable floatTextures
+ * @deprecated
+ */
+ setFloatTextures(flag) {
+ utils.warnDeprecated('method', 'setFloatTextures', 'setOptimizeFloatMemory');
+ this.floatTextures = flag;
+ return this;
+ }
+
+ /**
+ * A highly readable very forgiving micro-parser for a glsl function that gets argument types
+ * @param {String} source
+ * @returns {{argumentTypes: String[], argumentNames: String[]}}
+ */
+ static nativeFunctionArguments(source) {
+ const argumentTypes = [];
+ const argumentNames = [];
+ const states = [];
+ const isStartingVariableName = /^[a-zA-Z_]/;
+ const isVariableChar = /[a-zA-Z_0-9]/;
+ let i = 0;
+ let argumentName = null;
+ let argumentType = null;
+ while (i < source.length) {
+ const char = source[i];
+ const nextChar = source[i + 1];
+ const state = states.length > 0 ? states[states.length - 1] : null;
+
+ // begin MULTI_LINE_COMMENT handling
+ if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '*') {
+ states.push('MULTI_LINE_COMMENT');
+ i += 2;
+ continue;
+ } else if (state === 'MULTI_LINE_COMMENT' && char === '*' && nextChar === '/') {
+ states.pop();
+ i += 2;
+ continue;
+ }
+ // end MULTI_LINE_COMMENT handling
+
+ // begin COMMENT handling
+ else if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '/') {
+ states.push('COMMENT');
+ i += 2;
+ continue;
+ } else if (state === 'COMMENT' && char === '\n') {
+ states.pop();
+ i++;
+ continue;
+ }
+ // end COMMENT handling
+
+ // being FUNCTION_ARGUMENTS handling
+ else if (state === null && char === '(') {
+ states.push('FUNCTION_ARGUMENTS');
+ i++;
+ continue;
+ } else if (state === 'FUNCTION_ARGUMENTS') {
+ if (char === ')') {
+ states.pop();
+ break;
+ }
+ if (char === 'f' && nextChar === 'l' && source[i + 2] === 'o' && source[i + 3] === 'a' && source[i + 4] === 't' && source[i + 5] === ' ') {
+ states.push('DECLARE_VARIABLE');
+ argumentType = 'float';
+ argumentName = '';
+ i += 6;
+ continue;
+ } else if (char === 'i' && nextChar === 'n' && source[i + 2] === 't' && source[i + 3] === ' ') {
+ states.push('DECLARE_VARIABLE');
+ argumentType = 'int';
+ argumentName = '';
+ i += 4;
+ continue;
+ } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '2' && source[i + 4] === ' ') {
+ states.push('DECLARE_VARIABLE');
+ argumentType = 'vec2';
+ argumentName = '';
+ i += 5;
+ continue;
+ } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '3' && source[i + 4] === ' ') {
+ states.push('DECLARE_VARIABLE');
+ argumentType = 'vec3';
+ argumentName = '';
+ i += 5;
+ continue;
+ } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '4' && source[i + 4] === ' ') {
+ states.push('DECLARE_VARIABLE');
+ argumentType = 'vec4';
+ argumentName = '';
+ i += 5;
+ continue;
+ }
+ }
+ // end FUNCTION_ARGUMENTS handling
+
+ // begin DECLARE_VARIABLE handling
+ else if (state === 'DECLARE_VARIABLE') {
+ if (argumentName === '') {
+ if (char === ' ') {
+ i++;
+ continue;
+ }
+ if (!isStartingVariableName.test(char)) {
+ throw new Error('variable name is not expected string');
+ }
+ }
+ argumentName += char;
+ if (!isVariableChar.test(nextChar)) {
+ states.pop();
+ argumentNames.push(argumentName);
+ argumentTypes.push(typeMap[argumentType]);
+ }
+ }
+ // end DECLARE_VARIABLE handling
+
+ // Progress to next character
+ i++;
+ }
+ if (states.length > 0) {
+ throw new Error('GLSL function was not parsable');
+ }
+ return {
+ argumentNames,
+ argumentTypes,
+ };
+ }
+
+ static nativeFunctionReturnType(source) {
+ return typeMap[source.match(/int|float|vec[2-4]/)[0]];
+ }
+
+ static combineKernels(combinedKernel, lastKernel) {
+ combinedKernel.apply(null, arguments);
+ const {
+ texSize,
+ context,
+ threadDim
+ } = lastKernel.texSize;
+ let result;
+ if (lastKernel.precision === 'single') {
+ const w = texSize[0];
+ const h = Math.ceil(texSize[1] / 4);
+ result = new Float32Array(w * h * 4 * 4);
+ context.readPixels(0, 0, w, h * 4, context.RGBA, context.FLOAT, result);
+ } else {
+ const bytes = new Uint8Array(texSize[0] * texSize[1] * 4);
+ context.readPixels(0, 0, texSize[0], texSize[1], context.RGBA, context.UNSIGNED_BYTE, bytes);
+ result = new Float32Array(bytes.buffer);
+ }
+
+ result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]);
+
+ if (lastKernel.output.length === 1) {
+ return result;
+ } else if (lastKernel.output.length === 2) {
+ return utils.splitArray(result, lastKernel.output[0]);
+ } else if (lastKernel.output.length === 3) {
+ const cube = utils.splitArray(result, lastKernel.output[0] * lastKernel.output[1]);
+ return cube.map(function(x) {
+ return utils.splitArray(x, lastKernel.output[0]);
+ });
+ }
+ }
+
+ constructor(source, settings) {
+ super(source, settings);
+ this.transferValues = null;
+ this.formatValues = null;
+ /**
+ *
+ * @type {Texture}
+ */
+ 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 } = this.constructor;
+ if (this.texSize[0] > features.maxTextureSize || this.texSize[1] > features.maxTextureSize) {
+ throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${features.maxTextureSize},${features.maxTextureSize}]`);
+ }
+ }
+
+ translateSource() {
+ throw new Error(`"translateSource" not defined on ${this.constructor.name}`);
+ }
+
+ /**
+ * Picks a render strategy for the now finally parsed kernel
+ * @param args
+ * @return {null|KernelOutput}
+ */
+ pickRenderStrategy(args) {
+ if (this.graphical) {
+ this.renderRawOutput = this.readPackedPixelsToUint8Array;
+ this.transferValues = (pixels) => pixels;
+ this.TextureConstructor = GLTextureGraphical;
+ return null;
+ }
+ if (this.precision === 'unsigned') {
+ this.renderRawOutput = this.readPackedPixelsToUint8Array;
+ this.transferValues = this.readPackedPixelsToFloat32Array;
+ if (this.pipeline) {
+ this.renderOutput = this.renderTexture;
+ if (this.subKernels !== null) {
+ this.renderKernels = this.renderKernelsToTextures;
+ }
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Float':
+ case 'Number':
+ case 'Integer':
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureUnsigned3D;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureUnsigned2D;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureUnsigned;
+ return null;
+ }
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ return this.requestFallback(args);
+ }
+ } else {
+ if (this.subKernels !== null) {
+ this.renderKernels = this.renderKernelsToArrays;
+ }
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Float':
+ case 'Number':
+ case 'Integer':
+ this.renderOutput = this.renderValues;
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureUnsigned3D;
+ this.formatValues = utils.erect3DPackedFloat;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureUnsigned2D;
+ this.formatValues = utils.erect2DPackedFloat;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureUnsigned;
+ this.formatValues = utils.erectPackedFloat;
+ return null;
+ }
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ return this.requestFallback(args);
+ }
+ }
+ } else if (this.precision === 'single') {
+ this.renderRawOutput = this.readFloatPixelsToFloat32Array;
+ this.transferValues = this.readFloatPixelsToFloat32Array;
+ if (this.pipeline) {
+ this.renderOutput = this.renderTexture;
+ if (this.subKernels !== null) {
+ this.renderKernels = this.renderKernelsToTextures;
+ }
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Float':
+ case 'Number':
+ case 'Integer': {
+ if (this.optimizeFloatMemory) {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureMemoryOptimized3D;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureMemoryOptimized2D;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureMemoryOptimized;
+ return null;
+ }
+ } else {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureFloat3D;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureFloat2D;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureFloat;
+ return null;
+ }
+ }
+ }
+ case 'Array(2)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray2Float3D;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray2Float2D;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray2Float;
+ return null;
+ }
+ }
+ case 'Array(3)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray3Float3D;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray3Float2D;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray3Float;
+ return null;
+ }
+ }
+ case 'Array(4)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray4Float3D;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray4Float2D;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray4Float;
+ return null;
+ }
+ }
+ }
+ }
+ this.renderOutput = this.renderValues;
+ if (this.subKernels !== null) {
+ this.renderKernels = this.renderKernelsToArrays;
+ }
+ if (this.optimizeFloatMemory) {
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Float':
+ case 'Number':
+ case 'Integer': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureMemoryOptimized3D;
+ this.formatValues = utils.erectMemoryOptimized3DFloat;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureMemoryOptimized2D;
+ this.formatValues = utils.erectMemoryOptimized2DFloat;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureMemoryOptimized;
+ this.formatValues = utils.erectMemoryOptimizedFloat;
+ return null;
+ }
+ }
+ case 'Array(2)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray2Float3D;
+ this.formatValues = utils.erect3DArray2;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray2Float2D;
+ this.formatValues = utils.erect2DArray2;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray2Float;
+ this.formatValues = utils.erectArray2;
+ return null;
+ }
+ }
+ case 'Array(3)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray3Float3D;
+ this.formatValues = utils.erect3DArray3;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray3Float2D;
+ this.formatValues = utils.erect2DArray3;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray3Float;
+ this.formatValues = utils.erectArray3;
+ return null;
+ }
+ }
+ case 'Array(4)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray4Float3D;
+ this.formatValues = utils.erect3DArray4;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray4Float2D;
+ this.formatValues = utils.erect2DArray4;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray4Float;
+ this.formatValues = utils.erectArray4;
+ return null;
+ }
+ }
+ }
+ } else {
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Float':
+ case 'Number':
+ case 'Integer': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureFloat3D;
+ this.formatValues = utils.erect3DFloat;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureFloat2D;
+ this.formatValues = utils.erect2DFloat;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureFloat;
+ this.formatValues = utils.erectFloat;
+ return null;
+ }
+ }
+ case 'Array(2)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray2Float3D;
+ this.formatValues = utils.erect3DArray2;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray2Float2D;
+ this.formatValues = utils.erect2DArray2;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray2Float;
+ this.formatValues = utils.erectArray2;
+ return null;
+ }
+ }
+ case 'Array(3)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray3Float3D;
+ this.formatValues = utils.erect3DArray3;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray3Float2D;
+ this.formatValues = utils.erect2DArray3;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray3Float;
+ this.formatValues = utils.erectArray3;
+ return null;
+ }
+ }
+ case 'Array(4)': {
+ if (this.output[2] > 0) {
+ this.TextureConstructor = GLTextureArray4Float3D;
+ this.formatValues = utils.erect3DArray4;
+ return null;
+ } else if (this.output[1] > 0) {
+ this.TextureConstructor = GLTextureArray4Float2D;
+ this.formatValues = utils.erect2DArray4;
+ return null;
+ } else {
+ this.TextureConstructor = GLTextureArray4Float;
+ this.formatValues = utils.erectArray4;
+ return null;
+ }
+ }
+ }
+ }
+ } else {
+ throw new Error(`unhandled precision of "${this.precision}"`);
+ }
+
+ throw new Error(`unhandled return type "${this.returnType}"`);
+ }
+
+ /**
+ * @abstract
+ * @returns String
+ */
+ 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 }`);
+ }
+ }
+
+ /**
+ * @abstract
+ * @returns String[]
+ */
+ getMainResultKernelNumberTexture() {
+ throw new Error(`abstract method call`);
+ }
+ /**
+ * @abstract
+ * @returns String[]
+ */
+ getMainResultSubKernelNumberTexture() {
+ throw new Error(`abstract method call`);
+ }
+ /**
+ * @abstract
+ * @returns String[]
+ */
+ getMainResultKernelArray2Texture() {
+ throw new Error(`abstract method call`);
+ }
+ /**
+ * @abstract
+ * @returns String[]
+ */
+ getMainResultSubKernelArray2Texture() {
+ throw new Error(`abstract method call`);
+ }
+ /**
+ * @abstract
+ * @returns String[]
+ */
+ getMainResultKernelArray3Texture() {
+ throw new Error(`abstract method call`);
+ }
+ /**
+ * @abstract
+ * @returns String[]
+ */
+ getMainResultSubKernelArray3Texture() {
+ throw new Error(`abstract method call`);
+ }
+ /**
+ * @abstract
+ * @returns String[]
+ */
+ getMainResultKernelArray4Texture() {
+ throw new Error(`abstract method call`);
+ }
+ /**
+ * @abstract
+ * @returns String[]
+ */
+ getMainResultSubKernelArray4Texture() {
+ throw new Error(`abstract method call`);
+ }
+ /**
+ * @abstract
+ * @returns String[]
+ */
+ getMainResultGraphical() {
+ throw new Error(`abstract method call`);
+ }
+ /**
+ * @abstract
+ * @returns String[]
+ */
+ getMainResultMemoryOptimizedFloats() {
+ throw new Error(`abstract method call`);
+ }
+ /**
+ * @abstract
+ * @returns String[]
+ */
+ getMainResultPackedPixels() {
+ throw new Error(`abstract method call`);
+ }
+
+ getMainResultString() {
+ if (this.graphical) {
+ return this.getMainResultGraphical();
+ } else if (this.precision === 'single') {
+ if (this.optimizeFloatMemory) {
+ return this.getMainResultMemoryOptimizedFloats();
+ }
+ return this.getMainResultTexture();
+ } else {
+ return this.getMainResultPackedPixels();
+ }
+ }
+
+ getMainResultNumberTexture() {
+ return utils.linesToString(this.getMainResultKernelNumberTexture()) +
+ utils.linesToString(this.getMainResultSubKernelNumberTexture());
+ }
+
+ getMainResultArray2Texture() {
+ return utils.linesToString(this.getMainResultKernelArray2Texture()) +
+ utils.linesToString(this.getMainResultSubKernelArray2Texture());
+ }
+
+ getMainResultArray3Texture() {
+ return utils.linesToString(this.getMainResultKernelArray3Texture()) +
+ utils.linesToString(this.getMainResultSubKernelArray3Texture());
+ }
+
+ getMainResultArray4Texture() {
+ return utils.linesToString(this.getMainResultKernelArray4Texture()) +
+ utils.linesToString(this.getMainResultSubKernelArray4Texture());
+ }
+
+ /**
+ *
+ * @return {string}
+ */
+ getFloatTacticDeclaration() {
+ const variablePrecision = this.getVariablePrecisionString(this.texSize, this.tactic);
+ return `precision ${variablePrecision} float;\n`;
+ }
+
+ /**
+ *
+ * @return {string}
+ */
+ getIntTacticDeclaration() {
+ return `precision ${this.getVariablePrecisionString(this.texSize, this.tactic, true)} int;\n`;
+ }
+
+ /**
+ *
+ * @return {string}
+ */
+ 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 (this.precision !== 'unsigned') throw new Error('Requires this.precision to be "unsigned"');
+ const {
+ texSize,
+ context: gl
+ } = this;
+ const result = new Uint8Array(texSize[0] * texSize[1] * 4);
+ gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, result);
+ return result;
+ }
+
+ readPackedPixelsToFloat32Array() {
+ return new Float32Array(this.readPackedPixelsToUint8Array().buffer);
+ }
+
+ readFloatPixelsToFloat32Array() {
+ if (this.precision !== 'single') throw new Error('Requires this.precision to be "single"');
+ const {
+ texSize,
+ context: gl
+ } = this;
+ const w = texSize[0];
+ const h = texSize[1];
+ const result = new Float32Array(w * h * 4);
+ gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result);
+ return result;
+ }
+
+ /**
+ *
+ * @param {Boolean} [flip]
+ * @return {Uint8ClampedArray}
+ */
+ getPixels(flip) {
+ const {
+ context: gl,
+ output
+ } = this;
+ const [width, height] = output;
+ const pixels = new Uint8Array(width * height * 4);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+ // flipped by default, so invert
+ return new Uint8ClampedArray((flip ? pixels : utils.flipPixels(pixels, width, height)).buffer);
+ }
+
+ renderKernelsToArrays() {
+ const result = {
+ result: this.renderOutput(),
+ };
+ for (let i = 0; i < this.subKernels.length; i++) {
+ result[this.subKernels[i].property] = this.mappedTextures[i].toArray();
+ }
+ return result;
+ }
+
+ renderKernelsToTextures() {
+ const result = {
+ result: this.renderOutput(),
+ };
+ 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) {
+ if (!this.dynamicOutput) {
+ throw new Error('Resizing a kernel with dynamicOutput: false is not possible');
+ }
+ const newThreadDim = [newOutput[0], newOutput[1] || 1, newOutput[2] || 1];
+ const newTexSize = utils.getKernelTextureSize({
+ optimizeFloatMemory: this.optimizeFloatMemory,
+ precision: this.precision,
+ }, newThreadDim);
+ const oldTexSize = this.texSize;
+ if (oldTexSize) {
+ const oldPrecision = this.getVariablePrecisionString(oldTexSize, this.tactic);
+ const newPrecision = this.getVariablePrecisionString(newTexSize, this.tactic);
+ if (oldPrecision !== newPrecision) {
+ if (this.debug) {
+ console.warn('Precision requirement changed, asking GPU instance to recompile');
+ }
+ this.switchKernels({
+ type: 'outputPrecisionMismatch',
+ precision: newPrecision,
+ needed: output
+ });
+ return;
+ }
+ }
+ this.output = newOutput;
+ this.threadDim = newThreadDim;
+ this.texSize = newTexSize;
+ const { context: gl } = this;
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
+ this.updateMaxTexSize();
+ this.framebuffer.width = this.texSize[0];
+ this.framebuffer.height = this.texSize[1];
+ gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);
+ this.canvas.width = this.maxTexSize[0];
+ this.canvas.height = this.maxTexSize[1];
+ if (this.texture) {
+ this.texture.delete();
+ }
+ this.texture = null;
+ this._setupOutputTexture();
+ if (this.mappedTextures && this.mappedTextures.length > 0) {
+ for (let i = 0; i < this.mappedTextures.length; i++) {
+ this.mappedTextures[i].delete();
+ }
+ this.mappedTextures = null;
+ this._setupSubOutputTextures();
+ }
+ } else {
+ this.output = newOutput;
+ }
+ return this;
+ }
+ 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';
+ const low = this.constructor.features[isInt ? 'lowIntPrecision' : 'lowFloatPrecision'];
+ const medium = this.constructor.features[isInt ? 'mediumIntPrecision' : 'mediumFloatPrecision'];
+ const high = this.constructor.features[isInt ? 'highIntPrecision' : 'highFloatPrecision'];
+ const requiredSize = Math.log2(textureSize[0] * textureSize[1]);
+ if (requiredSize <= low.rangeMax) {
+ return 'lowp';
+ } else if (requiredSize <= medium.rangeMax) {
+ return 'mediump';
+ } else if (requiredSize <= high.rangeMax) {
+ return 'highp';
+ } else {
+ throw new Error(`The required size exceeds that of the ability of your system`);
+ }
+ }
+ switch (tactic) {
+ case 'speed':
+ return 'lowp';
+ case 'balanced':
+ return 'mediump';
+ case 'precision':
+ return 'highp';
+ default:
+ throw new Error(`Unknown tactic "${tactic}" use "speed", "balanced", "precision", or empty for auto`);
+ }
+ }
+
+ /**
+ *
+ * @param {WebGLKernelValue} kernelValue
+ * @param {GLTexture} arg
+ */
+ updateTextureArgumentRefs(kernelValue, arg) {
+ if (!this.immutable) return;
+ if (this.texture.texture === arg.texture) {
+ const { prevArg } = kernelValue;
+ if (prevArg) {
+ if (prevArg.texture._refs === 1) {
+ this.texture.delete();
+ this.texture = prevArg.clone();
+ this._textureSwitched = true;
+ }
+ prevArg.delete();
+ }
+ kernelValue.prevArg = arg.clone();
+ } else if (this.mappedTextures && this.mappedTextures.length > 0) {
+ const { mappedTextures } = this;
+ for (let i = 0; i < mappedTextures.length; i++) {
+ const mappedTexture = mappedTextures[i];
+ if (mappedTexture.texture === arg.texture) {
+ const { prevArg } = kernelValue;
+ if (prevArg) {
+ if (prevArg.texture._refs === 1) {
+ mappedTexture.delete();
+ mappedTextures[i] = prevArg.clone();
+ this._mappedTextureSwitched[i] = true;
+ }
+ prevArg.delete();
+ }
+ kernelValue.prevArg = arg.clone();
+ return;
+ }
+ }
+ }
+ }
+
+ onActivate(previousKernel) {
+ this._textureSwitched = true;
+ this.texture = previousKernel.texture;
+ if (this.mappedTextures) {
+ for (let i = 0; i < this.mappedTextures.length; i++) {
+ this._mappedTextureSwitched[i] = true;
+ }
+ this.mappedTextures = previousKernel.mappedTextures;
+ }
+ }
+
+ initCanvas() {}
+}
+
+const typeMap = {
+ int: 'Integer',
+ float: 'Number',
+ vec2: 'Array(2)',
+ vec3: 'Array(3)',
+ vec4: 'Array(4)',
+};
+
+module.exports = {
+ GLKernel
+};
\ No newline at end of file
diff --git a/src/backend/gl/texture/array-2-float-2d.js b/src/backend/gl/texture/array-2-float-2d.js
new file mode 100644
index 00000000..a0e7defd
--- /dev/null
+++ b/src/backend/gl/texture/array-2-float-2d.js
@@ -0,0 +1,16 @@
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray2Float2D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(2)';
+ }
+ toArray() {
+ return utils.erect2DArray2(this.renderValues(), this.output[0], this.output[1]);
+ }
+}
+
+module.exports = {
+ GLTextureArray2Float2D
+};
\ No newline at end of file
diff --git a/src/backend/gl/texture/array-2-float-3d.js b/src/backend/gl/texture/array-2-float-3d.js
new file mode 100644
index 00000000..28f5b092
--- /dev/null
+++ b/src/backend/gl/texture/array-2-float-3d.js
@@ -0,0 +1,16 @@
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray2Float3D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(2)';
+ }
+ toArray() {
+ return utils.erect3DArray2(this.renderValues(), this.output[0], this.output[1], this.output[2]);
+ }
+}
+
+module.exports = {
+ GLTextureArray2Float3D
+};
\ No newline at end of file
diff --git a/src/backend/gl/texture/array-2-float.js b/src/backend/gl/texture/array-2-float.js
new file mode 100644
index 00000000..fab1a2ae
--- /dev/null
+++ b/src/backend/gl/texture/array-2-float.js
@@ -0,0 +1,16 @@
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray2Float extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(2)';
+ }
+ toArray() {
+ return utils.erectArray2(this.renderValues(), this.output[0], this.output[1]);
+ }
+}
+
+module.exports = {
+ GLTextureArray2Float
+};
\ No newline at end of file
diff --git a/src/backend/gl/texture/array-3-float-2d.js b/src/backend/gl/texture/array-3-float-2d.js
new file mode 100644
index 00000000..4f615879
--- /dev/null
+++ b/src/backend/gl/texture/array-3-float-2d.js
@@ -0,0 +1,16 @@
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray3Float2D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(3)';
+ }
+ toArray() {
+ return utils.erect2DArray3(this.renderValues(), this.output[0], this.output[1]);
+ }
+}
+
+module.exports = {
+ GLTextureArray3Float2D
+};
\ No newline at end of file
diff --git a/src/backend/gl/texture/array-3-float-3d.js b/src/backend/gl/texture/array-3-float-3d.js
new file mode 100644
index 00000000..ea53aee0
--- /dev/null
+++ b/src/backend/gl/texture/array-3-float-3d.js
@@ -0,0 +1,16 @@
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray3Float3D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(3)';
+ }
+ toArray() {
+ return utils.erect3DArray3(this.renderValues(), this.output[0], this.output[1], this.output[2]);
+ }
+}
+
+module.exports = {
+ GLTextureArray3Float3D
+};
\ No newline at end of file
diff --git a/src/backend/gl/texture/array-3-float.js b/src/backend/gl/texture/array-3-float.js
new file mode 100644
index 00000000..5f99396b
--- /dev/null
+++ b/src/backend/gl/texture/array-3-float.js
@@ -0,0 +1,16 @@
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray3Float extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(3)';
+ }
+ toArray() {
+ return utils.erectArray3(this.renderValues(), this.output[0]);
+ }
+}
+
+module.exports = {
+ GLTextureArray3Float
+};
\ No newline at end of file
diff --git a/src/backend/gl/texture/array-4-float-2d.js b/src/backend/gl/texture/array-4-float-2d.js
new file mode 100644
index 00000000..a370eaa2
--- /dev/null
+++ b/src/backend/gl/texture/array-4-float-2d.js
@@ -0,0 +1,16 @@
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray4Float2D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(4)';
+ }
+ toArray() {
+ return utils.erect2DArray4(this.renderValues(), this.output[0], this.output[1]);
+ }
+}
+
+module.exports = {
+ GLTextureArray4Float2D
+};
\ No newline at end of file
diff --git a/src/backend/gl/texture/array-4-float-3d.js b/src/backend/gl/texture/array-4-float-3d.js
new file mode 100644
index 00000000..21e09249
--- /dev/null
+++ b/src/backend/gl/texture/array-4-float-3d.js
@@ -0,0 +1,16 @@
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray4Float3D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(4)';
+ }
+ toArray() {
+ return utils.erect3DArray4(this.renderValues(), this.output[0], this.output[1], this.output[2]);
+ }
+}
+
+module.exports = {
+ GLTextureArray4Float3D
+};
\ No newline at end of file
diff --git a/src/backend/gl/texture/array-4-float.js b/src/backend/gl/texture/array-4-float.js
new file mode 100644
index 00000000..80553d15
--- /dev/null
+++ b/src/backend/gl/texture/array-4-float.js
@@ -0,0 +1,16 @@
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureArray4Float extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(4)';
+ }
+ toArray() {
+ return utils.erectArray4(this.renderValues(), this.output[0]);
+ }
+}
+
+module.exports = {
+ GLTextureArray4Float
+};
\ No newline at end of file
diff --git a/src/backend/gl/texture/float-2d.js b/src/backend/gl/texture/float-2d.js
new file mode 100644
index 00000000..1fb927e9
--- /dev/null
+++ b/src/backend/gl/texture/float-2d.js
@@ -0,0 +1,16 @@
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureFloat2D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(1)';
+ }
+ toArray() {
+ return utils.erect2DFloat(this.renderValues(), this.output[0], this.output[1]);
+ }
+}
+
+module.exports = {
+ GLTextureFloat2D
+};
\ No newline at end of file
diff --git a/src/backend/gl/texture/float-3d.js b/src/backend/gl/texture/float-3d.js
new file mode 100644
index 00000000..9a8a536f
--- /dev/null
+++ b/src/backend/gl/texture/float-3d.js
@@ -0,0 +1,16 @@
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureFloat3D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(1)';
+ }
+ toArray() {
+ return utils.erect3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]);
+ }
+}
+
+module.exports = {
+ GLTextureFloat3D
+};
\ No newline at end of file
diff --git a/src/backend/gl/texture/float.js b/src/backend/gl/texture/float.js
new file mode 100644
index 00000000..21d3748f
--- /dev/null
+++ b/src/backend/gl/texture/float.js
@@ -0,0 +1,38 @@
+const { utils } = require('../../../utils');
+const { GLTexture } = require('./index');
+
+class GLTextureFloat extends GLTexture {
+ get textureType() {
+ return this.context.FLOAT;
+ }
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(1)';
+ }
+ renderRawOutput() {
+ const gl = this.context;
+ const size = this.size;
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer());
+ gl.framebufferTexture2D(
+ gl.FRAMEBUFFER,
+ gl.COLOR_ATTACHMENT0,
+ gl.TEXTURE_2D,
+ this.texture,
+ 0
+ );
+ const result = new Float32Array(size[0] * size[1] * 4);
+ gl.readPixels(0, 0, size[0], size[1], gl.RGBA, gl.FLOAT, result);
+ return result;
+ }
+ renderValues() {
+ if (this._deleted) return null;
+ return this.renderRawOutput();
+ }
+ toArray() {
+ return utils.erectFloat(this.renderValues(), this.output[0]);
+ }
+}
+
+module.exports = {
+ GLTextureFloat
+};
\ No newline at end of file
diff --git a/src/backend/gl/texture/graphical.js b/src/backend/gl/texture/graphical.js
new file mode 100644
index 00000000..18360021
--- /dev/null
+++ b/src/backend/gl/texture/graphical.js
@@ -0,0 +1,15 @@
+const { GLTextureUnsigned } = require('./unsigned');
+
+class GLTextureGraphical extends GLTextureUnsigned {
+ constructor(settings) {
+ super(settings);
+ this.type = 'ArrayTexture(4)';
+ }
+ toArray() {
+ return this.renderValues();
+ }
+}
+
+module.exports = {
+ GLTextureGraphical
+};
\ No newline at end of file
diff --git a/src/backend/gl/texture/index.js b/src/backend/gl/texture/index.js
new file mode 100644
index 00000000..d5cac523
--- /dev/null
+++ b/src/backend/gl/texture/index.js
@@ -0,0 +1,125 @@
+const { Texture } = require('../../../texture');
+
+/**
+ * @class
+ * @property framebuffer
+ * @extends Texture
+ */
+class GLTexture extends Texture {
+ /**
+ * @returns {Number}
+ * @abstract
+ */
+ get textureType() {
+ throw new Error(`"textureType" not implemented on ${ this.name }`);
+ }
+
+ clone() {
+ return new this.constructor(this);
+ }
+
+ /**
+ * @returns {Boolean}
+ */
+ beforeMutate() {
+ if (this.texture._refs > 1) {
+ this.newTexture();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @private
+ */
+ cloneTexture() {
+ this.texture._refs--;
+ const { context: gl, size, texture, kernel } = this;
+ if (kernel.debug) {
+ console.warn('cloning internal texture');
+ }
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer());
+ selectTexture(gl, texture);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ const target = gl.createTexture();
+ selectTexture(gl, target);
+ gl.texImage2D(gl.TEXTURE_2D, 0, this.internalFormat, size[0], size[1], 0, this.textureFormat, this.textureType, null);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, size[0], size[1]);
+ target._refs = 1;
+ this.texture = target;
+ }
+
+ /**
+ * @private
+ */
+ newTexture() {
+ this.texture._refs--;
+ const gl = this.context;
+ const size = this.size;
+ const kernel = this.kernel;
+ if (kernel.debug) {
+ console.warn('new internal texture');
+ }
+ const target = gl.createTexture();
+ selectTexture(gl, target);
+ gl.texImage2D(gl.TEXTURE_2D, 0, this.internalFormat, size[0], size[1], 0, this.textureFormat, this.textureType, null);
+ target._refs = 1;
+ this.texture = target;
+ }
+
+ clear() {
+ if (this.texture._refs) {
+ this.texture._refs--;
+ const gl = this.context;
+ const target = this.texture = gl.createTexture();
+ selectTexture(gl, target);
+ const size = this.size;
+ target._refs = 1;
+ gl.texImage2D(gl.TEXTURE_2D, 0, this.internalFormat, size[0], size[1], 0, this.textureFormat, this.textureType, null);
+ }
+ const { context: gl, texture } = this;
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer());
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ selectTexture(gl, texture);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ gl.clearColor(0, 0, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ }
+
+ delete() {
+ if (this._deleted) return;
+ this._deleted = true;
+ if (this.texture._refs) {
+ this.texture._refs--;
+ if (this.texture._refs) return;
+ }
+ this.context.deleteTexture(this.texture);
+ // TODO: Remove me
+ // if (this.texture._refs === 0 && this._framebuffer) {
+ // this.context.deleteFramebuffer(this._framebuffer);
+ // this._framebuffer = null;
+ // }
+ }
+
+ framebuffer() {
+ if (!this._framebuffer) {
+ this._framebuffer = this.kernel.getRawValueFramebuffer(this.size[0], this.size[1]);
+ }
+ return this._framebuffer;
+ }
+}
+
+function selectTexture(gl, texture) {
+ /* Maximum a texture can be, so that collision is highly unlikely
+ * basically gl.TEXTURE15 + gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
+ * Was gl.TEXTURE31, but safari didn't like it
+ * */
+ gl.activeTexture(gl.TEXTURE15);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+}
+
+module.exports = { GLTexture };
\ No newline at end of file
diff --git a/src/backend/gl/texture/memory-optimized-2d.js b/src/backend/gl/texture/memory-optimized-2d.js
new file mode 100644
index 00000000..20234ee3
--- /dev/null
+++ b/src/backend/gl/texture/memory-optimized-2d.js
@@ -0,0 +1,16 @@
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureMemoryOptimized2D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'MemoryOptimizedNumberTexture';
+ }
+ toArray() {
+ return utils.erectMemoryOptimized2DFloat(this.renderValues(), this.output[0], this.output[1]);
+ }
+}
+
+module.exports = {
+ GLTextureMemoryOptimized2D
+};
\ No newline at end of file
diff --git a/src/backend/gl/texture/memory-optimized-3d.js b/src/backend/gl/texture/memory-optimized-3d.js
new file mode 100644
index 00000000..f65e5f9f
--- /dev/null
+++ b/src/backend/gl/texture/memory-optimized-3d.js
@@ -0,0 +1,16 @@
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureMemoryOptimized3D extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'MemoryOptimizedNumberTexture';
+ }
+ toArray() {
+ return utils.erectMemoryOptimized3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]);
+ }
+}
+
+module.exports = {
+ GLTextureMemoryOptimized3D
+};
\ No newline at end of file
diff --git a/src/backend/gl/texture/memory-optimized.js b/src/backend/gl/texture/memory-optimized.js
new file mode 100644
index 00000000..03474f58
--- /dev/null
+++ b/src/backend/gl/texture/memory-optimized.js
@@ -0,0 +1,16 @@
+const { utils } = require('../../../utils');
+const { GLTextureFloat } = require('./float');
+
+class GLTextureMemoryOptimized extends GLTextureFloat {
+ constructor(settings) {
+ super(settings);
+ this.type = 'MemoryOptimizedNumberTexture';
+ }
+ toArray() {
+ return utils.erectMemoryOptimizedFloat(this.renderValues(), this.output[0]);
+ }
+}
+
+module.exports = {
+ GLTextureMemoryOptimized
+};
\ No newline at end of file
diff --git a/src/backend/gl/texture/unsigned-2d.js b/src/backend/gl/texture/unsigned-2d.js
new file mode 100644
index 00000000..3adba8b1
--- /dev/null
+++ b/src/backend/gl/texture/unsigned-2d.js
@@ -0,0 +1,16 @@
+const { utils } = require('../../../utils');
+const { GLTextureUnsigned } = require('./unsigned');
+
+class GLTextureUnsigned2D extends GLTextureUnsigned {
+ constructor(settings) {
+ super(settings);
+ this.type = 'NumberTexture';
+ }
+ toArray() {
+ return utils.erect2DPackedFloat(this.renderValues(), this.output[0], this.output[1]);
+ }
+}
+
+module.exports = {
+ GLTextureUnsigned2D
+};
\ No newline at end of file
diff --git a/src/backend/gl/texture/unsigned-3d.js b/src/backend/gl/texture/unsigned-3d.js
new file mode 100644
index 00000000..ccedf143
--- /dev/null
+++ b/src/backend/gl/texture/unsigned-3d.js
@@ -0,0 +1,16 @@
+const { utils } = require('../../../utils');
+const { GLTextureUnsigned } = require('./unsigned');
+
+class GLTextureUnsigned3D extends GLTextureUnsigned {
+ constructor(settings) {
+ super(settings);
+ this.type = 'NumberTexture';
+ }
+ toArray() {
+ return utils.erect3DPackedFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]);
+ }
+}
+
+module.exports = {
+ GLTextureUnsigned3D
+};
\ No newline at end of file
diff --git a/src/backend/gl/texture/unsigned.js b/src/backend/gl/texture/unsigned.js
new file mode 100644
index 00000000..0a357206
--- /dev/null
+++ b/src/backend/gl/texture/unsigned.js
@@ -0,0 +1,37 @@
+const { utils } = require('../../../utils');
+const { GLTexture } = require('./index');
+
+class GLTextureUnsigned extends GLTexture {
+ get textureType() {
+ return this.context.UNSIGNED_BYTE;
+ }
+ constructor(settings) {
+ super(settings);
+ this.type = 'NumberTexture';
+ }
+ renderRawOutput() {
+ const { context: gl } = this;
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer());
+ gl.framebufferTexture2D(
+ gl.FRAMEBUFFER,
+ gl.COLOR_ATTACHMENT0,
+ gl.TEXTURE_2D,
+ this.texture,
+ 0
+ );
+ const result = new Uint8Array(this.size[0] * this.size[1] * 4);
+ gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.UNSIGNED_BYTE, result);
+ return result;
+ }
+ renderValues() {
+ if (this._deleted) return null;
+ return new Float32Array(this.renderRawOutput().buffer);
+ }
+ toArray() {
+ return utils.erectPackedFloat(this.renderValues(), this.output[0]);
+ }
+}
+
+module.exports = {
+ GLTextureUnsigned
+};
\ No newline at end of file
diff --git a/src/backend/headless-gl/kernel.js b/src/backend/headless-gl/kernel.js
new file mode 100644
index 00000000..f91b1352
--- /dev/null
+++ b/src/backend/headless-gl/kernel.js
@@ -0,0 +1,145 @@
+const getContext = require('gl');
+const { WebGLKernel } = require('../web-gl/kernel');
+const { glKernelString } = require('../gl/kernel-string');
+
+let isSupported = null;
+let testCanvas = null;
+let testContext = null;
+let testExtensions = null;
+let features = null;
+
+class HeadlessGLKernel extends WebGLKernel {
+ static get isSupported() {
+ if (isSupported !== null) return isSupported;
+ this.setupFeatureChecks();
+ isSupported = testContext !== null;
+ return isSupported;
+ }
+
+ static setupFeatureChecks() {
+ testCanvas = null;
+ testExtensions = null;
+ if (typeof getContext !== 'function') return;
+ try { // just in case, edge cases
+ testContext = getContext(2, 2, {
+ preserveDrawingBuffer: true
+ });
+ if (!testContext || !testContext.getExtension) return;
+ testExtensions = {
+ STACKGL_resize_drawingbuffer: testContext.getExtension('STACKGL_resize_drawingbuffer'),
+ STACKGL_destroy_context: testContext.getExtension('STACKGL_destroy_context'),
+ OES_texture_float: testContext.getExtension('OES_texture_float'),
+ OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'),
+ OES_element_index_uint: testContext.getExtension('OES_element_index_uint'),
+ WEBGL_draw_buffers: testContext.getExtension('WEBGL_draw_buffers'),
+ WEBGL_color_buffer_float: testContext.getExtension('WEBGL_color_buffer_float'),
+ };
+ features = this.getFeatures();
+ } catch (e) {
+ console.warn(e);
+ }
+ }
+
+ static isContextMatch(context) {
+ try {
+ return context.getParameter(context.RENDERER) === 'ANGLE';
+ } catch (e) {
+ return false;
+ }
+ }
+
+ static getIsTextureFloat() {
+ return Boolean(testExtensions.OES_texture_float);
+ }
+
+ static getIsDrawBuffers() {
+ return Boolean(testExtensions.WEBGL_draw_buffers);
+ }
+
+ static getChannelCount() {
+ return testExtensions.WEBGL_draw_buffers ?
+ testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) :
+ 1;
+ }
+
+ static getMaxTextureSize() {
+ return testContext.getParameter(testContext.MAX_TEXTURE_SIZE);
+ }
+
+ static get testCanvas() {
+ return testCanvas;
+ }
+
+ static get testContext() {
+ return testContext;
+ }
+
+ static get features() {
+ return features;
+ }
+
+ initCanvas() {
+ return {};
+ }
+
+ initContext() {
+ return getContext(2, 2, {
+ preserveDrawingBuffer: true
+ });
+ }
+
+ 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);
+ if (!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(context) {
+ const extension = context.getExtension('STACKGL_destroy_context');
+ if (extension && extension.destroy) {
+ extension.destroy();
+ }
+ }
+
+ /**
+ * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused.
+ */
+ toString() {
+ const setupContextString = `const gl = context || require('gl')(1, 1);\n`;
+ const destroyContextString = ` if (!context) { gl.getExtension('STACKGL_destroy_context').destroy(); }\n`;
+ return glKernelString(this.constructor, arguments, this, setupContextString, destroyContextString);
+ }
+
+ setOutput(output) {
+ super.setOutput(output);
+ if (this.graphical && this.extensions.STACKGL_resize_drawingbuffer) {
+ this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0], this.maxTexSize[1]);
+ }
+ return this;
+ }
+}
+
+module.exports = {
+ HeadlessGLKernel
+};
\ No newline at end of file
diff --git a/src/backend/kernel-base.js b/src/backend/kernel-base.js
deleted file mode 100644
index 81348197..00000000
--- a/src/backend/kernel-base.js
+++ /dev/null
@@ -1,376 +0,0 @@
-'use strict';
-
-const utils = require('../core/utils');
-
-module.exports = class BaseKernel {
-
- /**
- * @constructor BaseKernel
- *
- * @desc Implements the base class for Kernels, and is used as a
- * parent class for all Kernel implementations.
- *
- * This contains the basic methods needed by all Kernel implementations,
- * like setDimensions, addSubKernel, etc.
- *
- * @prop {Array} paramNames - Name of the parameters of the kernel function
- * @prop {String} fnString - Kernel function as a String
- * @prop {Array} dimensions - Dimensions of the kernel function, this.thread.x, etc.
- * @prop {Boolean} debug - Toggle debug mode
- * @prop {String} graphical - Toggle graphical mode
- * @prop {number} loopMaxIterations - Maximum number of loop iterations
- * @prop {Object} constants - Global constants
- * @prop {Array} subKernels - Sub kernels bound to this kernel instance
- * @prop {Object} subKernelProperties - Sub kernels bound to this kernel instance as key/value pairs
- * @prop {Array} subKernelOutputVariableNames - Names of the variables outputted by the subkerls
- *
- */
- constructor(fnString, settings) {
- this.paramNames = utils.getParamNamesFromString(fnString);
- this.fnString = fnString;
- this.output = null;
- this.debug = false;
- this.graphical = false;
- this.loopMaxIterations = 0;
- this.constants = null;
- this.wraparound = null;
- this.hardcodeConstants = null;
- this.outputToTexture = null;
- this.texSize = null;
- this._canvas = null;
- this._webGl = null;
- this.threadDim = null;
- this.floatTextures = null;
- this.floatOutput = null;
- this.floatOutputForce = null;
- this.addFunction = null;
- this.functions = null;
- this.nativeFunctions = null;
- this.copyData = true;
- this.subKernels = null;
- this.subKernelProperties = null;
- this.subKernelNames = null;
- this.subKernelOutputVariableNames = null;
- this.functionBuilder = null;
- this.paramTypes = null;
-
- for (let p in settings) {
- if (!settings.hasOwnProperty(p) || !this.hasOwnProperty(p)) continue;
- this[p] = settings[p];
- }
- if (settings.hasOwnProperty('canvas')) {
- this._canvas = settings.canvas;
- }
- if (settings.hasOwnProperty('output')) {
- this.setOutput(settings.output); // Flatten output object
- }
-
- if (!this._canvas) this._canvas = utils.initCanvas();
- }
-
- build() {
- throw new Error('"build" not defined on Base');
- }
-
- /**
- * @memberOf KernelBase#
- * @function
- * @name setupParams
- *
- * @desc Setup the parameter types for the parameters
- * supplied to the Kernel function
- *
- * @param {Array} args - The actual parameters sent to the Kernel
- *
- */
- setupParams(args) {
- const paramTypes = this.paramTypes = [];
- for (let i = 0; i < args.length; i++) {
- const param = args[i];
- const paramType = utils.getArgumentType(param);
- paramTypes.push(paramType);
- }
- }
-
- setAddFunction(cb) {
- this.addFunction = cb;
- return this;
- }
-
- setFunctions(functions) {
- this.functions = functions;
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name setOutput
- *
- * @desc Set dimensions of the kernel function
- *
- * @param {Array|Object} output - The output array to set the kernel output size to
- *
- */
- setOutput(output) {
- if (output.hasOwnProperty('x')) {
- if (output.hasOwnProperty('y')) {
- if (output.hasOwnProperty('z')) {
- this.output = [output.x, output.y, output.z];
- } else {
- this.output = [output.x, output.y];
- }
- } else {
- this.output = [output.x];
- }
- } else {
- this.output = output;
- }
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name setDebug
- *
- * @desc Toggle debug mode
- *
- * @param {Boolean} flag - true to enable debug
- *
- */
- setDebug(flag) {
- this.debug = flag;
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name setGraphical
- *
- * @desc Toggle graphical output mode
- *
- * @param {Boolean} flag - true to enable graphical output
- *
- */
- setGraphical(flag) {
- this.graphical = flag;
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name setLoopMaxIterations
- *
- * @desc Set the maximum number of loop iterations
- *
- * @param {number} max - iterations count
- *
- */
- setLoopMaxIterations(max) {
- this.loopMaxIterations = max;
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name setConstants
- * @desc Set Constants
- */
- setConstants(constants) {
- this.constants = constants;
- return this;
- }
-
- setWraparound(flag) {
- console.warn('Wraparound mode is not supported and undocumented.');
- this.wraparound = flag;
- return this;
- }
-
- setHardcodeConstants(flag) {
- this.hardcodeConstants = flag;
- return this;
- }
-
- setOutputToTexture(flag) {
- this.outputToTexture = flag;
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name setFloatTextures
- *
- * @desc Toggle texture output mode
- *
- * @param {Boolean} flag - true to enable floatTextures
- *
- */
- setFloatTextures(flag) {
- this.floatTextures = flag;
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name setFloatOutput
- *
- * @desc Toggle output mode
- *
- * @param {Boolean} flag - true to enable float
- *
- */
- setFloatOutput(flag) {
- this.floatOutput = flag;
- return this;
- }
-
- setFloatOutputForce(flag) {
- this.floatOutputForce = flag;
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name setCanvas
- *
- * @desc Bind the canvas to kernel
- *
- * @param {Canvas} canvas - Canvas to bind
- *
- */
- setCanvas(canvas) {
- this._canvas = canvas;
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name setCanvas
- *
- * @desc Bind the webGL instance to kernel
- *
- * @param {Canvas} webGL - webGL instance to bind
- *
- */
- setWebGl(webGl) {
- this._webGl = webGl;
- return this;
- }
-
- setCopyData(copyData) {
- this.copyData = copyData;
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name getCanvas()
- *
- * @desc Returns the current canvas instance bound to the kernel
- *
- */
- getCanvas() {
- return this._canvas;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name getWebGl()
- *
- * @desc Returns the current webGl instance bound to the kernel
- *
- */
- getWebGl() {
- return this._webGl;
- }
-
- validateOptions() {
- throw new Error('validateOptions not defined');
- }
-
- exec() {
- return this.execute.apply(this, arguments);
- }
-
- execute() {
- //
- // Prepare the required objects
- //
- const args = (arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments));
-
- //
- // Setup and return the promise, and execute the function, in synchronous mode
- //
- return utils.newPromise((accept, reject) => {
- try {
- accept(this.run.apply(this, args));
- } catch (e) {
- //
- // Error : throw rejection
- //
- reject(e);
- }
- });
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name addSubKernel
- *
- * @desc Add a sub kernel to the root kernel instance.
- * This is what `createKernelMap` uses.
- *
- * @param {String} fnString - function (as a String) of the subKernel to add
- *
- */
- addSubKernel(fnString) {
- if (this.subKernels === null) {
- this.subKernels = [];
- this.subKernelNames = [];
- }
- this.subKernels.push(fnString);
- this.subKernelNames.push(utils.getFunctionNameFromString(fnString));
- return this;
- }
-
- /**
- * @memberOf BaseKernel#
- * @function
- * @name addSubKernelProperty
- *
- * @desc Add a sub kernel to the root kernel instance, indexed by a property name
- * This is what `createKernelMap` uses.
- *
- * @param {String} property - property key for the subKernel
- * @param {String} fnString - function (as a String) of the subKernel to add
- *
- */
- addSubKernelProperty(property, fnString) {
- if (this.subKernelProperties === null) {
- this.subKernelProperties = {};
- this.subKernelNames = [];
- }
- if (this.subKernelProperties.hasOwnProperty(property)) {
- throw new Error(`cannot add sub kernel ${ property }, already defined`);
- }
- this.subKernelProperties[property] = fnString;
- this.subKernelNames.push(utils.getFunctionNameFromString(fnString));
- return this;
- }
-
- addNativeFunction(name, source) {
- this.functionBuilder.addNativeFunction(name, source);
- }
-};
\ No newline at end of file
diff --git a/src/backend/kernel-run-shortcut.js b/src/backend/kernel-run-shortcut.js
deleted file mode 100644
index 4508fddf..00000000
--- a/src/backend/kernel-run-shortcut.js
+++ /dev/null
@@ -1,34 +0,0 @@
-'use strict';
-
-const utils = require('../core/utils');
-
-module.exports = function kernelRunShortcut(kernel) {
- const shortcut = function() {
- return kernel.run.apply(kernel, arguments);
- };
-
- utils.allPropertiesOf(kernel).forEach((key) => {
- if (key[0] === '_' && key[1] === '_') return;
- if (typeof kernel[key] === 'function') {
- if (key.substring(0, 3) === 'add' || key.substring(0, 3) === 'set') {
- shortcut[key] = function() {
- kernel[key].apply(kernel, arguments);
- return shortcut;
- };
- } else {
- shortcut[key] = kernel[key].bind(kernel);
- }
- } else {
- shortcut.__defineGetter__(key, () => {
- return kernel[key];
- });
- shortcut.__defineSetter__(key, (value) => {
- kernel[key] = value;
- });
- }
- });
-
- shortcut.kernel = kernel;
-
- return shortcut;
-};
\ No newline at end of file
diff --git a/src/backend/kernel-value.js b/src/backend/kernel-value.js
new file mode 100644
index 00000000..1fdfc369
--- /dev/null
+++ b/src/backend/kernel-value.js
@@ -0,0 +1,70 @@
+/**
+ * @class KernelValue
+ */
+class KernelValue {
+ /**
+ * @param {KernelVariable} value
+ * @param {IKernelValueSettings} settings
+ */
+ constructor(value, settings) {
+ const {
+ name,
+ kernel,
+ context,
+ checkContext,
+ onRequestContextHandle,
+ onUpdateValueMismatch,
+ origin,
+ strictIntegers,
+ type,
+ tactic,
+ } = settings;
+ if (!name) {
+ throw new Error('name not set');
+ }
+ if (!type) {
+ throw new Error('type not set');
+ }
+ if (!origin) {
+ throw new Error('origin not set');
+ }
+ if (origin !== 'user' && origin !== 'constants') {
+ throw new Error(`origin must be "user" or "constants" value is "${ origin }"`);
+ }
+ if (!onRequestContextHandle) {
+ throw new Error('onRequestContextHandle is not set');
+ }
+ this.name = name;
+ this.origin = origin;
+ this.tactic = tactic;
+ this.varName = origin === 'constants' ? `constants.${name}` : name;
+ this.kernel = kernel;
+ this.strictIntegers = strictIntegers;
+ // handle textures
+ this.type = value.type || type;
+ this.size = value.size || null;
+ this.index = null;
+ this.context = context;
+ this.checkContext = checkContext !== null && checkContext !== undefined ? checkContext : true;
+ this.contextHandle = null;
+ this.onRequestContextHandle = onRequestContextHandle;
+ this.onUpdateValueMismatch = onUpdateValueMismatch;
+ this.forceUploadEachRun = null;
+ }
+
+ get id() {
+ return `${this.origin}_${name}`;
+ }
+
+ getSource() {
+ throw new Error(`"getSource" not defined on ${ this.constructor.name }`);
+ }
+
+ updateValue(value) {
+ throw new Error(`"updateValue" not defined on ${ this.constructor.name }`);
+ }
+}
+
+module.exports = {
+ KernelValue
+};
\ No newline at end of file
diff --git a/src/backend/kernel.js b/src/backend/kernel.js
new file mode 100644
index 00000000..dd68ca10
--- /dev/null
+++ b/src/backend/kernel.js
@@ -0,0 +1,949 @@
+const { utils } = require('../utils');
+const { Input } = require('../input');
+
+class Kernel {
+ /**
+ * @type {Boolean}
+ */
+ static get isSupported() {
+ throw new Error(`"isSupported" not implemented on ${ this.name }`);
+ }
+
+ /**
+ * @abstract
+ * @returns {Boolean}
+ */
+ static isContextMatch(context) {
+ throw new Error(`"isContextMatch" not implemented on ${ this.name }`);
+ }
+
+ /**
+ * @type {IKernelFeatures}
+ * Used internally to populate the kernel.feature, which is a getter for the output of this value
+ */
+ static getFeatures() {
+ throw new Error(`"getFeatures" not implemented on ${ this.name }`);
+ }
+
+ static destroyContext(context) {
+ 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 }`);
+ }
+
+ /**
+ *
+ * @param {string|IKernelJSON} source
+ * @param [settings]
+ */
+ constructor(source, settings) {
+ if (typeof source !== 'object') {
+ if (typeof source !== 'string') {
+ throw new Error('source not a string');
+ }
+ if (!utils.isFunctionString(source)) {
+ throw new Error('source not a function string');
+ }
+ }
+ this.useLegacyEncoder = false;
+ this.fallbackRequested = false;
+ this.onRequestFallback = null;
+
+ /**
+ * Name of the arguments found from parsing source argument
+ * @type {String[]}
+ */
+ this.argumentNames = typeof source === 'string' ? utils.getArgumentNamesFromString(source) : null;
+ this.argumentTypes = null;
+ this.argumentSizes = null;
+ this.argumentBitRatios = null;
+ this.kernelArguments = null;
+ this.kernelConstants = null;
+ this.forceUploadKernelConstants = null;
+
+
+ /**
+ * The function source
+ * @type {String|IKernelJSON}
+ */
+ this.source = source;
+
+ /**
+ * The size of the kernel's output
+ * @type {Number[]}
+ */
+ this.output = null;
+
+ /**
+ * Debug mode
+ * @type {Boolean}
+ */
+ this.debug = false;
+
+ /**
+ * Graphical mode
+ * @type {Boolean}
+ */
+ this.graphical = false;
+
+ /**
+ * Maximum loops when using argument values to prevent infinity
+ * @type {Number}
+ */
+ this.loopMaxIterations = 0;
+
+ /**
+ * Constants used in kernel via `this.constants`
+ * @type {Object}
+ */
+ this.constants = null;
+
+ /**
+ *
+ * @type {Object.}
+ */
+ this.constantTypes = null;
+
+ /**
+ *
+ * @type {Object.}
+ */
+ this.constantBitRatios = null;
+
+ /**
+ *
+ * @type {boolean}
+ */
+ this.dynamicArguments = false;
+
+ /**
+ *
+ * @type {boolean}
+ */
+ this.dynamicOutput = false;
+
+ /**
+ *
+ * @type {Object}
+ */
+ this.canvas = null;
+
+ /**
+ *
+ * @type {Object}
+ */
+ this.context = null;
+
+ /**
+ *
+ * @type {Boolean}
+ */
+ this.checkContext = null;
+
+ /**
+ *
+ * @type {GPU}
+ */
+ this.gpu = null;
+
+ /**
+ *
+ * @type {IGPUFunction[]}
+ */
+ this.functions = null;
+
+ /**
+ *
+ * @type {IGPUNativeFunction[]}
+ */
+ this.nativeFunctions = null;
+
+ /**
+ *
+ * @type {String}
+ */
+ this.injectedNative = null;
+
+ /**
+ *
+ * @type {ISubKernel[]}
+ */
+ this.subKernels = null;
+
+ /**
+ *
+ * @type {Boolean}
+ */
+ this.validate = true;
+
+ /**
+ * Enforces kernel to write to a new array or texture on run
+ * @type {Boolean}
+ */
+ this.immutable = false;
+
+ /**
+ * Enforces kernel to write to a texture on run
+ * @type {Boolean}
+ */
+ this.pipeline = false;
+
+ /**
+ * Make GPU use single precision or unsigned. Acceptable values: 'single' or 'unsigned'
+ * @type {String|null}
+ * @enum 'single' | 'unsigned'
+ */
+ this.precision = null;
+
+ /**
+ *
+ * @type {String|null}
+ * @enum 'speed' | 'balanced' | 'precision'
+ */
+ this.tactic = null;
+
+ this.plugins = null;
+
+ this.returnType = null;
+ this.leadingReturnStatement = null;
+ this.followingReturnStatement = null;
+ this.optimizeFloatMemory = null;
+ this.strictIntegers = false;
+ this.fixIntegerDivisionAccuracy = null;
+ this.built = false;
+ this.signature = null;
+ }
+
+ /**
+ *
+ * @param {IDirectKernelSettings|IJSONSettings} settings
+ */
+ mergeSettings(settings) {
+ for (let p in settings) {
+ if (!settings.hasOwnProperty(p) || !this.hasOwnProperty(p)) continue;
+ switch (p) {
+ case 'output':
+ if (!Array.isArray(settings.output)) {
+ this.setOutput(settings.output); // Flatten output object
+ continue;
+ }
+ break;
+ case 'functions':
+ this.functions = [];
+ for (let i = 0; i < settings.functions.length; i++) {
+ this.addFunction(settings.functions[i]);
+ }
+ continue;
+ case 'graphical':
+ if (settings[p] && !settings.hasOwnProperty('precision')) {
+ this.precision = 'unsigned';
+ }
+ this[p] = settings[p];
+ continue;
+ case 'nativeFunctions':
+ if (!settings.nativeFunctions) continue;
+ this.nativeFunctions = [];
+ for (let i = 0; i < settings.nativeFunctions.length; i++) {
+ const s = settings.nativeFunctions[i];
+ const { name, source } = s;
+ this.addNativeFunction(name, source, s);
+ }
+ continue;
+ }
+ this[p] = settings[p];
+ }
+
+ if (!this.canvas) this.canvas = this.initCanvas();
+ if (!this.context) this.context = this.initContext();
+ if (!this.plugins) this.plugins = this.initPlugins(settings);
+ }
+ /**
+ * @desc Builds the Kernel, by compiling Fragment and Vertical Shaders,
+ * and instantiates the program.
+ * @abstract
+ */
+ build() {
+ throw new Error(`"build" not defined on ${ this.constructor.name }`);
+ }
+
+ /**
+ * @desc Run the kernel program, and send the output to renderOutput
+ * This method calls a helper method *renderOutput* to return the result.
+ * @returns {Float32Array|Float32Array[]|Float32Array[][]|void} Result The final output of the program, as float, and as Textures for reuse.
+ * @abstract
+ */
+ run() {
+ throw new Error(`"run" not defined on ${ this.constructor.name }`)
+ }
+
+ /**
+ * @abstract
+ * @return {Object}
+ */
+ initCanvas() {
+ throw new Error(`"initCanvas" not defined on ${ this.constructor.name }`);
+ }
+
+ /**
+ * @abstract
+ * @return {Object}
+ */
+ initContext() {
+ throw new Error(`"initContext" not defined on ${ this.constructor.name }`);
+ }
+
+ /**
+ * @param {IDirectKernelSettings} settings
+ * @return {string[]};
+ * @abstract
+ */
+ initPlugins(settings) {
+ throw new Error(`"initPlugins" not defined on ${ this.constructor.name }`);
+ }
+
+ /**
+ *
+ * @param {KernelFunction|string|IGPUFunction} source
+ * @param {IFunctionSettings} [settings]
+ * @return {Kernel}
+ */
+ addFunction(source, settings = {}) {
+ if (source.name && source.source && source.argumentTypes && 'returnType' in source) {
+ this.functions.push(source);
+ } else if ('settings' in source && 'source' in source) {
+ this.functions.push(this.functionToIGPUFunction(source.source, source.settings));
+ } else if (typeof source === 'string' || typeof source === 'function') {
+ this.functions.push(this.functionToIGPUFunction(source, settings));
+ } else {
+ throw new Error(`function not properly defined`);
+ }
+ return this;
+ }
+
+ /**
+ *
+ * @param {string} name
+ * @param {string} source
+ * @param {IGPUFunctionSettings} [settings]
+ */
+ addNativeFunction(name, source, settings = {}) {
+ const { argumentTypes, argumentNames } = settings.argumentTypes ?
+ splitArgumentTypes(settings.argumentTypes) :
+ this.constructor.nativeFunctionArguments(source) || {};
+ this.nativeFunctions.push({
+ name,
+ source,
+ settings,
+ argumentTypes,
+ argumentNames,
+ returnType: settings.returnType || this.constructor.nativeFunctionReturnType(source)
+ });
+ return this;
+ }
+
+ /**
+ * @desc Setup the parameter types for the parameters
+ * supplied to the Kernel function
+ *
+ * @param {IArguments} args - The actual parameters sent to the Kernel
+ */
+ setupArguments(args) {
+ this.kernelArguments = [];
+ if (!this.argumentTypes) {
+ if (!this.argumentTypes) {
+ this.argumentTypes = [];
+ for (let i = 0; i < args.length; i++) {
+ const argType = utils.getVariableType(args[i], this.strictIntegers);
+ const type = argType === 'Integer' ? 'Number' : argType;
+ this.argumentTypes.push(type);
+ this.kernelArguments.push({
+ type
+ });
+ }
+ }
+ } else {
+ for (let i = 0; i < this.argumentTypes.length; i++) {
+ this.kernelArguments.push({
+ type: this.argumentTypes[i]
+ });
+ }
+ }
+
+ // setup sizes
+ this.argumentSizes = new Array(args.length);
+ this.argumentBitRatios = new Int32Array(args.length);
+
+ for (let i = 0; i < args.length; i++) {
+ const arg = args[i];
+ this.argumentSizes[i] = arg.constructor === Input ? arg.size : null;
+ this.argumentBitRatios[i] = this.getBitRatio(arg);
+ }
+
+ if (this.argumentNames.length !== args.length) {
+ throw new Error(`arguments are miss-aligned`);
+ }
+ }
+
+ /**
+ * Setup constants
+ */
+ setupConstants() {
+ this.kernelConstants = [];
+ let needsConstantTypes = this.constantTypes === null;
+ if (needsConstantTypes) {
+ this.constantTypes = {};
+ }
+ this.constantBitRatios = {};
+ if (this.constants) {
+ for (let name in this.constants) {
+ if (needsConstantTypes) {
+ const type = utils.getVariableType(this.constants[name], this.strictIntegers);
+ this.constantTypes[name] = type;
+ this.kernelConstants.push({
+ name,
+ type
+ });
+ } else {
+ this.kernelConstants.push({
+ name,
+ type: this.constantTypes[name]
+ });
+ }
+ this.constantBitRatios[name] = this.getBitRatio(this.constants[name]);
+ }
+ }
+ }
+
+ /**
+ *
+ * @param flag
+ * @return {this}
+ */
+ setOptimizeFloatMemory(flag) {
+ this.optimizeFloatMemory = flag;
+ return this;
+ }
+
+ /**
+ *
+ * @param {Array|Object} output
+ * @return {number[]}
+ */
+ toKernelOutput(output) {
+ if (output.hasOwnProperty('x')) {
+ if (output.hasOwnProperty('y')) {
+ if (output.hasOwnProperty('z')) {
+ return [output.x, output.y, output.z];
+ } else {
+ return [output.x, output.y];
+ }
+ } else {
+ return [output.x];
+ }
+ } else {
+ return output;
+ }
+ }
+
+ /**
+ * @desc Set output dimensions of the kernel function
+ * @param {Array|Object} output - The output array to set the kernel output size to
+ * @return {this}
+ */
+ setOutput(output) {
+ this.output = this.toKernelOutput(output);
+ return this;
+ }
+
+ /**
+ * @desc Toggle debug mode
+ * @param {Boolean} flag - true to enable debug
+ * @return {this}
+ */
+ setDebug(flag) {
+ this.debug = flag;
+ return this;
+ }
+
+ /**
+ * @desc Toggle graphical output mode
+ * @param {Boolean} flag - true to enable graphical output
+ * @return {this}
+ */
+ setGraphical(flag) {
+ this.graphical = flag;
+ this.precision = 'unsigned';
+ return this;
+ }
+
+ /**
+ * @desc Set the maximum number of loop iterations
+ * @param {number} max - iterations count
+ * @return {this}
+ */
+ setLoopMaxIterations(max) {
+ this.loopMaxIterations = max;
+ return this;
+ }
+
+ /**
+ * @desc Set Constants
+ * @return {this}
+ */
+ setConstants(constants) {
+ this.constants = constants;
+ return this;
+ }
+
+ /**
+ *
+ * @param {IKernelValueTypes} constantTypes
+ * @return {this}
+ */
+ setConstantTypes(constantTypes) {
+ this.constantTypes = constantTypes;
+ return this;
+ }
+
+ /**
+ *
+ * @param {IFunction[]|KernelFunction[]} functions
+ * @return {this}
+ */
+ setFunctions(functions) {
+ for (let i = 0; i < functions.length; i++) {
+ this.addFunction(functions[i]);
+ }
+ return this;
+ }
+
+ /**
+ *
+ * @param {IGPUNativeFunction[]} nativeFunctions
+ * @return {this}
+ */
+ setNativeFunctions(nativeFunctions) {
+ for (let i = 0; i < nativeFunctions.length; i++) {
+ const settings = nativeFunctions[i];
+ const { name, source } = settings;
+ this.addNativeFunction(name, source, settings);
+ }
+ return this;
+ }
+
+ /**
+ *
+ * @param {String} injectedNative
+ * @return {this}
+ */
+ setInjectedNative(injectedNative) {
+ this.injectedNative = injectedNative;
+ return this;
+ }
+
+ /**
+ * Set writing to texture on/off
+ * @param flag
+ * @return {this}
+ */
+ setPipeline(flag) {
+ this.pipeline = flag;
+ return this;
+ }
+
+ /**
+ * Set precision to 'unsigned' or 'single'
+ * @param {String} flag 'unsigned' or 'single'
+ * @return {this}
+ */
+ setPrecision(flag) {
+ this.precision = flag;
+ return this;
+ }
+
+ /**
+ * @param flag
+ * @return {Kernel}
+ * @deprecated
+ */
+ setDimensions(flag) {
+ utils.warnDeprecated('method', 'setDimensions', 'setOutput');
+ this.output = flag;
+ return this;
+ }
+
+ /**
+ * @param flag
+ * @return {this}
+ * @deprecated
+ */
+ setOutputToTexture(flag) {
+ utils.warnDeprecated('method', 'setOutputToTexture', 'setPipeline');
+ this.pipeline = flag;
+ return this;
+ }
+
+ /**
+ * Set to immutable
+ * @param flag
+ * @return {this}
+ */
+ setImmutable(flag) {
+ this.immutable = flag;
+ return this;
+ }
+
+ /**
+ * @desc Bind the canvas to kernel
+ * @param {Object} canvas
+ * @return {this}
+ */
+ setCanvas(canvas) {
+ this.canvas = canvas;
+ return this;
+ }
+
+ /**
+ * @param {Boolean} flag
+ * @return {this}
+ */
+ setStrictIntegers(flag) {
+ this.strictIntegers = flag;
+ return this;
+ }
+
+ /**
+ *
+ * @param flag
+ * @return {this}
+ */
+ setDynamicOutput(flag) {
+ this.dynamicOutput = flag;
+ return this;
+ }
+
+ /**
+ * @deprecated
+ * @param flag
+ * @return {this}
+ */
+ setHardcodeConstants(flag) {
+ utils.warnDeprecated('method', 'setHardcodeConstants');
+ this.setDynamicOutput(flag);
+ this.setDynamicArguments(flag);
+ return this;
+ }
+
+ /**
+ *
+ * @param flag
+ * @return {this}
+ */
+ setDynamicArguments(flag) {
+ this.dynamicArguments = flag;
+ return this;
+ }
+
+ /**
+ * @param {Boolean} flag
+ * @return {this}
+ */
+ setUseLegacyEncoder(flag) {
+ this.useLegacyEncoder = flag;
+ return this;
+ }
+
+ /**
+ *
+ * @param {Boolean} flag
+ * @return {this}
+ */
+ setWarnVarUsage(flag) {
+ utils.warnDeprecated('method', 'setWarnVarUsage');
+ return this;
+ }
+
+ /**
+ * @deprecated
+ * @returns {Object}
+ */
+ getCanvas() {
+ utils.warnDeprecated('method', 'getCanvas');
+ return this.canvas;
+ }
+
+ /**
+ * @deprecated
+ * @returns {Object}
+ */
+ getWebGl() {
+ utils.warnDeprecated('method', 'getWebGl');
+ return this.context;
+ }
+
+ /**
+ * @desc Bind the webGL instance to kernel
+ * @param {WebGLRenderingContext} context - webGl instance to bind
+ */
+ setContext(context) {
+ this.context = context;
+ return this;
+ }
+
+ /**
+ *
+ * @param {IKernelValueTypes|GPUVariableType[]} argumentTypes
+ * @return {this}
+ */
+ setArgumentTypes(argumentTypes) {
+ if (Array.isArray(argumentTypes)) {
+ this.argumentTypes = argumentTypes;
+ } else {
+ this.argumentTypes = [];
+ for (const p in argumentTypes) {
+ if (!argumentTypes.hasOwnProperty(p)) continue;
+ const argumentIndex = this.argumentNames.indexOf(p);
+ if (argumentIndex === -1) throw new Error(`unable to find argument ${ p }`);
+ this.argumentTypes[argumentIndex] = argumentTypes[p];
+ }
+ }
+ return this;
+ }
+
+ /**
+ *
+ * @param {Tactic} tactic
+ * @return {this}
+ */
+ setTactic(tactic) {
+ this.tactic = tactic;
+ return this;
+ }
+
+ requestFallback(args) {
+ if (!this.onRequestFallback) {
+ throw new Error(`"onRequestFallback" not defined on ${ this.constructor.name }`);
+ }
+ this.fallbackRequested = true;
+ return this.onRequestFallback(args);
+ }
+
+ /**
+ * @desc Validate settings
+ * @abstract
+ */
+ validateSettings() {
+ throw new Error(`"validateSettings" not defined on ${ this.constructor.name }`);
+ }
+
+ /**
+ * @desc Add a sub kernel to the root kernel instance.
+ * This is what `createKernelMap` uses.
+ *
+ * @param {ISubKernel} subKernel - function (as a String) of the subKernel to add
+ */
+ addSubKernel(subKernel) {
+ if (this.subKernels === null) {
+ this.subKernels = [];
+ }
+ if (!subKernel.source) throw new Error('subKernel missing "source" property');
+ if (!subKernel.property && isNaN(subKernel.property)) throw new Error('subKernel missing "property" property');
+ if (!subKernel.name) throw new Error('subKernel missing "name" property');
+ this.subKernels.push(subKernel);
+ return this;
+ }
+
+ /**
+ * @desc Destroys all memory associated with this kernel
+ * @param {Boolean} [removeCanvasReferences] remove any associated canvas references
+ */
+ destroy(removeCanvasReferences) {
+ throw new Error(`"destroy" called on ${ this.constructor.name }`);
+ }
+
+ /**
+ * bit storage ratio of source to target 'buffer', i.e. if 8bit array -> 32bit tex = 4
+ * @param value
+ * @returns {number}
+ */
+ getBitRatio(value) {
+ if (this.precision === 'single') {
+ // 8 and 16 are up-converted to float32
+ return 4;
+ } else if (Array.isArray(value[0])) {
+ return this.getBitRatio(value[0]);
+ } else if (value.constructor === Input) {
+ return this.getBitRatio(value.value);
+ }
+ switch (value.constructor) {
+ case Uint8ClampedArray:
+ case Uint8Array:
+ case Int8Array:
+ return 1;
+ case Uint16Array:
+ case Int16Array:
+ return 2;
+ case Float32Array:
+ case Int32Array:
+ default:
+ return 4;
+ }
+ }
+
+ /**
+ * @param {Boolean} [flip]
+ * @returns {Uint8ClampedArray}
+ */
+ getPixels(flip) {
+ throw new Error(`"getPixels" called on ${ this.constructor.name }`);
+ }
+
+ checkOutput() {
+ if (!this.output || !utils.isArray(this.output)) throw new Error('kernel.output not an array');
+ if (this.output.length < 1) throw new Error('kernel.output is empty, needs at least 1 value');
+ for (let i = 0; i < this.output.length; i++) {
+ if (isNaN(this.output[i]) || this.output[i] < 1) {
+ throw new Error(`${ this.constructor.name }.output[${ i }] incorrectly defined as \`${ this.output[i] }\`, needs to be numeric, and greater than 0`);
+ }
+ }
+ }
+
+ /**
+ *
+ * @param {String} value
+ */
+ prependString(value) {
+ throw new Error(`"prependString" called on ${ this.constructor.name }`);
+ }
+
+ /**
+ *
+ * @param {String} value
+ * @return Boolean
+ */
+ hasPrependString(value) {
+ throw new Error(`"hasPrependString" called on ${ this.constructor.name }`);
+ }
+
+ /**
+ * @return {IKernelJSON}
+ */
+ toJSON() {
+ return {
+ settings: {
+ output: this.output,
+ pipeline: this.pipeline,
+ argumentNames: this.argumentNames,
+ argumentsTypes: this.argumentTypes,
+ constants: this.constants,
+ pluginNames: this.plugins ? this.plugins.map(plugin => plugin.name) : null,
+ returnType: this.returnType,
+ }
+ };
+ }
+
+ /**
+ * @param {IArguments} args
+ */
+ buildSignature(args) {
+ const Constructor = this.constructor;
+ this.signature = Constructor.getSignature(this, Constructor.getArgumentTypes(this, args));
+ }
+
+ /**
+ * @param {Kernel} kernel
+ * @param {IArguments} args
+ * @returns GPUVariableType[]
+ */
+ static getArgumentTypes(kernel, args) {
+ const argumentTypes = new Array(args.length);
+ for (let i = 0; i < args.length; i++) {
+ const arg = args[i];
+ const type = kernel.argumentTypes[i];
+ if (arg.type) {
+ argumentTypes[i] = arg.type;
+ } else {
+ switch (type) {
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ case 'ArrayTexture(1)':
+ argumentTypes[i] = utils.getVariableType(arg);
+ break;
+ default:
+ argumentTypes[i] = type;
+ }
+ }
+ }
+ return argumentTypes;
+ }
+
+ /**
+ *
+ * @param {Kernel} kernel
+ * @param {GPUVariableType[]} argumentTypes
+ * @abstract
+ */
+ static getSignature(kernel, argumentTypes) {
+ throw new Error(`"getSignature" not implemented on ${ this.name }`);
+ }
+
+ /**
+ *
+ * @param {String|Function} source
+ * @param {IFunctionSettings} [settings]
+ * @returns {IGPUFunction}
+ */
+ functionToIGPUFunction(source, settings = {}) {
+ if (typeof source !== 'string' && typeof source !== 'function') throw new Error('source not a string or function');
+ const sourceString = typeof source === 'string' ? source : source.toString();
+ let argumentTypes = [];
+
+ if (Array.isArray(settings.argumentTypes)) {
+ argumentTypes = settings.argumentTypes;
+ } else if (typeof settings.argumentTypes === 'object') {
+ argumentTypes = utils.getArgumentNamesFromString(sourceString)
+ .map(name => settings.argumentTypes[name]) || [];
+ } else {
+ argumentTypes = settings.argumentTypes || [];
+ }
+
+ return {
+ name: utils.getFunctionNameFromString(sourceString) || null,
+ source: sourceString,
+ argumentTypes,
+ returnType: settings.returnType || null,
+ };
+ }
+
+ /**
+ *
+ * @param {Kernel} previousKernel
+ * @abstract
+ */
+ onActivate(previousKernel) {}
+}
+
+function splitArgumentTypes(argumentTypesObject) {
+ const argumentNames = Object.keys(argumentTypesObject);
+ const argumentTypes = [];
+ for (let i = 0; i < argumentNames.length; i++) {
+ const argumentName = argumentNames[i];
+ argumentTypes.push(argumentTypesObject[argumentName]);
+ }
+ return { argumentTypes, argumentNames };
+}
+
+module.exports = {
+ Kernel
+};
\ No newline at end of file
diff --git a/src/backend/runner-base.js b/src/backend/runner-base.js
deleted file mode 100644
index 25eef0f0..00000000
--- a/src/backend/runner-base.js
+++ /dev/null
@@ -1,121 +0,0 @@
-'use strict';
-
-const utils = require('../core/utils');
-const kernelRunShortcut = require('./kernel-run-shortcut');
-
-module.exports = class BaseRunner {
-
- /**
- * @constructor BaseRunner
- *
- * @desc Represents the 'private/protected' namespace of the GPU class
- *
- * I know @private makes more sense, but since the documentation engine state is undetirmined.
- * (See https://github.com/gpujs/gpu.js/issues/19 regarding documentation engine issue)
- * File isolation is currently the best way to go.
- *
- * *base.js* internal functions namespace
- * *gpu.js* PUBLIC function namespace
- *
- * @prop {Object} settings - Settings object used to set Dimensions, etc.
- * @prop {String} kernel - Current kernel instance
- * @prop {Object} canvas - Canvas instance attached to the kernel
- * @prop {Object} webGl - WebGl instance attached to the kernel
- * @prop {Function} fn - Kernel function to run
- * @prop {Object} functionBuilder - FunctionBuilder instance
- * @prop {String} fnString - Kernel function (as a String)
- * @prop {String} endianness - endian information like Little-endian, Big-endian.
- *
- */
-
- constructor(functionBuilder, settings) {
- settings = settings || {};
- this.kernel = settings.kernel;
- this.canvas = settings.canvas;
- this.webGl = settings.webGl;
- this.fn = null;
- this.functionBuilder = functionBuilder;
- this.fnString = null;
- this.endianness = utils.systemEndianness();
- this.functionBuilder.polyfillStandardFunctions();
- }
-
- /**
- * @memberOf BaseRunner#
- * @function
- * @name textureToArray
- *
- * @desc Converts the provided Texture instance to a JavaScript Array
- *
- * @param {Object} texture - Texture Object
- *
- */
- textureToArray(texture) {
- const copy = this.createKernel(function(x) {
- return x[this.thread.z][this.thread.y][this.thread.x];
- });
-
- return copy(texture);
- }
-
- /**
- * @memberOf BaseRunner#
- * @function
- *
- * @name deleteTexture
- *
- * @desc Deletes the provided Texture instance
- *
- * @param {Object} texture - Texture Object
- */
- deleteTexture(texture) {
- this.webGl.deleteTexture(texture.texture);
- }
-
- /**
- * @memberOf BaseRunner#
- * @function
- * @name buildPromiseKernel
- *
- * @desc Get and returns the ASYNCHRONOUS executor, of a class and kernel
- * This returns a Promise object from an argument set.
- *
- * Note that there is no current implementation.
- *
- */
- buildPromiseKernel() {
- throw new Error('not yet implemented');
- }
-
- getMode() {
- throw new Error('"mode" not implemented on BaseRunner');
- }
-
- /**
- * @memberOf BaseRunner#
- * @function
- *
- * @name buildKernel
- *
- * @desc Get and returns the Synchronous executor, of a class and kernel
- * Which returns the result directly after passing the arguments.
- *
- */
- buildKernel(fn, settings) {
- settings = Object.assign({}, settings || {});
- const fnString = fn.toString();
- if (!settings.functionBuilder) {
- settings.functionBuilder = this.functionBuilder;
- }
-
- if (!settings.canvas) {
- settings.canvas = this.canvas;
- }
-
- if (!settings.webGl) {
- settings.webGl = this.webgl;
- }
-
- return kernelRunShortcut(new this.Kernel(fnString, settings));
- }
-};
\ No newline at end of file
diff --git a/src/backend/web-gl/fragment-shader.js b/src/backend/web-gl/fragment-shader.js
new file mode 100644
index 00000000..166e80e5
--- /dev/null
+++ b/src/backend/web-gl/fragment-shader.js
@@ -0,0 +1,496 @@
+// language=GLSL
+const fragmentShader = `__HEADER__;
+__FLOAT_TACTIC_DECLARATION__;
+__INT_TACTIC_DECLARATION__;
+__SAMPLER_2D_TACTIC_DECLARATION__;
+
+const int LOOP_MAX = __LOOP_MAX__;
+
+__PLUGINS__;
+__CONSTANTS__;
+
+varying vec2 vTexCoord;
+
+float acosh(float x) {
+ return log(x + sqrt(x * x - 1.0));
+}
+
+float sinh(float x) {
+ return (pow(${Math.E}, x) - pow(${Math.E}, -x)) / 2.0;
+}
+
+float asinh(float x) {
+ return log(x + sqrt(x * x + 1.0));
+}
+
+float atan2(float v1, float v2) {
+ if (v1 == 0.0 || v2 == 0.0) return 0.0;
+ return atan(v1 / v2);
+}
+
+float atanh(float x) {
+ x = (x + 1.0) / (x - 1.0);
+ if (x < 0.0) {
+ return 0.5 * log(-x);
+ }
+ return 0.5 * log(x);
+}
+
+float cbrt(float x) {
+ if (x >= 0.0) {
+ return pow(x, 1.0 / 3.0);
+ } else {
+ return -pow(x, 1.0 / 3.0);
+ }
+}
+
+float cosh(float x) {
+ return (pow(${Math.E}, x) + pow(${Math.E}, -x)) / 2.0;
+}
+
+float expm1(float x) {
+ return pow(${Math.E}, x) - 1.0;
+}
+
+float fround(highp float x) {
+ return x;
+}
+
+float imul(float v1, float v2) {
+ return float(int(v1) * int(v2));
+}
+
+float log10(float x) {
+ return log2(x) * (1.0 / log2(10.0));
+}
+
+float log1p(float x) {
+ return log(1.0 + x);
+}
+
+float _pow(float v1, float v2) {
+ if (v2 == 0.0) return 1.0;
+ return pow(v1, v2);
+}
+
+float tanh(float x) {
+ float e = exp(2.0 * x);
+ return (e - 1.0) / (e + 1.0);
+}
+
+float trunc(float x) {
+ if (x >= 0.0) {
+ return floor(x);
+ } else {
+ return ceil(x);
+ }
+}
+
+vec4 _round(vec4 x) {
+ return floor(x + 0.5);
+}
+
+float _round(float x) {
+ return floor(x + 0.5);
+}
+
+const int BIT_COUNT = 32;
+int modi(int x, int y) {
+ return x - y * (x / y);
+}
+
+int bitwiseOr(int a, int b) {
+ int result = 0;
+ int n = 1;
+
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {
+ result += n;
+ }
+ a = a / 2;
+ b = b / 2;
+ n = n * 2;
+ if(!(a > 0 || b > 0)) {
+ break;
+ }
+ }
+ return result;
+}
+int bitwiseXOR(int a, int b) {
+ int result = 0;
+ int n = 1;
+
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {
+ result += n;
+ }
+ a = a / 2;
+ b = b / 2;
+ n = n * 2;
+ if(!(a > 0 || b > 0)) {
+ break;
+ }
+ }
+ return result;
+}
+int bitwiseAnd(int a, int b) {
+ int result = 0;
+ int n = 1;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {
+ result += n;
+ }
+ a = a / 2;
+ b = b / 2;
+ n = n * 2;
+ if(!(a > 0 && b > 0)) {
+ break;
+ }
+ }
+ return result;
+}
+int bitwiseNot(int a) {
+ int result = 0;
+ int n = 1;
+
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (modi(a, 2) == 0) {
+ result += n;
+ }
+ a = a / 2;
+ n = n * 2;
+ }
+ return result;
+}
+int bitwiseZeroFillLeftShift(int n, int shift) {
+ int maxBytes = BIT_COUNT;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (maxBytes >= n) {
+ break;
+ }
+ maxBytes *= 2;
+ }
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= shift) {
+ break;
+ }
+ n *= 2;
+ }
+
+ int result = 0;
+ int byteVal = 1;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= maxBytes) break;
+ if (modi(n, 2) > 0) { result += byteVal; }
+ n = int(n / 2);
+ byteVal *= 2;
+ }
+ return result;
+}
+
+int bitwiseSignedRightShift(int num, int shifts) {
+ return int(floor(float(num) / pow(2.0, float(shifts))));
+}
+
+int bitwiseZeroFillRightShift(int n, int shift) {
+ int maxBytes = BIT_COUNT;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (maxBytes >= n) {
+ break;
+ }
+ maxBytes *= 2;
+ }
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= shift) {
+ break;
+ }
+ n /= 2;
+ }
+ int result = 0;
+ int byteVal = 1;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= maxBytes) break;
+ if (modi(n, 2) > 0) { result += byteVal; }
+ n = int(n / 2);
+ byteVal *= 2;
+ }
+ return result;
+}
+
+vec2 integerMod(vec2 x, float y) {
+ vec2 res = floor(mod(x, y));
+ return res * step(1.0 - floor(y), -res);
+}
+
+vec3 integerMod(vec3 x, float y) {
+ vec3 res = floor(mod(x, y));
+ return res * step(1.0 - floor(y), -res);
+}
+
+vec4 integerMod(vec4 x, vec4 y) {
+ vec4 res = floor(mod(x, y));
+ return res * step(1.0 - floor(y), -res);
+}
+
+float integerMod(float x, float y) {
+ float res = floor(mod(x, y));
+ return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);
+}
+
+int integerMod(int x, int y) {
+ return x - (y * int(x / y));
+}
+
+__DIVIDE_WITH_INTEGER_CHECK__;
+
+// Here be dragons!
+// DO NOT OPTIMIZE THIS CODE
+// YOU WILL BREAK SOMETHING ON SOMEBODY\'S MACHINE
+// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME
+const vec2 MAGIC_VEC = vec2(1.0, -256.0);
+const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);
+const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536
+float decode32(vec4 texel) {
+ __DECODE32_ENDIANNESS__;
+ texel *= 255.0;
+ vec2 gte128;
+ gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;
+ gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;
+ float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);
+ float res = exp2(_round(exponent));
+ texel.b = texel.b - 128.0 * gte128.x;
+ res = dot(texel, SCALE_FACTOR) * exp2(_round(exponent-23.0)) + res;
+ res *= gte128.y * -2.0 + 1.0;
+ return res;
+}
+
+float decode16(vec4 texel, int index) {
+ int channel = integerMod(index, 2);
+ if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0;
+ if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0;
+ return 0.0;
+}
+
+float decode8(vec4 texel, int index) {
+ int channel = integerMod(index, 4);
+ if (channel == 0) return texel.r * 255.0;
+ if (channel == 1) return texel.g * 255.0;
+ if (channel == 2) return texel.b * 255.0;
+ if (channel == 3) return texel.a * 255.0;
+ return 0.0;
+}
+
+vec4 legacyEncode32(float f) {
+ float F = abs(f);
+ float sign = f < 0.0 ? 1.0 : 0.0;
+ float exponent = floor(log2(F));
+ float mantissa = (exp2(-exponent) * F);
+ // exponent += floor(log2(mantissa));
+ vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;
+ texel.rg = integerMod(texel.rg, 256.0);
+ texel.b = integerMod(texel.b, 128.0);
+ texel.a = exponent*0.5 + 63.5;
+ texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;
+ texel = floor(texel);
+ texel *= 0.003921569; // 1/255
+ __ENCODE32_ENDIANNESS__;
+ return texel;
+}
+
+// https://github.com/gpujs/gpu.js/wiki/Encoder-details
+vec4 encode32(float value) {
+ if (value == 0.0) return vec4(0, 0, 0, 0);
+
+ float exponent;
+ float mantissa;
+ vec4 result;
+ float sgn;
+
+ sgn = step(0.0, -value);
+ value = abs(value);
+
+ exponent = floor(log2(value));
+
+ mantissa = value*pow(2.0, -exponent)-1.0;
+ exponent = exponent+127.0;
+ result = vec4(0,0,0,0);
+
+ result.a = floor(exponent/2.0);
+ exponent = exponent - result.a*2.0;
+ result.a = result.a + 128.0*sgn;
+
+ result.b = floor(mantissa * 128.0);
+ mantissa = mantissa - result.b / 128.0;
+ result.b = result.b + exponent*128.0;
+
+ result.g = floor(mantissa*32768.0);
+ mantissa = mantissa - result.g/32768.0;
+
+ result.r = floor(mantissa*8388608.0);
+ return result/255.0;
+}
+// Dragons end here
+
+int index;
+ivec3 threadId;
+
+ivec3 indexTo3D(int idx, ivec3 texDim) {
+ int z = int(idx / (texDim.x * texDim.y));
+ idx -= z * int(texDim.x * texDim.y);
+ int y = int(idx / texDim.x);
+ int x = int(integerMod(idx, texDim.x));
+ return ivec3(x, y, z);
+}
+
+float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture2D(tex, st / vec2(texSize));
+ return decode32(texel);
+}
+
+float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int w = texSize.x * 2;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y));
+ return decode16(texel, index);
+}
+
+float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int w = texSize.x * 4;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y));
+ return decode8(texel, index);
+}
+
+float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int channel = integerMod(index, 4);
+ index = index / 4;
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture2D(tex, st / vec2(texSize));
+ if (channel == 0) return texel.r;
+ if (channel == 1) return texel.g;
+ if (channel == 2) return texel.b;
+ if (channel == 3) return texel.a;
+ return 0.0;
+}
+
+vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ return texture2D(tex, st / vec2(texSize));
+}
+
+float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
+ return result[0];
+}
+
+vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
+ return vec2(result[0], result[1]);
+}
+
+vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + (texDim.x * (y + (texDim.y * z)));
+ int channel = integerMod(index, 2);
+ index = index / 2;
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture2D(tex, st / vec2(texSize));
+ if (channel == 0) return vec2(texel.r, texel.g);
+ if (channel == 1) return vec2(texel.b, texel.a);
+ return vec2(0.0, 0.0);
+}
+
+vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
+ return vec3(result[0], result[1], result[2]);
+}
+
+vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));
+ int vectorIndex = fieldIndex / 4;
+ int vectorOffset = fieldIndex - vectorIndex * 4;
+ int readY = vectorIndex / texSize.x;
+ int readX = vectorIndex - readY * texSize.x;
+ vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));
+
+ if (vectorOffset == 0) {
+ return tex1.xyz;
+ } else if (vectorOffset == 1) {
+ return tex1.yzw;
+ } else {
+ readX++;
+ if (readX >= texSize.x) {
+ readX = 0;
+ readY++;
+ }
+ vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize));
+ if (vectorOffset == 2) {
+ return vec3(tex1.z, tex1.w, tex2.x);
+ } else {
+ return vec3(tex1.w, tex2.x, tex2.y);
+ }
+ }
+}
+
+vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ return getImage2D(tex, texSize, texDim, z, y, x);
+}
+
+vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int channel = integerMod(index, 2);
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture2D(tex, st / vec2(texSize));
+ return vec4(texel.r, texel.g, texel.b, texel.a);
+}
+
+vec4 actualColor;
+void color(float r, float g, float b, float a) {
+ actualColor = vec4(r,g,b,a);
+}
+
+void color(float r, float g, float b) {
+ color(r,g,b,1.0);
+}
+
+void color(sampler2D image) {
+ actualColor = texture2D(image, vTexCoord);
+}
+
+float modulo(float number, float divisor) {
+ if (number < 0.0) {
+ number = abs(number);
+ if (divisor < 0.0) {
+ divisor = abs(divisor);
+ }
+ return -mod(number, divisor);
+ }
+ if (divisor < 0.0) {
+ divisor = abs(divisor);
+ }
+ return mod(number, divisor);
+}
+
+__INJECTED_NATIVE__;
+__MAIN_CONSTANTS__;
+__MAIN_ARGUMENTS__;
+__KERNEL__;
+
+void main(void) {
+ index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;
+ __MAIN_RESULT__;
+}`;
+
+module.exports = {
+ fragmentShader
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/function-builder.js b/src/backend/web-gl/function-builder.js
deleted file mode 100644
index 002d05c3..00000000
--- a/src/backend/web-gl/function-builder.js
+++ /dev/null
@@ -1,46 +0,0 @@
-'use strict';
-
-const FunctionBuilderBase = require('../function-builder-base');
-const WebGLFunctionNode = require('./function-node');
-
-/**
- * @class WebGLFunctionBuilder
- *
- * @extends FunctionBuilderBase
- *
- * @desc Builds webGl functions (shaders) from JavaScript function Strings
- *
- */
-module.exports = class WebGLFunctionBuilder extends FunctionBuilderBase {
- constructor() {
- super();
- this.Node = WebGLFunctionNode;
- }
-
- //---------------------------------------------------------
- //
- // Polyfill stuff
- //
- //---------------------------------------------------------
-
- // Round function used in polyfill
- static round(a) {
- return round(a);
- }
-
- /**
- * @memberOf FunctionBuilderBase#
- * @function
- * @name polyfillStandardFunctions
- *
- * @desc Polyfill in the missing Math functions (round)
- *
- */
- polyfillStandardFunctions() {
- this.addFunction('round', round);
- }
-};
-
-function round(a) {
- return Math.floor(a + 0.5);
-}
\ No newline at end of file
diff --git a/src/backend/web-gl/function-node.js b/src/backend/web-gl/function-node.js
index 6636eadf..0a0e844f 100644
--- a/src/backend/web-gl/function-node.js
+++ b/src/backend/web-gl/function-node.js
@@ -1,1144 +1,1606 @@
-'use strict';
-
-const FunctionNodeBase = require('../function-node-base');
-const utils = require('../../core/utils');
-// Closure capture for the ast function, prevent collision with existing AST functions
-// The prefixes to use
-const jsMathPrefix = 'Math.';
-const localPrefix = 'this.';
-const constantsPrefix = 'this.constants.';
-
-const DECODE32_ENCODE32 = /decode32\(\s+encode32\(/g;
-const ENCODE32_DECODE32 = /encode32\(\s+decode32\(/g;
-
-/**
- * @class WebGLFunctionNode
- *
- * @desc [INTERNAL] Takes in a function node, and does all the AST voodoo required to generate its respective webGL code.
- *
- * @extends FunctionNodeBase
- *
- * @param {functionNode} inNode - The function node object
- *
- * @returns the converted webGL function string
- *
- */
-module.exports = class WebGLFunctionNode extends FunctionNodeBase {
- generate() {
- if (this.debug) {
- console.log(this);
- }
- if (this.prototypeOnly) {
- return WebGLFunctionNode.astFunctionPrototype(this.getJsAST(), [], this).join('').trim();
- } else {
- this.functionStringArray = this.astGeneric(this.getJsAST(), [], this);
- }
- this.functionString = webGlRegexOptimize(
- this.functionStringArray.join('').trim()
- );
- return this.functionString;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astGeneric
- *
- * @desc Parses the abstract syntax tree for generically to its respective function
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {String} the prased openclgl string array
- */
- astGeneric(ast, retArr, funcParam) {
- if (ast === null) {
- throw this.astErrorOutput('NULL ast', ast, funcParam);
- } else {
- if (Array.isArray(ast)) {
- for (let i = 0; i < ast.length; i++) {
- this.astGeneric(ast[i], retArr, funcParam);
- }
- return retArr;
- }
-
- switch (ast.type) {
- case 'FunctionDeclaration':
- return this.astFunctionDeclaration(ast, retArr, funcParam);
- case 'FunctionExpression':
- return this.astFunctionExpression(ast, retArr, funcParam);
- case 'ReturnStatement':
- return this.astReturnStatement(ast, retArr, funcParam);
- case 'Literal':
- return this.astLiteral(ast, retArr, funcParam);
- case 'BinaryExpression':
- return this.astBinaryExpression(ast, retArr, funcParam);
- case 'Identifier':
- return this.astIdentifierExpression(ast, retArr, funcParam);
- case 'AssignmentExpression':
- return this.astAssignmentExpression(ast, retArr, funcParam);
- case 'ExpressionStatement':
- return this.astExpressionStatement(ast, retArr, funcParam);
- case 'EmptyStatement':
- return this.astEmptyStatement(ast, retArr, funcParam);
- case 'BlockStatement':
- return this.astBlockStatement(ast, retArr, funcParam);
- case 'IfStatement':
- return this.astIfStatement(ast, retArr, funcParam);
- case 'BreakStatement':
- return this.astBreakStatement(ast, retArr, funcParam);
- case 'ContinueStatement':
- return this.astContinueStatement(ast, retArr, funcParam);
- case 'ForStatement':
- return this.astForStatement(ast, retArr, funcParam);
- case 'WhileStatement':
- return this.astWhileStatement(ast, retArr, funcParam);
- case 'VariableDeclaration':
- return this.astVariableDeclaration(ast, retArr, funcParam);
- case 'VariableDeclarator':
- return this.astVariableDeclarator(ast, retArr, funcParam);
- case 'ThisExpression':
- return this.astThisExpression(ast, retArr, funcParam);
- case 'SequenceExpression':
- return this.astSequenceExpression(ast, retArr, funcParam);
- case 'UnaryExpression':
- return this.astUnaryExpression(ast, retArr, funcParam);
- case 'UpdateExpression':
- return this.astUpdateExpression(ast, retArr, funcParam);
- case 'LogicalExpression':
- return this.astLogicalExpression(ast, retArr, funcParam);
- case 'MemberExpression':
- return this.astMemberExpression(ast, retArr, funcParam);
- case 'CallExpression':
- return this.astCallExpression(ast, retArr, funcParam);
- case 'ArrayExpression':
- return this.astArrayExpression(ast, retArr, funcParam);
- case 'DebuggerStatement':
- return this.astDebuggerStatement(ast, retArr, funcParam);
- }
-
- throw this.astErrorOutput('Unknown ast type : ' + ast.type, ast, funcParam);
- }
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astFunctionDeclaration
- *
- * @desc Parses the abstract syntax tree for to its *named function declaration*
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astFunctionDeclaration(ast, retArr, funcParam) {
- if (this.addFunction) {
- this.addFunction(null, utils.getAstString(this.jsFunctionString, ast));
- }
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astFunctionPrototype
- * @static
- *
- * @desc Parses the abstract syntax tree for to its *named function prototype*
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- static astFunctionPrototype(ast, retArr, funcParam) {
- // Setup function return type and name
- if (funcParam.isRootKernel || funcParam.isSubKernel) {
- return retArr;
- }
-
- retArr.push(funcParam.returnType);
- retArr.push(' ');
- retArr.push(funcParam.functionName);
- retArr.push('(');
-
- // Arguments handling
- for (let i = 0; i < funcParam.paramNames.length; ++i) {
- if (i > 0) {
- retArr.push(', ');
- }
-
- retArr.push(funcParam.paramTypes[i]);
- retArr.push(' ');
- retArr.push('user_');
- retArr.push(funcParam.paramNames[i]);
- }
-
- retArr.push(');\n');
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astFunctionExpression
- *
- * @desc Parses the abstract syntax tree for to its *named function*
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astFunctionExpression(ast, retArr, funcParam) {
-
- // Setup function return type and name
- if (funcParam.isRootKernel) {
- retArr.push('void');
- funcParam.kernalAst = ast;
- } else {
- retArr.push(funcParam.returnType);
- }
- retArr.push(' ');
- retArr.push(funcParam.functionName);
- retArr.push('(');
-
- if (!funcParam.isRootKernel) {
- // Arguments handling
- for (let i = 0; i < funcParam.paramNames.length; ++i) {
- const paramName = funcParam.paramNames[i];
-
- if (i > 0) {
- retArr.push(', ');
- }
- const type = funcParam.getParamType(paramName);
- switch (type) {
- case 'Texture':
- case 'Input':
- case 'Array':
- retArr.push('sampler2D');
- break;
- default:
- retArr.push('float');
- }
-
- retArr.push(' ');
- retArr.push('user_');
- retArr.push(paramName);
- }
- }
-
- // Function opening
- retArr.push(') {\n');
-
- // Body statement iteration
- for (let i = 0; i < ast.body.body.length; ++i) {
- this.astGeneric(ast.body.body[i], retArr, funcParam);
- retArr.push('\n');
- }
-
- // Function closing
- retArr.push('}\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astReturnStatement
- *
- * @desc Parses the abstract syntax tree for to *return* statement
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Object} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astReturnStatement(ast, retArr, funcParam) {
- if (funcParam.isRootKernel) {
- retArr.push('kernelResult = ');
- this.astGeneric(ast.argument, retArr, funcParam);
- retArr.push(';');
- retArr.push('return;');
- } else if (funcParam.isSubKernel) {
- retArr.push(`${ funcParam.functionName }Result = `);
- this.astGeneric(ast.argument, retArr, funcParam);
- retArr.push(';');
- retArr.push(`return ${ funcParam.functionName }Result;`);
- } else {
- retArr.push('return ');
- this.astGeneric(ast.argument, retArr, funcParam);
- retArr.push(';');
- }
-
- //throw this.astErrorOutput(
- // 'Non main function return, is not supported : '+funcParam.currentFunctionNamespace,
- // ast, funcParam
- //);
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astLiteral
- *
- * @desc Parses the abstract syntax tree for *literal value*
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astLiteral(ast, retArr, funcParam) {
-
- // Reject non numeric literals
- if (isNaN(ast.value)) {
- throw this.astErrorOutput(
- 'Non-numeric literal not supported : ' + ast.value,
- ast, funcParam
- );
- }
-
- // Push the literal value as a float/int
- retArr.push(ast.value);
-
- // If it was an int, node made a float
- if (Number.isInteger(ast.value)) {
- retArr.push('.0');
- }
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astBinaryExpression
- *
- * @desc Parses the abstract syntax tree for *binary* expression
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astBinaryExpression(ast, retArr, funcParam) {
- retArr.push('(');
-
- if (ast.operator === '%') {
- retArr.push('mod(');
- this.astGeneric(ast.left, retArr, funcParam);
- retArr.push(',');
- this.astGeneric(ast.right, retArr, funcParam);
- retArr.push(')');
- } else if (ast.operator === '===') {
- this.astGeneric(ast.left, retArr, funcParam);
- retArr.push('==');
- this.astGeneric(ast.right, retArr, funcParam);
- } else if (ast.operator === '!==') {
- this.astGeneric(ast.left, retArr, funcParam);
- retArr.push('!=');
- this.astGeneric(ast.right, retArr, funcParam);
- } else {
- this.astGeneric(ast.left, retArr, funcParam);
- retArr.push(ast.operator);
- this.astGeneric(ast.right, retArr, funcParam);
- }
-
- retArr.push(')');
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astIdentifierExpression
- *
- * @desc Parses the abstract syntax tree for *identifier* expression
- *
- * @param {Object} idtNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astIdentifierExpression(idtNode, retArr, funcParam) {
- if (idtNode.type !== 'Identifier') {
- throw this.astErrorOutput(
- 'IdentifierExpression - not an Identifier',
- ast, funcParam
- );
- }
-
- switch (idtNode.name) {
- case 'gpu_threadX':
- retArr.push('threadId.x');
- break;
- case 'gpu_threadY':
- retArr.push('threadId.y');
- break;
- case 'gpu_threadZ':
- retArr.push('threadId.z');
- break;
- case 'gpu_outputX':
- retArr.push('uOutputDim.x');
- break;
- case 'gpu_outputY':
- retArr.push('uOutputDim.y');
- break;
- case 'gpu_outputZ':
- retArr.push('uOutputDim.z');
- break;
- default:
- if (this.constants && this.constants.hasOwnProperty(idtNode.name)) {
- retArr.push('constants_' + idtNode.name);
- } else {
- const userParamName = funcParam.getUserParamName(idtNode.name);
- if (userParamName !== null) {
- retArr.push('user_' + userParamName);
- } else {
- retArr.push('user_' + idtNode.name);
- }
- }
- }
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astForStatement
- *
- * @desc Parses the abstract syntax tree forfor *for-loop* expression
- *
- * @param {Object} forNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {String} the prased openclgl string
- */
- astForStatement(forNode, retArr, funcParam) {
- if (forNode.type !== 'ForStatement') {
- throw this.astErrorOutput(
- 'Invalid for statment',
- ast, funcParam
- );
- }
-
- if (forNode.test && forNode.test.type === 'BinaryExpression') {
- if (forNode.test.right.type === 'Identifier' &&
- forNode.test.operator === '<' &&
- this.isIdentifierConstant(forNode.test.right.name) === false) {
-
- if (!this.loopMaxIterations) {
- console.warn('Warning: loopMaxIterations is not set! Using default of 1000 which may result in unintended behavior.');
- console.warn('Set loopMaxIterations or use a for loop of fixed length to silence this message.');
- }
-
- retArr.push('for (');
- this.astGeneric(forNode.init, retArr, funcParam);
- this.astGeneric(forNode.test.left, retArr, funcParam);
- retArr.push(forNode.test.operator);
- retArr.push('LOOP_MAX');
- retArr.push(';');
- this.astGeneric(forNode.update, retArr, funcParam);
- retArr.push(')');
-
- retArr.push('{\n');
- retArr.push('if (');
- this.astGeneric(forNode.test.left, retArr, funcParam);
- retArr.push(forNode.test.operator);
- this.astGeneric(forNode.test.right, retArr, funcParam);
- retArr.push(') {\n');
- if (forNode.body.type === 'BlockStatement') {
- for (let i = 0; i < forNode.body.body.length; i++) {
- this.astGeneric(forNode.body.body[i], retArr, funcParam);
- }
- } else {
- this.astGeneric(forNode.body, retArr, funcParam);
- }
- retArr.push('} else {\n');
- retArr.push('break;\n');
- retArr.push('}\n');
- retArr.push('}\n');
-
- return retArr;
- } else {
- const declarations = JSON.parse(JSON.stringify(forNode.init.declarations));
- const updateArgument = forNode.update.argument;
- if (!Array.isArray(declarations) || declarations.length < 1) {
- console.log(this.jsFunctionString);
- throw new Error('Error: Incompatible for loop declaration');
- }
-
- if (declarations.length > 1) {
- let initArgument = null;
- for (let i = 0; i < declarations.length; i++) {
- const declaration = declarations[i];
- if (declaration.id.name === updateArgument.name) {
- initArgument = declaration;
- declarations.splice(i, 1);
- } else {
- retArr.push('float ');
- this.astGeneric(declaration, retArr, funcParam);
- retArr.push(';');
- }
- }
-
- retArr.push('for (float ');
- this.astGeneric(initArgument, retArr, funcParam);
- retArr.push(';');
- } else {
- retArr.push('for (');
- this.astGeneric(forNode.init, retArr, funcParam);
- }
-
- this.astGeneric(forNode.test, retArr, funcParam);
- retArr.push(';');
- this.astGeneric(forNode.update, retArr, funcParam);
- retArr.push(')');
- this.astGeneric(forNode.body, retArr, funcParam);
- return retArr;
- }
- }
-
- throw this.astErrorOutput(
- 'Invalid for statement',
- ast, funcParam
- );
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astWhileStatement
- *
- * @desc Parses the abstract syntax tree for *while* loop
- *
- *
- * @param {Object} whileNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {String} the parsed openclgl string
- */
- astWhileStatement(whileNode, retArr, funcParam) {
- if (whileNode.type !== 'WhileStatement') {
- throw this.astErrorOutput(
- 'Invalid while statment',
- ast, funcParam
- );
- }
-
- retArr.push('for (float i = 0.0; i < LOOP_MAX; i++) {');
- retArr.push('if (');
- this.astGeneric(whileNode.test, retArr, funcParam);
- retArr.push(') {\n');
- this.astGeneric(whileNode.body, retArr, funcParam);
- retArr.push('} else {\n');
- retArr.push('break;\n');
- retArr.push('}\n');
- retArr.push('}\n');
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astAssignmentExpression
- *
- * @desc Parses the abstract syntax tree for *Assignment* Expression
- *
- * @param {Object} assNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astAssignmentExpression(assNode, retArr, funcParam) {
- if (assNode.operator === '%=') {
- this.astGeneric(assNode.left, retArr, funcParam);
- retArr.push('=');
- retArr.push('mod(');
- this.astGeneric(assNode.left, retArr, funcParam);
- retArr.push(',');
- this.astGeneric(assNode.right, retArr, funcParam);
- retArr.push(')');
- } else {
- this.astGeneric(assNode.left, retArr, funcParam);
- retArr.push(assNode.operator);
- this.astGeneric(assNode.right, retArr, funcParam);
- return retArr;
- }
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astEmptyStatement
- *
- * @desc Parses the abstract syntax tree for an *Empty* Statement
- *
- * @param {Object} eNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astEmptyStatement(eNode, retArr, funcParam) {
- //retArr.push(';\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astBlockStatement
- *
- * @desc Parses the abstract syntax tree for *Block* statement
- *
- * @param {Object} bnode - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astBlockStatement(bNode, retArr, funcParam) {
- retArr.push('{\n');
- for (let i = 0; i < bNode.body.length; i++) {
- this.astGeneric(bNode.body[i], retArr, funcParam);
- }
- retArr.push('}\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astExpressionStatement
- *
- * @desc Parses the abstract syntax tree for *generic expression* statement
- *
- * @param {Object} esNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astExpressionStatement(esNode, retArr, funcParam) {
- this.astGeneric(esNode.expression, retArr, funcParam);
- retArr.push(';\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astVariableDeclaration
- *
- * @desc Parses the abstract syntax tree for *Variable Declaration*
- *
- * @param {Object} vardecNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astVariableDeclaration(vardecNode, retArr, funcParam) {
- retArr.push('float ');
- for (let i = 0; i < vardecNode.declarations.length; i++) {
- if (i > 0) {
- retArr.push(',');
- }
- this.astGeneric(vardecNode.declarations[i], retArr, funcParam);
- }
- retArr.push(';');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astVariableDeclarator
- *
- * @desc Parses the abstract syntax tree for *Variable Declarator*
- *
- * @param {Object} ivardecNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astVariableDeclarator(ivardecNode, retArr, funcParam) {
- this.astGeneric(ivardecNode.id, retArr, funcParam);
- if (ivardecNode.init !== null) {
- retArr.push('=');
- this.astGeneric(ivardecNode.init, retArr, funcParam);
- }
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astIfStatement
- *
- * @desc Parses the abstract syntax tree for *If* Statement
- *
- * @param {Object} ifNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astIfStatement(ifNode, retArr, funcParam) {
- retArr.push('if (');
- this.astGeneric(ifNode.test, retArr, funcParam);
- retArr.push(')');
- if (ifNode.consequent.type === 'BlockStatement') {
- this.astGeneric(ifNode.consequent, retArr, funcParam);
- } else {
- retArr.push(' {\n');
- this.astGeneric(ifNode.consequent, retArr, funcParam);
- retArr.push('\n}\n');
- }
-
- if (ifNode.alternate) {
- retArr.push('else ');
- if (ifNode.alternate.type === 'BlockStatement') {
- this.astGeneric(ifNode.alternate, retArr, funcParam);
- } else {
- retArr.push(' {\n');
- this.astGeneric(ifNode.alternate, retArr, funcParam);
- retArr.push('\n}\n');
- }
- }
- return retArr;
-
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astBreakStatement
- *
- * @desc Parses the abstract syntax tree for *Break* Statement
- *
- * @param {Object} brNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astBreakStatement(brNode, retArr, funcParam) {
- retArr.push('break;\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astContinueStatement
- *
- * @desc Parses the abstract syntax tree for *Continue* Statement
- *
- * @param {Object} crNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astContinueStatement(crNode, retArr, funcParam) {
- retArr.push('continue;\n');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astLogicalExpression
- *
- * @desc Parses the abstract syntax tree for *Logical* Expression
- *
- * @param {Object} logNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astLogicalExpression(logNode, retArr, funcParam) {
- retArr.push('(');
- this.astGeneric(logNode.left, retArr, funcParam);
- retArr.push(logNode.operator);
- this.astGeneric(logNode.right, retArr, funcParam);
- retArr.push(')');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astUpdateExpression
- *
- * @desc Parses the abstract syntax tree for *Update* Expression
- *
- * @param {Object} uNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astUpdateExpression(uNode, retArr, funcParam) {
- if (uNode.prefix) {
- retArr.push(uNode.operator);
- this.astGeneric(uNode.argument, retArr, funcParam);
- } else {
- this.astGeneric(uNode.argument, retArr, funcParam);
- retArr.push(uNode.operator);
- }
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astUnaryExpression
- *
- * @desc Parses the abstract syntax tree for *Unary* Expression
- *
- * @param {Object} uNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astUnaryExpression(uNode, retArr, funcParam) {
- if (uNode.prefix) {
- retArr.push(uNode.operator);
- this.astGeneric(uNode.argument, retArr, funcParam);
- } else {
- this.astGeneric(uNode.argument, retArr, funcParam);
- retArr.push(uNode.operator);
- }
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astThisExpression
- *
- * @desc Parses the abstract syntax tree for *This* expression
- *
- * @param {Object} tNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astThisExpression(tNode, retArr, funcParam) {
- retArr.push('this');
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astMemberExpression
- *
- * @desc Parses the abstract syntax tree for *Member* Expression
- *
- * @param {Object} mNode - An ast Node
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astMemberExpression(mNode, retArr, funcParam) {
- if (mNode.computed) {
- if (mNode.object.type === 'Identifier') {
- // Working logger
- const reqName = mNode.object.name;
- const funcName = funcParam.functionName || 'kernel';
- let assumeNotTexture = false;
-
- // Possibly an array request - handle it as such
- if (funcParam.paramNames) {
- const idx = funcParam.paramNames.indexOf(reqName);
- if (idx >= 0 && funcParam.paramTypes[idx] === 'float') {
- assumeNotTexture = true;
- }
- }
-
- if (assumeNotTexture) {
- // Get from array
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push('[int(');
- this.astGeneric(mNode.property, retArr, funcParam);
- retArr.push(')]');
- } else {
- // Get from texture
- // This normally refers to the global read only input vars
- retArr.push('get(');
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push(', vec2(');
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push('Size[0],');
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push('Size[1]), vec3(');
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push('Dim[0],');
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push('Dim[1],');
- this.astGeneric(mNode.object, retArr, funcParam);
- retArr.push('Dim[2]');
- retArr.push('), ');
- this.astGeneric(mNode.property, retArr, funcParam);
- retArr.push(')');
- }
- } else {
- this.astGeneric(mNode.object, retArr, funcParam);
- const last = retArr.pop();
- retArr.push(',');
- this.astGeneric(mNode.property, retArr, funcParam);
- retArr.push(last);
- }
- } else {
-
- // Unroll the member expression
- let unrolled = this.astMemberExpressionUnroll(mNode);
- let unrolled_lc = unrolled.toLowerCase();
-
- // Its a constant, remove this.constants.
- if (unrolled.indexOf(constantsPrefix) === 0) {
- unrolled = 'constants_' + unrolled.slice(constantsPrefix.length);
- }
-
- switch (unrolled_lc) {
- case 'this.thread.x':
- retArr.push('threadId.x');
- break;
- case 'this.thread.y':
- retArr.push('threadId.y');
- break;
- case 'this.thread.z':
- retArr.push('threadId.z');
- break;
- case 'this.output.x':
- retArr.push(this.output[0] + '.0');
- break;
- case 'this.output.y':
- retArr.push(this.output[1] + '.0');
- break;
- case 'this.output.z':
- retArr.push(this.output[2] + '.0');
- break;
- default:
- retArr.push(unrolled);
- }
- }
- return retArr;
- }
-
- astSequenceExpression(sNode, retArr, funcParam) {
- for (let i = 0; i < sNode.expressions.length; i++) {
- if (i > 0) {
- retArr.push(',');
- }
- this.astGeneric(sNode.expressions, retArr, funcParam);
- }
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astCallExpression
- *
- * @desc Parses the abstract syntax tree for *call* expression
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astCallExpression(ast, retArr, funcParam) {
- if (ast.callee) {
- // Get the full function call, unrolled
- let funcName = this.astMemberExpressionUnroll(ast.callee);
-
- // Its a math operator, remove the prefix
- if (funcName.indexOf(jsMathPrefix) === 0) {
- funcName = funcName.slice(jsMathPrefix.length);
- }
-
- // Its a local function, remove this
- if (funcName.indexOf(localPrefix) === 0) {
- funcName = funcName.slice(localPrefix.length);
- }
-
- // Register the function into the called registry
- if (funcParam.calledFunctions.indexOf(funcName) < 0) {
- funcParam.calledFunctions.push(funcName);
- }
- if (!funcParam.hasOwnProperty('funcName')) {
- funcParam.calledFunctionsArguments[funcName] = [];
- }
-
- const functionArguments = [];
- funcParam.calledFunctionsArguments[funcName].push(functionArguments);
-
- // Call the function
- retArr.push(funcName);
-
- // Open arguments space
- retArr.push('(');
-
- // Add the vars
- for (let i = 0; i < ast.arguments.length; ++i) {
- const argument = ast.arguments[i];
- if (i > 0) {
- retArr.push(', ');
- }
- this.astGeneric(argument, retArr, funcParam);
- if (argument.type === 'Identifier') {
- const paramIndex = funcParam.paramNames.indexOf(argument.name);
- if (paramIndex === -1) {
- functionArguments.push(null);
- } else {
- functionArguments.push({
- name: argument.name,
- type: funcParam.paramTypes[paramIndex]
- });
- }
- } else {
- functionArguments.push(null);
- }
- }
-
- // Close arguments space
- retArr.push(')');
-
- return retArr;
- }
-
- // Failure, unknown expression
- throw this.astErrorOutput(
- 'Unknown CallExpression',
- ast, funcParam
- );
-
- return retArr;
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name astArrayExpression
- *
- * @desc Parses the abstract syntax tree for *Array* Expression
- *
- * @param {Object} ast - the AST object to parse
- * @param {Array} retArr - return array string
- * @param {Function} funcParam - FunctionNode, that tracks compilation state
- *
- * @returns {Array} the append retArr
- */
- astArrayExpression(arrNode, retArr, funcParam) {
- const arrLen = arrNode.elements.length;
-
- retArr.push('float[' + arrLen + '](');
- for (let i = 0; i < arrLen; ++i) {
- if (i > 0) {
- retArr.push(', ');
- }
- const subNode = arrNode.elements[i];
- this.astGeneric(subNode, retArr, funcParam)
- }
- retArr.push(')');
-
- return retArr;
-
- // // Failure, unknown expression
- // throw this.astErrorOutput(
- // 'Unknown ArrayExpression',
- // arrNode, funcParam
- //);
- }
-
- /**
- * @memberOf WebGLFunctionNode#
- * @function
- * @name getFunctionPrototypeString
- *
- * @desc Returns the converted webgl shader function equivalent of the JS function
- *
- * @returns {String} webgl function string, result is cached under this.getFunctionPrototypeString
- *
- */
- getFunctionPrototypeString() {
- if (this.webGlFunctionPrototypeString) {
- return this.webGlFunctionPrototypeString;
- }
- return this.webGlFunctionPrototypeString = this.generate();
- }
-
- build() {
- return this.getFunctionPrototypeString().length > 0;
- }
-};
+const { utils } = require('../../utils');
+const { FunctionNode } = require('../function-node');
-function isIdentifierKernelParam(paramName, ast, funcParam) {
- return funcParam.paramNames.indexOf(paramName) !== -1;
+/**
+ * @desc [INTERNAL] Takes in a function node, and does all the AST voodoo required to toString its respective WebGL code
+ */
+class WebGLFunctionNode extends FunctionNode {
+ constructor(source, settings) {
+ super(source, settings);
+ if (settings && settings.hasOwnProperty('fixIntegerDivisionAccuracy')) {
+ this.fixIntegerDivisionAccuracy = settings.fixIntegerDivisionAccuracy;
+ }
+ }
+
+ 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);
+ // minification handling if void
+ 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;
+ }
+ retArr.push('(');
+ this.astGeneric(ast.test, retArr);
+ retArr.push('?');
+ this.astGeneric(ast.consequent, retArr);
+ retArr.push(':');
+ this.astGeneric(ast.alternate, retArr);
+ retArr.push(')');
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for to its *named function*
+ * @param {Object} ast - the AST object to parse
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astFunction(ast, retArr) {
+ // Setup function return type and name
+ if (this.isRootKernel) {
+ retArr.push('void');
+ } else {
+ // looking up return type, this is a little expensive, and can be avoided if returnType is set
+ 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;
+ if (!returnType) {
+ retArr.push('void');
+ } else {
+ const type = typeMap[returnType];
+ if (!type) {
+ throw new Error(`unknown type ${returnType}`);
+ }
+ retArr.push(type);
+ }
+ }
+ retArr.push(' ');
+ retArr.push(this.name);
+ retArr.push('(');
+
+ if (!this.isRootKernel) {
+ // Arguments handling
+ 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)];
+ // The type is too loose ended, here we decide to solidify a type, lets go with float
+ if (!argumentType) {
+ throw this.astErrorOutput(`Unknown argument ${argumentName} type`, ast);
+ }
+ if (argumentType === 'LiteralInteger') {
+ this.argumentTypes[i] = argumentType = 'Number';
+ }
+ const type = typeMap[argumentType];
+ if (!type) {
+ throw this.astErrorOutput('Unexpected expression', ast);
+ }
+ const name = utils.sanitizeName(argumentName);
+ if (type === 'sampler2D' || type === 'sampler2DArray') {
+ // mash needed arguments together, since now we have end to end inference
+ retArr.push(`${type} user_${name},ivec2 user_${name}Size,ivec3 user_${name}Dim`);
+ } else {
+ retArr.push(`${type} user_${name}`);
+ }
+ }
+ }
+
+ // Function opening
+ retArr.push(') {\n');
+
+ // Body statement iteration
+ for (let i = 0; i < ast.body.body.length; ++i) {
+ this.astGeneric(ast.body.body[i], retArr);
+ retArr.push('\n');
+ }
+
+ // Function closing
+ retArr.push('}\n');
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for to *return* statement
+ * @param {Object} ast - the AST object to parse
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append 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('float(');
+ this.astGeneric(ast.argument, result);
+ result.push(')');
+ break;
+ case 'LiteralInteger':
+ this.castLiteralToFloat(ast.argument, result);
+
+ // Running astGeneric forces the LiteralInteger to pick a type, and here, if we are returning a float, yet
+ // the LiteralInteger has picked to be an integer because of constraints on it we cast it to float.
+ if (this.getType(ast) === 'Integer') {
+ result.unshift('float(');
+ 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 'Array(4)':
+ case 'Array(3)':
+ case 'Array(2)':
+ case 'Matrix(2)':
+ case 'Matrix(3)':
+ case 'Matrix(4)':
+ case 'Input':
+ this.astGeneric(ast.argument, result);
+ break;
+ default:
+ throw this.astErrorOutput(`unhandled return type ${this.returnType}`, ast);
+ }
+
+ if (this.isRootKernel) {
+ retArr.push(`kernelResult = ${ result.join('') };`);
+ retArr.push('return;');
+ } else if (this.isSubKernel) {
+ retArr.push(`subKernelResult_${ this.name } = ${ result.join('') };`);
+ retArr.push(`return subKernelResult_${ this.name };`);
+ } else {
+ retArr.push(`return ${ result.join('') };`);
+ }
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *literal value*
+ *
+ * @param {Object} ast - the AST object to parse
+ * @param {Array} retArr - return array string
+ *
+ * @returns {Array} the append retArr
+ */
+ astLiteral(ast, retArr) {
+ // Reject non numeric literals
+ 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(`${ast.value}`);
+ } else if (this.isState('casting-to-float') || this.isState('building-float')) {
+ this.literalTypes[key] = 'Number';
+ retArr.push(`${ast.value}.0`);
+ } else {
+ this.literalTypes[key] = 'Number';
+ retArr.push(`${ast.value}.0`);
+ }
+ } else if (this.isState('casting-to-integer') || this.isState('building-integer')) {
+ this.literalTypes[key] = 'Integer';
+ retArr.push(Math.round(ast.value));
+ } else {
+ this.literalTypes[key] = 'Number';
+ retArr.push(`${ast.value}`);
+ }
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *binary* expression
+ * @param {Object} ast - the AST object to parse
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astBinaryExpression(ast, retArr) {
+ if (this.checkAndUpconvertOperator(ast, retArr)) {
+ return retArr;
+ }
+
+ if (this.fixIntegerDivisionAccuracy && ast.operator === '/') {
+ retArr.push('divWithIntCheck(');
+ 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(', ');
+ 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';
+ if (!leftType || !rightType) {
+ throw this.astErrorOutput(`Unhandled binary expression`, ast);
+ }
+ 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 right value is actually a float, don't loose that information, cast left to right rather than the usual right to left
+ 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('int(');
+ 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.astGeneric(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) {
+ const bitwiseResult = this.checkAndUpconvertBitwiseOperators(ast, retArr);
+ if (bitwiseResult) {
+ return bitwiseResult;
+ }
+ const upconvertableOperators = {
+ '%': this.fixIntegerDivisionAccuracy ? 'integerCorrectionModulo' : 'modulo',
+ '**': 'pow',
+ };
+ const foundOperator = upconvertableOperators[ast.operator];
+ if (!foundOperator) return null;
+ retArr.push(foundOperator);
+ 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 upconvertableOperators = {
+ '&': 'bitwiseAnd',
+ '|': 'bitwiseOr',
+ '^': 'bitwiseXOR',
+ '<<': 'bitwiseZeroFillLeftShift',
+ '>>': 'bitwiseSignedRightShift',
+ '>>>': 'bitwiseZeroFillRightShift',
+ };
+ const foundOperator = upconvertableOperators[ast.operator];
+ if (!foundOperator) return null;
+ retArr.push(foundOperator);
+ retArr.push('(');
+ const leftType = this.getType(ast.left);
+ switch (leftType) {
+ case 'Number':
+ case 'Float':
+ this.castValueToInteger(ast.left, retArr);
+ break;
+ case 'LiteralInteger':
+ this.castLiteralToInteger(ast.left, retArr);
+ break;
+ default:
+ this.astGeneric(ast.left, retArr);
+ }
+ retArr.push(',');
+ const rightType = this.getType(ast.right);
+ switch (rightType) {
+ case 'Number':
+ case 'Float':
+ this.castValueToInteger(ast.right, retArr);
+ break;
+ case 'LiteralInteger':
+ this.castLiteralToInteger(ast.right, retArr);
+ break;
+ default:
+ this.astGeneric(ast.right, retArr);
+ }
+ retArr.push(')');
+ return retArr;
+ }
+
+ checkAndUpconvertBitwiseUnary(ast, retArr) {
+ const upconvertableOperators = {
+ '~': 'bitwiseNot',
+ };
+ const foundOperator = upconvertableOperators[ast.operator];
+ if (!foundOperator) return null;
+ retArr.push(foundOperator);
+ 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;
+ }
+
+ /**
+ *
+ * @param {Object} ast
+ * @param {Array} retArr
+ * @return {String[]}
+ */
+ castLiteralToInteger(ast, retArr) {
+ this.pushState('casting-to-integer');
+ this.astGeneric(ast, retArr);
+ this.popState('casting-to-integer');
+ return retArr;
+ }
+
+ /**
+ *
+ * @param {Object} ast
+ * @param {Array} retArr
+ * @return {String[]}
+ */
+ castLiteralToFloat(ast, retArr) {
+ this.pushState('casting-to-float');
+ this.astGeneric(ast, retArr);
+ this.popState('casting-to-float');
+ return retArr;
+ }
+
+ /**
+ *
+ * @param {Object} ast
+ * @param {Array} retArr
+ * @return {String[]}
+ */
+ castValueToInteger(ast, retArr) {
+ this.pushState('casting-to-integer');
+ retArr.push('int(');
+ this.astGeneric(ast, retArr);
+ retArr.push(')');
+ this.popState('casting-to-integer');
+ return retArr;
+ }
+
+ /**
+ *
+ * @param {Object} ast
+ * @param {Array} retArr
+ * @return {String[]}
+ */
+ castValueToFloat(ast, retArr) {
+ this.pushState('casting-to-float');
+ retArr.push('float(');
+ this.astGeneric(ast, retArr);
+ retArr.push(')');
+ this.popState('casting-to-float');
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *identifier* expression
+ * @param {Object} idtNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append 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') {
+ // https://stackoverflow.com/a/47543127/1324039
+ retArr.push('3.402823466e+38');
+ } else if (type === 'Boolean') {
+ if (this.argumentNames.indexOf(name) > -1) {
+ retArr.push(`bool(user_${name})`);
+ } else {
+ retArr.push(`user_${name}`);
+ }
+ } else {
+ retArr.push(`user_${name}`);
+ }
+
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *for-loop* expression
+ * @param {Object} forNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the parsed webgl string
+ */
+ 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) {
+ this.astGeneric(forNode.update, updateArr);
+ } else {
+ isSafe = false;
+ }
+
+ if (forNode.body) {
+ this.pushState('loop-body');
+ this.astGeneric(forNode.body, bodyArr);
+ this.popState('loop-body');
+ }
+
+ // have all parts, now make them safe
+ 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 (int ${iVariableName}=0;${iVariableName} 0) {
+ retArr.push(`if (!${testArr.join('')}) break;\n`);
+ }
+ retArr.push(bodyArr.join(''));
+ retArr.push(`\n${updateArr.join('')};`);
+ retArr.push('}\n');
+ }
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *while* loop
+ * @param {Object} whileNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the parsed webgl string
+ */
+ astWhileStatement(whileNode, retArr) {
+ if (whileNode.type !== 'WhileStatement') {
+ throw this.astErrorOutput('Invalid while statement', whileNode);
+ }
+
+ const iVariableName = this.getInternalVariableName('safeI');
+ retArr.push(`for (int ${iVariableName}=0;${iVariableName} 0) {
+ declarationSets.push(declarationSet.join(','));
+ }
+
+ result.push(declarationSets.join(';'));
+
+ retArr.push(result.join(''));
+ retArr.push(';');
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *If* Statement
+ * @param {Object} ifNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astIfStatement(ifNode, retArr) {
+ retArr.push('if (');
+ this.astGeneric(ifNode.test, retArr);
+ retArr.push(')');
+ if (ifNode.consequent.type === 'BlockStatement') {
+ this.astGeneric(ifNode.consequent, retArr);
+ } else {
+ retArr.push(' {\n');
+ this.astGeneric(ifNode.consequent, retArr);
+ retArr.push('\n}\n');
+ }
+
+ if (ifNode.alternate) {
+ retArr.push('else ');
+ if (ifNode.alternate.type === 'BlockStatement' || ifNode.alternate.type === 'IfStatement') {
+ this.astGeneric(ifNode.alternate, retArr);
+ } else {
+ retArr.push(' {\n');
+ this.astGeneric(ifNode.alternate, retArr);
+ retArr.push('\n}\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(`float ${varName} = `);
+ this.astGeneric(discriminant, retArr);
+ retArr.push(';\n');
+ break;
+ case 'Integer':
+ retArr.push(`int ${varName} = `);
+ this.astGeneric(discriminant, retArr);
+ retArr.push(';\n');
+ break;
+ }
+ // switch with just a default:
+ if (cases.length === 1 && !cases[0].test) {
+ this.astGeneric(cases[0].consequent, retArr);
+ return retArr;
+ }
+
+ // regular switches:
+ let fallingThrough = false;
+ let defaultResult = [];
+ let movingDefaultToEnd = false;
+ let pastFirstIf = false;
+ for (let i = 0; i < cases.length; i++) {
+ // default
+ if (!cases[i].test) {
+ if (cases.length > i + 1) {
+ movingDefaultToEnd = true;
+ this.astGeneric(cases[i].consequent, defaultResult);
+ continue;
+ } else {
+ retArr.push(' else {\n');
+ }
+ } else {
+ // all others
+ 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 if (type === 'Float') {
+ 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;
+ }
+ } else {
+ throw new Error('unhanlded');
+ }
+ if (!cases[i].consequent || cases[i].consequent.length === 0) {
+ fallingThrough = true;
+ retArr.push(' || ');
+ continue;
+ }
+ retArr.push(`) {\n`);
+ }
+ this.astGeneric(cases[i].consequent, retArr);
+ retArr.push('\n}');
+ }
+ if (movingDefaultToEnd) {
+ retArr.push(' else {');
+ retArr.push(defaultResult.join(''));
+ retArr.push('}');
+ }
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *This* expression
+ * @param {Object} tNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astThisExpression(tNode, retArr) {
+ retArr.push('this');
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *Member* Expression
+ * @param {Object} mNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ 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);
+ }
+ retArr.push(`threadId.${name}`);
+ return retArr;
+ case 'this.output.value':
+ if (this.dynamicOutput) {
+ switch (name) {
+ case 'x':
+ if (this.isState('casting-to-float')) {
+ retArr.push('float(uOutputDim.x)');
+ } else {
+ retArr.push('uOutputDim.x');
+ }
+ break;
+ case 'y':
+ if (this.isState('casting-to-float')) {
+ retArr.push('float(uOutputDim.y)');
+ } else {
+ retArr.push('uOutputDim.y');
+ }
+ break;
+ case 'z':
+ if (this.isState('casting-to-float')) {
+ retArr.push('float(uOutputDim.z)');
+ } else {
+ retArr.push('uOutputDim.z');
+ }
+ break;
+ default:
+ throw this.astErrorOutput('Unexpected expression', mNode);
+ }
+ } else {
+ switch (name) {
+ case 'x':
+ if (this.isState('casting-to-integer')) {
+ retArr.push(this.output[0]);
+ } else {
+ retArr.push(this.output[0], '.0');
+ }
+ break;
+ case 'y':
+ if (this.isState('casting-to-integer')) {
+ retArr.push(this.output[1]);
+ } else {
+ retArr.push(this.output[1], '.0');
+ }
+ break;
+ case 'z':
+ if (this.isState('casting-to-integer')) {
+ retArr.push(this.output[2]);
+ } else {
+ retArr.push(this.output[2], '.0');
+ }
+ break;
+ default:
+ throw this.astErrorOutput('Unexpected expression', mNode);
+ }
+ }
+ 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(Math[name]);
+ return retArr;
+ }
+ const cleanName = utils.sanitizeName(name);
+ switch (property) {
+ case 'r':
+ retArr.push(`user_${ cleanName }.r`);
+ return retArr;
+ case 'g':
+ retArr.push(`user_${ cleanName }.g`);
+ return retArr;
+ case 'b':
+ retArr.push(`user_${ cleanName }.b`);
+ return retArr;
+ case 'a':
+ retArr.push(`user_${ cleanName }.a`);
+ return retArr;
+ }
+ break;
+ case 'this.constants.value':
+ if (typeof xProperty === 'undefined') {
+ switch (type) {
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ retArr.push(`constants_${ utils.sanitizeName(name) }`);
+ return retArr;
+ }
+ }
+ 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;
+ case 'fn()[][]':
+ this.astCallExpression(mNode.object.object, retArr);
+ retArr.push('[');
+ retArr.push(this.memberExpressionPropertyMarkup(mNode.object.property));
+ retArr.push(']');
+ retArr.push('[');
+ retArr.push(this.memberExpressionPropertyMarkup(mNode.property));
+ retArr.push(']');
+ return retArr;
+ case '[][]':
+ this.astArrayExpression(mNode.object, retArr);
+ retArr.push('[');
+ retArr.push(this.memberExpressionPropertyMarkup(property));
+ retArr.push(']');
+ return retArr;
+ default:
+ throw this.astErrorOutput('Unexpected expression', mNode);
+ }
+
+ if (mNode.computed === false) {
+ // handle simple types
+ switch (type) {
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ case 'Boolean':
+ retArr.push(`${origin}_${utils.sanitizeName(name)}`);
+ return retArr;
+ }
+ }
+
+ // handle more complex types
+ // argument may have come from a parent
+ const markupName = `${origin}_${utils.sanitizeName(name)}`;
+
+ switch (type) {
+ case 'Array(2)':
+ case 'Array(3)':
+ case 'Array(4)':
+ // Get from local vec4
+ this.astGeneric(mNode.object, retArr);
+ retArr.push('[');
+ retArr.push(this.memberExpressionPropertyMarkup(xProperty));
+ retArr.push(']');
+ break;
+ case 'HTMLImageArray':
+ retArr.push(`getImage3D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'ArrayTexture(1)':
+ retArr.push(`getFloatFromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'Array1D(2)':
+ case 'Array2D(2)':
+ case 'Array3D(2)':
+ retArr.push(`getMemoryOptimizedVec2(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'ArrayTexture(2)':
+ retArr.push(`getVec2FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'Array1D(3)':
+ case 'Array2D(3)':
+ case 'Array3D(3)':
+ retArr.push(`getMemoryOptimizedVec3(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'ArrayTexture(3)':
+ retArr.push(`getVec3FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'Array1D(4)':
+ case 'Array2D(4)':
+ case 'Array3D(4)':
+ retArr.push(`getMemoryOptimizedVec4(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'ArrayTexture(4)':
+ case 'HTMLCanvas':
+ case 'OffscreenCanvas':
+ case 'HTMLImage':
+ case 'ImageBitmap':
+ case 'ImageData':
+ case 'HTMLVideo':
+ retArr.push(`getVec4FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'NumberTexture':
+ case 'Array':
+ case 'Array2D':
+ case 'Array3D':
+ case 'Array4D':
+ case 'Input':
+ case 'Number':
+ case 'Float':
+ case 'Integer':
+ if (this.precision === 'single') {
+ // bitRatio is always 4 here, javascript doesn't yet have 8 or 16 bit support
+ // TODO: make 8 or 16 bit work anyway!
+ retArr.push(`getMemoryOptimized32(${markupName}, ${markupName}Size, ${markupName}Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ } else {
+ const bitRatio = (origin === 'user' ?
+ this.lookupFunctionArgumentBitRatio(this.name, name) :
+ this.constantBitRatios[name]
+ );
+ switch (bitRatio) {
+ case 1:
+ retArr.push(`get8(${markupName}, ${markupName}Size, ${markupName}Dim, `);
+ break;
+ case 2:
+ retArr.push(`get16(${markupName}, ${markupName}Size, ${markupName}Dim, `);
+ break;
+ case 4:
+ case 0:
+ retArr.push(`get32(${markupName}, ${markupName}Size, ${markupName}Dim, `);
+ break;
+ default:
+ throw new Error(`unhandled bit ratio of ${bitRatio}`);
+ }
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ }
+ break;
+ case 'MemoryOptimizedNumberTexture':
+ retArr.push(`getMemoryOptimized32(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);
+ this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);
+ retArr.push(')');
+ break;
+ case 'Matrix(2)':
+ case 'Matrix(3)':
+ case 'Matrix(4)':
+ retArr.push(`${markupName}[${this.memberExpressionPropertyMarkup(yProperty)}]`);
+ if (yProperty) {
+ retArr.push(`[${this.memberExpressionPropertyMarkup(xProperty)}]`);
+ }
+ break;
+ default:
+ throw new Error(`unhandled member expression "${ type }"`);
+ }
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *call* expression
+ * @param {Object} ast - the AST object to parse
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astCallExpression(ast, retArr) {
+ if (!ast.callee) {
+ throw this.astErrorOutput('Unknown CallExpression', ast);
+ }
+
+ let functionName = null;
+ const isMathFunction = this.isAstMathFunction(ast);
+
+ // Its a math operator or this.something(), remove the prefix
+ if (isMathFunction || (ast.callee.object && ast.callee.object.type === 'ThisExpression')) {
+ functionName = ast.callee.property.name;
+ }
+ // Issue #212, BABEL!
+ 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);
+ }
+
+ // if this if grows to more than one, lets use a switch
+ switch (functionName) {
+ case 'pow':
+ functionName = '_pow';
+ break;
+ case 'round':
+ functionName = '_round';
+ break;
+ }
+
+ // Register the function into the called registry
+ if (this.calledFunctions.indexOf(functionName) < 0) {
+ this.calledFunctions.push(functionName);
+ }
+
+ if (functionName === 'random' && this.plugins && this.plugins.length > 0) {
+ for (let i = 0; i < this.plugins.length; i++) {
+ const plugin = this.plugins[i];
+ if (plugin.functionMatch === 'Math.random()' && plugin.functionReplace) {
+ retArr.push(plugin.functionReplace);
+ return retArr;
+ }
+ }
+ }
+
+ // track the function was called
+ if (this.onFunctionCall) {
+ this.onFunctionCall(this.name, functionName, ast.arguments);
+ }
+
+ // Call the function
+ retArr.push(functionName);
+
+ // Open arguments space
+ retArr.push('(');
+
+ // Add the arguments
+ 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;
+ 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('int(');
+ 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('float(');
+ 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 if (argument.type === 'ArrayExpression' || argument.type === 'MemberExpression' || argument.type === 'CallExpression') {
+ this.astGeneric(argument, retArr);
+ } else {
+ throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast);
+ }
+ 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 (targetType === argumentType) {
+ if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast);
+ this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i);
+ const name = utils.sanitizeName(argument.name);
+ retArr.push(`user_${name},user_${name}Size,user_${name}Dim`);
+ continue;
+ }
+ break;
+ }
+ throw this.astErrorOutput(`Unhandled argument combination of ${ argumentType } and ${ targetType } for argument named "${ argument.name }"`, ast);
+ }
+ }
+ // Close arguments space
+ retArr.push(')');
+
+ return retArr;
+ }
+
+ /**
+ * @desc Parses the abstract syntax tree for *Array* Expression
+ * @param {Object} arrNode - the AST object to parse
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append retArr
+ */
+ astArrayExpression(arrNode, retArr) {
+ const returnType = this.getType(arrNode);
+
+ const arrLen = arrNode.elements.length;
+
+ switch (returnType) {
+ case 'Matrix(2)':
+ case 'Matrix(3)':
+ case 'Matrix(4)':
+ retArr.push(`mat${arrLen}(`);
+ break;
+ default:
+ retArr.push(`vec${arrLen}(`);
+ }
+ for (let i = 0; i < arrLen; ++i) {
+ if (i > 0) {
+ retArr.push(', ');
+ }
+ const subNode = arrNode.elements[i];
+ 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;
+ default:
+ this.astGeneric(property, result);
+ }
+ return result.join('');
+ }
}
-function ensureIndentifierType(paramName, expectedType, ast, funcParam) {
- const start = ast.loc.start;
-
- if (!isIdentifierKernelParam(paramName, funcParam) && expectedType !== 'float') {
- throw 'Error unexpected identifier ' + paramName + ' on line ' + start.line;
- } else {
- const actualType = funcParam.paramTypes[funcParam.paramNames.indexOf(paramName)];
- if (actualType !== expectedType) {
- throw 'Error unexpected identifier ' + paramName + ' on line ' + start.line;
- }
- }
-}
+const typeMap = {
+ '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',
+};
-/**
- * @ignore
- * @function
- * @name webgl_regex_optimize
- *
- * @desc [INTERNAL] Takes the near final webgl function string, and do regex search and replacments.
- * For voodoo optimize out the following:
- *
- * - decode32(encode32(
- * - encode32(decode32(
- *
- * @param {String} inStr - The webGl function String
- *
- */
-function webGlRegexOptimize(inStr) {
- return inStr
- .replace(DECODE32_ENCODE32, '((')
- .replace(ENCODE32_DECODE32, '((');
-}
\ No newline at end of file
+const operatorMap = {
+ '===': '==',
+ '!==': '!='
+};
+
+module.exports = {
+ WebGLFunctionNode
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-string.js b/src/backend/web-gl/kernel-string.js
deleted file mode 100644
index c07f7eef..00000000
--- a/src/backend/web-gl/kernel-string.js
+++ /dev/null
@@ -1,57 +0,0 @@
-'use strict';
-
-const utils = require('../../core/utils');
-const kernelRunShortcut = require('../kernel-run-shortcut');
-
-module.exports = function(gpuKernel, name) {
- return `() => {
- ${ kernelRunShortcut.toString() };
- const utils = {
- allPropertiesOf: function ${ utils.allPropertiesOf.toString() },
- clone: function ${ utils.clone.toString() },
- splitArray: function ${ utils.splitArray.toString() },
- getArgumentType: function ${ utils.getArgumentType.toString() },
- getDimensions: function ${ utils.getDimensions.toString() },
- dimToTexSize: function ${ utils.dimToTexSize.toString() },
- copyFlatten: function ${ utils.copyFlatten.toString() },
- flatten: function ${ utils.flatten.toString() },
- systemEndianness: '${ utils.systemEndianness() }',
- initWebGl: function ${ utils.initWebGl.toString() },
- isArray: function ${ utils.isArray.toString() }
- };
- class ${ name || 'Kernel' } {
- constructor() {
- this.argumentsLength = 0;
- this._canvas = null;
- this._webGl = null;
- this.built = false;
- this.program = null;
- this.paramNames = ${ JSON.stringify(gpuKernel.paramNames) };
- this.paramTypes = ${ JSON.stringify(gpuKernel.paramTypes) };
- this.texSize = ${ JSON.stringify(gpuKernel.texSize) };
- this.output = ${ JSON.stringify(gpuKernel.output) };
- this.compiledFragShaderString = \`${ gpuKernel.compiledFragShaderString }\`;
- this.compiledVertShaderString = \`${ gpuKernel.compiledVertShaderString }\`;
- this.programUniformLocationCache = {};
- this.textureCache = {};
- this.subKernelOutputTextures = null;
- }
- ${ gpuKernel._getFragShaderString.toString() }
- ${ gpuKernel._getVertShaderString.toString() }
- validateOptions() {}
- setupParams() {}
- setCanvas(canvas) { this._canvas = canvas; return this; }
- setWebGl(webGl) { this._webGl = webGl; return this; }
- ${ gpuKernel.getUniformLocation.toString() }
- ${ gpuKernel.setupParams.toString() }
- ${ gpuKernel.build.toString() }
- ${ gpuKernel.run.toString() }
- ${ gpuKernel._addArgument.toString() }
- ${ gpuKernel.getArgumentTexture.toString() }
- ${ gpuKernel.getTextureCache.toString() }
- ${ gpuKernel.getOutputTexture.toString() }
- ${ gpuKernel.renderOutput.toString() }
- };
- return kernelRunShortcut(new Kernel());
- };`;
-};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value-maps.js b/src/backend/web-gl/kernel-value-maps.js
new file mode 100644
index 00000000..843164a7
--- /dev/null
+++ b/src/backend/web-gl/kernel-value-maps.js
@@ -0,0 +1,202 @@
+const { WebGLKernelValueBoolean } = require('./kernel-value/boolean');
+const { WebGLKernelValueFloat } = require('./kernel-value/float');
+const { WebGLKernelValueInteger } = require('./kernel-value/integer');
+
+const { WebGLKernelValueHTMLImage } = require('./kernel-value/html-image');
+const { WebGLKernelValueDynamicHTMLImage } = require('./kernel-value/dynamic-html-image');
+
+const { WebGLKernelValueHTMLVideo } = require('./kernel-value/html-video');
+const { WebGLKernelValueDynamicHTMLVideo } = require('./kernel-value/dynamic-html-video');
+
+const { WebGLKernelValueSingleInput } = require('./kernel-value/single-input');
+const { WebGLKernelValueDynamicSingleInput } = require('./kernel-value/dynamic-single-input');
+
+const { WebGLKernelValueUnsignedInput } = require('./kernel-value/unsigned-input');
+const { WebGLKernelValueDynamicUnsignedInput } = require('./kernel-value/dynamic-unsigned-input');
+
+const { WebGLKernelValueMemoryOptimizedNumberTexture } = require('./kernel-value/memory-optimized-number-texture');
+const { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } = require('./kernel-value/dynamic-memory-optimized-number-texture');
+
+const { WebGLKernelValueNumberTexture } = require('./kernel-value/number-texture');
+const { WebGLKernelValueDynamicNumberTexture } = require('./kernel-value/dynamic-number-texture');
+
+const { WebGLKernelValueSingleArray } = require('./kernel-value/single-array');
+const { WebGLKernelValueDynamicSingleArray } = require('./kernel-value/dynamic-single-array');
+
+const { WebGLKernelValueSingleArray1DI } = require('./kernel-value/single-array1d-i');
+const { WebGLKernelValueDynamicSingleArray1DI } = require('./kernel-value/dynamic-single-array1d-i');
+
+const { WebGLKernelValueSingleArray2DI } = require('./kernel-value/single-array2d-i');
+const { WebGLKernelValueDynamicSingleArray2DI } = require('./kernel-value/dynamic-single-array2d-i');
+
+const { WebGLKernelValueSingleArray3DI } = require('./kernel-value/single-array3d-i');
+const { WebGLKernelValueDynamicSingleArray3DI } = require('./kernel-value/dynamic-single-array3d-i');
+
+const { WebGLKernelValueArray2 } = require('./kernel-value/array2');
+const { WebGLKernelValueArray3 } = require('./kernel-value/array3');
+const { WebGLKernelValueArray4 } = require('./kernel-value/array4');
+
+const { WebGLKernelValueUnsignedArray } = require('./kernel-value/unsigned-array');
+const { WebGLKernelValueDynamicUnsignedArray } = require('./kernel-value/dynamic-unsigned-array');
+
+const kernelValueMaps = {
+ unsigned: {
+ dynamic: {
+ 'Boolean': WebGLKernelValueBoolean,
+ 'Integer': WebGLKernelValueInteger,
+ 'Float': WebGLKernelValueFloat,
+ 'Array': WebGLKernelValueDynamicUnsignedArray,
+ 'Array(2)': WebGLKernelValueArray2,
+ 'Array(3)': WebGLKernelValueArray3,
+ 'Array(4)': WebGLKernelValueArray4,
+ 'Array1D(2)': false,
+ 'Array1D(3)': false,
+ 'Array1D(4)': false,
+ 'Array2D(2)': false,
+ 'Array2D(3)': false,
+ 'Array2D(4)': false,
+ 'Array3D(2)': false,
+ 'Array3D(3)': false,
+ 'Array3D(4)': false,
+ 'Input': WebGLKernelValueDynamicUnsignedInput,
+ 'NumberTexture': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGLKernelValueDynamicHTMLImage,
+ 'OffscreenCanvas': WebGLKernelValueDynamicHTMLImage,
+ 'HTMLImage': WebGLKernelValueDynamicHTMLImage,
+ 'ImageBitmap': WebGLKernelValueDynamicHTMLImage,
+ 'ImageData': WebGLKernelValueDynamicHTMLImage,
+ 'HTMLImageArray': false,
+ 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo,
+ },
+ static: {
+ 'Boolean': WebGLKernelValueBoolean,
+ 'Float': WebGLKernelValueFloat,
+ 'Integer': WebGLKernelValueInteger,
+ 'Array': WebGLKernelValueUnsignedArray,
+ 'Array(2)': WebGLKernelValueArray2,
+ 'Array(3)': WebGLKernelValueArray3,
+ 'Array(4)': WebGLKernelValueArray4,
+ 'Array1D(2)': false,
+ 'Array1D(3)': false,
+ 'Array1D(4)': false,
+ 'Array2D(2)': false,
+ 'Array2D(3)': false,
+ 'Array2D(4)': false,
+ 'Array3D(2)': false,
+ 'Array3D(3)': false,
+ 'Array3D(4)': false,
+ 'Input': WebGLKernelValueUnsignedInput,
+ 'NumberTexture': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(1)': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(2)': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(3)': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(4)': WebGLKernelValueNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGLKernelValueHTMLImage,
+ 'OffscreenCanvas': WebGLKernelValueHTMLImage,
+ 'HTMLImage': WebGLKernelValueHTMLImage,
+ 'ImageBitmap': WebGLKernelValueHTMLImage,
+ 'ImageData': WebGLKernelValueHTMLImage,
+ 'HTMLImageArray': false,
+ 'HTMLVideo': WebGLKernelValueHTMLVideo,
+ }
+ },
+ single: {
+ dynamic: {
+ 'Boolean': WebGLKernelValueBoolean,
+ 'Integer': WebGLKernelValueInteger,
+ 'Float': WebGLKernelValueFloat,
+ 'Array': WebGLKernelValueDynamicSingleArray,
+ 'Array(2)': WebGLKernelValueArray2,
+ 'Array(3)': WebGLKernelValueArray3,
+ 'Array(4)': WebGLKernelValueArray4,
+ 'Array1D(2)': WebGLKernelValueDynamicSingleArray1DI,
+ 'Array1D(3)': WebGLKernelValueDynamicSingleArray1DI,
+ 'Array1D(4)': WebGLKernelValueDynamicSingleArray1DI,
+ 'Array2D(2)': WebGLKernelValueDynamicSingleArray2DI,
+ 'Array2D(3)': WebGLKernelValueDynamicSingleArray2DI,
+ 'Array2D(4)': WebGLKernelValueDynamicSingleArray2DI,
+ 'Array3D(2)': WebGLKernelValueDynamicSingleArray3DI,
+ 'Array3D(3)': WebGLKernelValueDynamicSingleArray3DI,
+ 'Array3D(4)': WebGLKernelValueDynamicSingleArray3DI,
+ 'Input': WebGLKernelValueDynamicSingleInput,
+ 'NumberTexture': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture,
+ 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGLKernelValueDynamicHTMLImage,
+ 'OffscreenCanvas': WebGLKernelValueDynamicHTMLImage,
+ 'HTMLImage': WebGLKernelValueDynamicHTMLImage,
+ 'ImageBitmap': WebGLKernelValueDynamicHTMLImage,
+ 'ImageData': WebGLKernelValueDynamicHTMLImage,
+ 'HTMLImageArray': false,
+ 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo,
+ },
+ static: {
+ 'Boolean': WebGLKernelValueBoolean,
+ 'Float': WebGLKernelValueFloat,
+ 'Integer': WebGLKernelValueInteger,
+ 'Array': WebGLKernelValueSingleArray,
+ 'Array(2)': WebGLKernelValueArray2,
+ 'Array(3)': WebGLKernelValueArray3,
+ 'Array(4)': WebGLKernelValueArray4,
+ 'Array1D(2)': WebGLKernelValueSingleArray1DI,
+ 'Array1D(3)': WebGLKernelValueSingleArray1DI,
+ 'Array1D(4)': WebGLKernelValueSingleArray1DI,
+ 'Array2D(2)': WebGLKernelValueSingleArray2DI,
+ 'Array2D(3)': WebGLKernelValueSingleArray2DI,
+ 'Array2D(4)': WebGLKernelValueSingleArray2DI,
+ 'Array3D(2)': WebGLKernelValueSingleArray3DI,
+ 'Array3D(3)': WebGLKernelValueSingleArray3DI,
+ 'Array3D(4)': WebGLKernelValueSingleArray3DI,
+ 'Input': WebGLKernelValueSingleInput,
+ 'NumberTexture': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(1)': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(2)': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(3)': WebGLKernelValueNumberTexture,
+ 'ArrayTexture(4)': WebGLKernelValueNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGLKernelValueHTMLImage,
+ 'OffscreenCanvas': WebGLKernelValueHTMLImage,
+ 'HTMLImage': WebGLKernelValueHTMLImage,
+ 'ImageBitmap': WebGLKernelValueHTMLImage,
+ 'ImageData': WebGLKernelValueHTMLImage,
+ 'HTMLImageArray': false,
+ 'HTMLVideo': WebGLKernelValueHTMLVideo,
+ }
+ },
+};
+
+function lookupKernelValueType(type, dynamic, precision, value) {
+ if (!type) {
+ throw new Error('type missing');
+ }
+ if (!dynamic) {
+ throw new Error('dynamic missing');
+ }
+ if (!precision) {
+ throw new Error('precision missing');
+ }
+ if (value.type) {
+ type = value.type;
+ }
+ const types = kernelValueMaps[precision][dynamic];
+ if (types[type] === false) {
+ return null;
+ } else if (types[type] === undefined) {
+ throw new Error(`Could not find a KernelValue for ${ type }`);
+ }
+ return types[type];
+}
+
+module.exports = {
+ lookupKernelValueType,
+ kernelValueMaps,
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/array.js b/src/backend/web-gl/kernel-value/array.js
new file mode 100644
index 00000000..b6e77f2f
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/array.js
@@ -0,0 +1,90 @@
+const { WebGLKernelValue } = require('./index');
+const { Input } = require('../../../input');
+
+/**
+ * @abstract
+ */
+class WebGLKernelArray extends WebGLKernelValue {
+ /**
+ *
+ * @param {number} width
+ * @param {number} height
+ */
+ checkSize(width, height) {
+ if (!this.kernel.validate) return;
+ const { maxTextureSize } = this.kernel.constructor.features;
+ if (width > maxTextureSize || height > maxTextureSize) {
+ if (width > height) {
+ throw new Error(`Argument texture width of ${width} larger than maximum size of ${maxTextureSize} for your GPU`);
+ } else if (width < height) {
+ throw new Error(`Argument texture height of ${height} larger than maximum size of ${maxTextureSize} for your GPU`);
+ } else {
+ throw new Error(`Argument texture height and width of ${height} larger than maximum size of ${maxTextureSize} for your GPU`);
+ }
+ }
+ }
+
+ setup() {
+ this.requestTexture();
+ this.setupTexture();
+ this.defineTexture();
+ }
+
+ requestTexture() {
+ this.texture = this.onRequestTexture();
+ }
+
+ defineTexture() {
+ const { context: gl } = this;
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ }
+
+ setupTexture() {
+ this.contextHandle = this.onRequestContextHandle();
+ this.index = this.onRequestIndex();
+ this.dimensionsId = this.id + 'Dim';
+ this.sizeId = this.id + 'Size';
+ }
+
+ /**
+ * bit storage ratio of source to target 'buffer', i.e. if 8bit array -> 32bit tex = 4
+ * @param value
+ * @returns {number}
+ */
+ getBitRatio(value) {
+ if (Array.isArray(value[0])) {
+ return this.getBitRatio(value[0]);
+ } else if (value.constructor === Input) {
+ return this.getBitRatio(value.value);
+ }
+ switch (value.constructor) {
+ case Uint8ClampedArray:
+ case Uint8Array:
+ case Int8Array:
+ return 1;
+ case Uint16Array:
+ case Int16Array:
+ return 2;
+ case Float32Array:
+ case Int32Array:
+ default:
+ return 4;
+ }
+ }
+
+ destroy() {
+ if (this.prevArg) {
+ this.prevArg.delete();
+ }
+ this.context.deleteTexture(this.texture);
+ }
+}
+
+module.exports = {
+ WebGLKernelArray
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/array2.js b/src/backend/web-gl/kernel-value/array2.js
new file mode 100644
index 00000000..ea4f1467
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/array2.js
@@ -0,0 +1,29 @@
+const { WebGLKernelValue } = require('./index');
+
+class WebGLKernelValueArray2 extends WebGLKernelValue {
+ constructor(value, settings) {
+ super(value, settings);
+ this.uploadValue = value;
+ }
+ getSource(value) {
+ if (this.origin === 'constants') {
+ return `const vec2 ${this.id} = vec2(${value[0]},${value[1]});\n`;
+ }
+ return `uniform vec2 ${this.id};\n`;
+ }
+
+ getStringValueHandler() {
+ // resetting isn't supported for Array(2)
+ if (this.origin === 'constants') return '';
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+
+ updateValue(value) {
+ if (this.origin === 'constants') return;
+ this.kernel.setUniform2fv(this.id, this.uploadValue = value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueArray2
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/array3.js b/src/backend/web-gl/kernel-value/array3.js
new file mode 100644
index 00000000..47ad55f8
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/array3.js
@@ -0,0 +1,29 @@
+const { WebGLKernelValue } = require('./index');
+
+class WebGLKernelValueArray3 extends WebGLKernelValue {
+ constructor(value, settings) {
+ super(value, settings);
+ this.uploadValue = value;
+ }
+ getSource(value) {
+ if (this.origin === 'constants') {
+ return `const vec3 ${this.id} = vec3(${value[0]},${value[1]},${value[2]});\n`;
+ }
+ return `uniform vec3 ${this.id};\n`;
+ }
+
+ getStringValueHandler() {
+ // resetting isn't supported for Array(3)
+ if (this.origin === 'constants') return '';
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+
+ updateValue(value) {
+ if (this.origin === 'constants') return;
+ this.kernel.setUniform3fv(this.id, this.uploadValue = value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueArray3
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/array4.js b/src/backend/web-gl/kernel-value/array4.js
new file mode 100644
index 00000000..a5556476
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/array4.js
@@ -0,0 +1,29 @@
+const { WebGLKernelValue } = require('./index');
+
+class WebGLKernelValueArray4 extends WebGLKernelValue {
+ constructor(value, settings) {
+ super(value, settings);
+ this.uploadValue = value;
+ }
+ getSource(value) {
+ if (this.origin === 'constants') {
+ return `const vec4 ${this.id} = vec4(${value[0]},${value[1]},${value[2]},${value[3]});\n`;
+ }
+ return `uniform vec4 ${this.id};\n`;
+ }
+
+ getStringValueHandler() {
+ // resetting isn't supported for Array(4)
+ if (this.origin === 'constants') return '';
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+
+ updateValue(value) {
+ if (this.origin === 'constants') return;
+ this.kernel.setUniform4fv(this.id, this.uploadValue = value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueArray4
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/boolean.js b/src/backend/web-gl/kernel-value/boolean.js
new file mode 100644
index 00000000..895663d0
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/boolean.js
@@ -0,0 +1,28 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValue } = require('./index');
+
+class WebGLKernelValueBoolean extends WebGLKernelValue {
+ constructor(value, settings) {
+ super(value, settings);
+ this.uploadValue = value;
+ }
+ getSource(value) {
+ if (this.origin === 'constants') {
+ return `const bool ${this.id} = ${value};\n`;
+ }
+ return `uniform bool ${this.id};\n`;
+ }
+
+ getStringValueHandler() {
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+
+ updateValue(value) {
+ if (this.origin === 'constants') return;
+ this.kernel.setUniform1i(this.id, this.uploadValue = value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueBoolean
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/dynamic-html-image.js b/src/backend/web-gl/kernel-value/dynamic-html-image.js
new file mode 100644
index 00000000..926ead66
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/dynamic-html-image.js
@@ -0,0 +1,26 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueHTMLImage } = require('./html-image');
+
+class WebGLKernelValueDynamicHTMLImage extends WebGLKernelValueHTMLImage {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ const { width, height } = value;
+ this.checkSize(width, height);
+ this.dimensions = [width, height, 1];
+ this.textureSize = [width, height];
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicHTMLImage
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/dynamic-html-video.js b/src/backend/web-gl/kernel-value/dynamic-html-video.js
new file mode 100644
index 00000000..a10a00f6
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/dynamic-html-video.js
@@ -0,0 +1,7 @@
+const { WebGLKernelValueDynamicHTMLImage } = require('./dynamic-html-image');
+
+class WebGLKernelValueDynamicHTMLVideo extends WebGLKernelValueDynamicHTMLImage {}
+
+module.exports = {
+ WebGLKernelValueDynamicHTMLVideo
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/dynamic-memory-optimized-number-texture.js b/src/backend/web-gl/kernel-value/dynamic-memory-optimized-number-texture.js
new file mode 100644
index 00000000..0db73297
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/dynamic-memory-optimized-number-texture.js
@@ -0,0 +1,25 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueMemoryOptimizedNumberTexture } = require('./memory-optimized-number-texture');
+
+class WebGLKernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(inputTexture) {
+ this.dimensions = inputTexture.dimensions;
+ this.checkSize(inputTexture.size[0], inputTexture.size[1]);
+ this.textureSize = inputTexture.size;
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(inputTexture);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicMemoryOptimizedNumberTexture
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/dynamic-number-texture.js b/src/backend/web-gl/kernel-value/dynamic-number-texture.js
new file mode 100644
index 00000000..edf5980d
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/dynamic-number-texture.js
@@ -0,0 +1,25 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueNumberTexture } = require('./number-texture');
+
+class WebGLKernelValueDynamicNumberTexture extends WebGLKernelValueNumberTexture {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.dimensions = value.dimensions;
+ this.checkSize(value.size[0], value.size[1]);
+ this.textureSize = value.size;
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicNumberTexture
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/dynamic-single-array.js b/src/backend/web-gl/kernel-value/dynamic-single-array.js
new file mode 100644
index 00000000..165fa10a
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/dynamic-single-array.js
@@ -0,0 +1,27 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray } = require('./single-array');
+
+class WebGLKernelValueDynamicSingleArray extends WebGLKernelValueSingleArray {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.dimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.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(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicSingleArray
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/dynamic-single-array1d-i.js b/src/backend/web-gl/kernel-value/dynamic-single-array1d-i.js
new file mode 100644
index 00000000..0c9489ce
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/dynamic-single-array1d-i.js
@@ -0,0 +1,23 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray1DI } = require('./single-array1d-i');
+
+class WebGLKernelValueDynamicSingleArray1DI extends WebGLKernelValueSingleArray1DI {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.setShape(value);
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicSingleArray1DI
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/dynamic-single-array2d-i.js b/src/backend/web-gl/kernel-value/dynamic-single-array2d-i.js
new file mode 100644
index 00000000..b164f3c1
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/dynamic-single-array2d-i.js
@@ -0,0 +1,23 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray2DI } = require('./single-array2d-i');
+
+class WebGLKernelValueDynamicSingleArray2DI extends WebGLKernelValueSingleArray2DI {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.setShape(value);
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicSingleArray2DI
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/dynamic-single-array3d-i.js b/src/backend/web-gl/kernel-value/dynamic-single-array3d-i.js
new file mode 100644
index 00000000..b1d52a5d
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/dynamic-single-array3d-i.js
@@ -0,0 +1,23 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray3DI } = require('./single-array3d-i');
+
+class WebGLKernelValueDynamicSingleArray3DI extends WebGLKernelValueSingleArray3DI {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.setShape(value);
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicSingleArray3DI
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/dynamic-single-input.js b/src/backend/web-gl/kernel-value/dynamic-single-input.js
new file mode 100644
index 00000000..4c17285d
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/dynamic-single-input.js
@@ -0,0 +1,28 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleInput } = require('./single-input');
+
+class WebGLKernelValueDynamicSingleInput extends WebGLKernelValueSingleInput {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ let [w, h, d] = value.size;
+ this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);
+ this.textureSize = utils.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(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicSingleInput
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/dynamic-unsigned-array.js b/src/backend/web-gl/kernel-value/dynamic-unsigned-array.js
new file mode 100644
index 00000000..fb2dd7dd
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/dynamic-unsigned-array.js
@@ -0,0 +1,29 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueUnsignedArray } = require('./unsigned-array');
+
+class WebGLKernelValueDynamicUnsignedArray extends WebGLKernelValueUnsignedArray {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.dimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.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 Type = this.getTransferArrayType(value);
+ this.preUploadValue = new Type(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(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicUnsignedArray
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/dynamic-unsigned-input.js b/src/backend/web-gl/kernel-value/dynamic-unsigned-input.js
new file mode 100644
index 00000000..de16334b
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/dynamic-unsigned-input.js
@@ -0,0 +1,30 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueUnsignedInput } = require('./unsigned-input');
+
+class WebGLKernelValueDynamicUnsignedInput extends WebGLKernelValueUnsignedInput {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ let [w, h, d] = value.size;
+ this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);
+ this.textureSize = utils.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 Type = this.getTransferArrayType(value.value);
+ this.preUploadValue = new Type(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(value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueDynamicUnsignedInput
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/float.js b/src/backend/web-gl/kernel-value/float.js
new file mode 100644
index 00000000..3668bfb6
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/float.js
@@ -0,0 +1,30 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValue } = require('./index');
+
+class WebGLKernelValueFloat extends WebGLKernelValue {
+ constructor(value, settings) {
+ super(value, settings);
+ this.uploadValue = value;
+ }
+ getStringValueHandler() {
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+ getSource(value) {
+ if (this.origin === 'constants') {
+ if (Number.isInteger(value)) {
+ return `const float ${this.id} = ${value}.0;\n`;
+ }
+ return `const float ${this.id} = ${value};\n`;
+ }
+ return `uniform float ${this.id};\n`;
+ }
+
+ updateValue(value) {
+ if (this.origin === 'constants') return;
+ this.kernel.setUniform1f(this.id, this.uploadValue = value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueFloat
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/html-image.js b/src/backend/web-gl/kernel-value/html-image.js
new file mode 100644
index 00000000..e0f169c2
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/html-image.js
@@ -0,0 +1,42 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueHTMLImage extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ const { width, height } = value;
+ this.checkSize(width, height);
+ this.dimensions = [width, height, 1];
+ this.textureSize = [width, height];
+ this.uploadValue = value;
+ }
+
+ getStringValueHandler() {
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+
+ getSource() {
+ return utils.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(inputImage) {
+ if (inputImage.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(inputImage.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue = inputImage);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueHTMLImage
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/html-video.js b/src/backend/web-gl/kernel-value/html-video.js
new file mode 100644
index 00000000..56165481
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/html-video.js
@@ -0,0 +1,7 @@
+const { WebGLKernelValueHTMLImage } = require('./html-image');
+
+class WebGLKernelValueHTMLVideo extends WebGLKernelValueHTMLImage {}
+
+module.exports = {
+ WebGLKernelValueHTMLVideo
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/index.js b/src/backend/web-gl/kernel-value/index.js
new file mode 100644
index 00000000..671bade1
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/index.js
@@ -0,0 +1,66 @@
+const { utils } = require('../../../utils');
+const { KernelValue } = require('../../kernel-value');
+
+class WebGLKernelValue extends KernelValue {
+ /**
+ * @param {KernelVariable} value
+ * @param {IWebGLKernelValueSettings} settings
+ */
+ constructor(value, settings) {
+ super(value, settings);
+ this.dimensionsId = null;
+ this.sizeId = null;
+ this.initialValueConstructor = value.constructor;
+ this.onRequestTexture = settings.onRequestTexture;
+ this.onRequestIndex = settings.onRequestIndex;
+ this.uploadValue = null;
+ this.textureSize = null;
+ this.bitRatio = null;
+ this.prevArg = null;
+ }
+
+ get id() {
+ return `${this.origin}_${utils.sanitizeName(this.name)}`;
+ }
+
+ setup() {}
+
+ getTransferArrayType(value) {
+ if (Array.isArray(value[0])) {
+ return this.getTransferArrayType(value[0]);
+ }
+ switch (value.constructor) {
+ case Array:
+ case Int32Array:
+ case Int16Array:
+ case Int8Array:
+ return Float32Array;
+ case Uint8ClampedArray:
+ case Uint8Array:
+ case Uint16Array:
+ case Uint32Array:
+ case Float32Array:
+ case Float64Array:
+ return value.constructor;
+ }
+ console.warn('Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros');
+ return value.constructor;
+ }
+
+ /**
+ * Used for when we want a string output of our kernel, so we can still input values to the kernel
+ */
+ getStringValueHandler() {
+ throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`);
+ }
+
+ getVariablePrecisionString() {
+ return this.kernel.getVariablePrecisionString(this.textureSize || undefined, this.tactic || undefined);
+ }
+
+ destroy() {}
+}
+
+module.exports = {
+ WebGLKernelValue
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/integer.js b/src/backend/web-gl/kernel-value/integer.js
new file mode 100644
index 00000000..c7dad4ac
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/integer.js
@@ -0,0 +1,27 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValue } = require('./index');
+
+class WebGLKernelValueInteger extends WebGLKernelValue {
+ constructor(value, settings) {
+ super(value, settings);
+ this.uploadValue = value;
+ }
+ getStringValueHandler() {
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+ getSource(value) {
+ if (this.origin === 'constants') {
+ return `const int ${this.id} = ${ parseInt(value) };\n`;
+ }
+ return `uniform int ${this.id};\n`;
+ }
+
+ updateValue(value) {
+ if (this.origin === 'constants') return;
+ this.kernel.setUniform1i(this.id, this.uploadValue = value);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueInteger
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/memory-optimized-number-texture.js b/src/backend/web-gl/kernel-value/memory-optimized-number-texture.js
new file mode 100644
index 00000000..11193441
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/memory-optimized-number-texture.js
@@ -0,0 +1,72 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+const sameError = `Source and destination textures are the same. Use immutable = true and manually cleanup kernel output texture memory with texture.delete()`;
+
+class WebGLKernelValueMemoryOptimizedNumberTexture extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ const [width, height] = value.size;
+ this.checkSize(width, height);
+ this.dimensions = value.dimensions;
+ this.textureSize = value.size;
+ this.uploadValue = value.texture;
+ this.forceUploadEachRun = true;
+ }
+
+ setup() {
+ this.setupTexture();
+ }
+
+ getStringValueHandler() {
+ return `const uploadValue_${this.name} = ${this.varName}.texture;\n`;
+ }
+
+ getSource() {
+ return utils.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]})`,
+ ]);
+ }
+
+ /**
+ * @param {GLTextureMemoryOptimized} inputTexture
+ */
+ updateValue(inputTexture) {
+ if (inputTexture.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(inputTexture.constructor);
+ return;
+ }
+ if (this.checkContext && inputTexture.context !== this.context) {
+ throw new Error(`Value ${this.name} (${this.type}) must be from same context`);
+ }
+
+ const { kernel, context: gl } = this;
+ if (kernel.pipeline) {
+ if (kernel.immutable) {
+ kernel.updateTextureArgumentRefs(this, inputTexture);
+ } else {
+ if (kernel.texture && kernel.texture.texture === inputTexture.texture) {
+ throw new Error(sameError);
+ } else if (kernel.mappedTextures) {
+ const { mappedTextures } = kernel;
+ for (let i = 0; i < mappedTextures.length; i++) {
+ if (mappedTextures[i].texture === inputTexture.texture) {
+ throw new Error(sameError);
+ }
+ }
+ }
+ }
+ }
+
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueMemoryOptimizedNumberTexture,
+ sameError
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/number-texture.js b/src/backend/web-gl/kernel-value/number-texture.js
new file mode 100644
index 00000000..97c43e7d
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/number-texture.js
@@ -0,0 +1,73 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+const { sameError } = require('./memory-optimized-number-texture');
+
+class WebGLKernelValueNumberTexture extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ const [width, height] = value.size;
+ this.checkSize(width, height);
+ const { size: textureSize, dimensions } = value;
+ this.bitRatio = this.getBitRatio(value);
+ this.dimensions = dimensions;
+ this.textureSize = textureSize;
+ this.uploadValue = value.texture;
+ this.forceUploadEachRun = true;
+ }
+
+ setup() {
+ this.setupTexture();
+ }
+
+ getStringValueHandler() {
+ return `const uploadValue_${this.name} = ${this.varName}.texture;\n`;
+ }
+
+ getSource() {
+ return utils.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]})`,
+ ]);
+ }
+
+ /**
+ *
+ * @param {GLTexture} inputTexture
+ */
+ updateValue(inputTexture) {
+ if (inputTexture.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(inputTexture.constructor);
+ return;
+ }
+ if (this.checkContext && inputTexture.context !== this.context) {
+ throw new Error(`Value ${this.name} (${this.type}) must be from same context`);
+ }
+
+ const { kernel, context: gl } = this;
+ if (kernel.pipeline) {
+ if (kernel.immutable) {
+ kernel.updateTextureArgumentRefs(this, inputTexture);
+ } else {
+ if (kernel.texture && kernel.texture.texture === inputTexture.texture) {
+ throw new Error(sameError);
+ } else if (kernel.mappedTextures) {
+ const { mappedTextures } = kernel;
+ for (let i = 0; i < mappedTextures.length; i++) {
+ if (mappedTextures[i].texture === inputTexture.texture) {
+ throw new Error(sameError);
+ }
+ }
+ }
+ }
+ }
+
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueNumberTexture
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/single-array.js b/src/backend/web-gl/kernel-value/single-array.js
new file mode 100644
index 00000000..1684f283
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/single-array.js
@@ -0,0 +1,47 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueSingleArray extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.bitRatio = 4;
+ this.dimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.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 utils.linesToString([
+ `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,
+ `flattenTo(${this.varName}, uploadValue_${this.name})`,
+ ]);
+ }
+
+ getSource() {
+ return utils.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(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueSingleArray
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/single-array1d-i.js b/src/backend/web-gl/kernel-value/single-array1d-i.js
new file mode 100644
index 00000000..0f7e4221
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/single-array1d-i.js
@@ -0,0 +1,52 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueSingleArray1DI extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.bitRatio = 4;
+ this.setShape(value);
+ }
+
+ setShape(value) {
+ const valueDimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio);
+ this.dimensions = new Int32Array([valueDimensions[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 utils.linesToString([
+ `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,
+ `flattenTo(${this.varName}, uploadValue_${this.name})`,
+ ]);
+ }
+
+ getSource() {
+ return utils.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(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flatten2dArrayTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueSingleArray1DI
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/single-array2d-i.js b/src/backend/web-gl/kernel-value/single-array2d-i.js
new file mode 100644
index 00000000..38bbf1ad
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/single-array2d-i.js
@@ -0,0 +1,52 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueSingleArray2DI extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.bitRatio = 4;
+ this.setShape(value);
+ }
+
+ setShape(value) {
+ const valueDimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio);
+ this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[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 utils.linesToString([
+ `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,
+ `flattenTo(${this.varName}, uploadValue_${this.name})`,
+ ]);
+ }
+
+ getSource() {
+ return utils.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(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flatten3dArrayTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueSingleArray2DI
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/single-array3d-i.js b/src/backend/web-gl/kernel-value/single-array3d-i.js
new file mode 100644
index 00000000..8992f1bd
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/single-array3d-i.js
@@ -0,0 +1,52 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueSingleArray3DI extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.bitRatio = 4;
+ this.setShape(value);
+ }
+
+ setShape(value) {
+ const valueDimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio);
+ this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], valueDimensions[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 utils.linesToString([
+ `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,
+ `flattenTo(${this.varName}, uploadValue_${this.name})`,
+ ]);
+ }
+
+ getSource() {
+ return utils.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(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flatten4dArrayTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueSingleArray3DI
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/single-input.js b/src/backend/web-gl/kernel-value/single-input.js
new file mode 100644
index 00000000..a9c3dbaa
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/single-input.js
@@ -0,0 +1,48 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueSingleInput extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.bitRatio = 4;
+ let [w, h, d] = value.size;
+ this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);
+ this.textureSize = utils.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 utils.linesToString([
+ `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,
+ `flattenTo(${this.varName}.value, uploadValue_${this.name})`,
+ ]);
+ }
+
+ getSource() {
+ return utils.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(input) {
+ if (input.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(input.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(input.value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueSingleInput
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/unsigned-array.js b/src/backend/web-gl/kernel-value/unsigned-array.js
new file mode 100644
index 00000000..8e52ae9f
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/unsigned-array.js
@@ -0,0 +1,50 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueUnsignedArray extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.bitRatio = this.getBitRatio(value);
+ this.dimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.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(value);
+ this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength);
+ this.uploadValue = new Uint8Array(this.preUploadValue.buffer);
+ }
+
+ getStringValueHandler() {
+ return utils.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 utils.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(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(value, this.preUploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueUnsignedArray
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel-value/unsigned-input.js b/src/backend/web-gl/kernel-value/unsigned-input.js
new file mode 100644
index 00000000..4370ac77
--- /dev/null
+++ b/src/backend/web-gl/kernel-value/unsigned-input.js
@@ -0,0 +1,51 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('./array');
+
+class WebGLKernelValueUnsignedInput extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.bitRatio = this.getBitRatio(value);
+ const [w, h, d] = value.size;
+ this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);
+ this.textureSize = utils.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(value.value);
+ this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength);
+ this.uploadValue = new Uint8Array(this.preUploadValue.buffer);
+ }
+
+ getStringValueHandler() {
+ return utils.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 utils.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(input) {
+ if (input.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(input.value, this.preUploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGLKernelValueUnsignedInput
+};
\ No newline at end of file
diff --git a/src/backend/web-gl/kernel.js b/src/backend/web-gl/kernel.js
index f05e3072..ffea4705 100644
--- a/src/backend/web-gl/kernel.js
+++ b/src/backend/web-gl/kernel.js
@@ -1,1227 +1,1607 @@
-'use strict';
-
-const fs = require('fs');
-const KernelBase = require('../kernel-base');
-const utils = require('../../core/utils');
-const Texture = require('../../core/texture');
-const fragShaderString = require('./shader-frag');
-const vertShaderString = require('./shader-vert');
-const kernelString = require('./kernel-string');
+const { GLKernel } = require('../gl/kernel');
+const { FunctionBuilder } = require('../function-builder');
+const { WebGLFunctionNode } = require('./function-node');
+const { utils } = require('../../utils');
+const mrud = require('../../plugins/math-random-uniformly-distributed');
+const { fragmentShader } = require('./fragment-shader');
+const { vertexShader } = require('./vertex-shader');
+const { glKernelString } = require('../gl/kernel-string');
+const { lookupKernelValueType } = require('./kernel-value-maps');
+
+let isSupported = null;
+/**
+ *
+ * @type {HTMLCanvasElement|OffscreenCanvas|null}
+ */
+let testCanvas = null;
+/**
+ *
+ * @type {WebGLRenderingContext|null}
+ */
+let testContext = null;
+let testExtensions = null;
+let features = null;
+
+const plugins = [mrud];
const canvases = [];
const maxTexSizes = {};
-module.exports = class WebGLKernel extends KernelBase {
-
- /**
- * @constructor WebGLKernel
- *
- * @desc Kernel Implementation for WebGL.
- * This builds the shaders and runs them on the GPU,
- * the outputs the result back as float(enabled by default) and Texture.
- *
- * @extends KernelBase
- *
- * @prop {Object} textureCache - webGl Texture cache
- * @prop {Object} threadDim - The thread dimensions, x, y and z
- * @prop {Object} programUniformLocationCache - Location of program variables in memory
- * @prop {Object} framebuffer - Webgl frameBuffer
- * @prop {Object} buffer - WebGL buffer
- * @prop {Object} program - The webGl Program
- * @prop {Object} functionBuilder - Function Builder instance bound to this Kernel
- * @prop {Boolean} outputToTexture - Set output type to Texture, instead of float
- * @prop {String} endianness - Endian information like Little-endian, Big-endian.
- * @prop {Array} paramTypes - Types of parameters sent to the Kernel
- * @prop {number} argumentsLength - Number of parameters sent to the Kernel
- * @prop {String} compiledFragShaderString - Compiled fragment shader string
- * @prop {String} compiledVertShaderString - Compiled Vertical shader string
- */
- constructor(fnString, settings) {
- super(fnString, settings);
- this.textureCache = {};
- this.threadDim = {};
- this.programUniformLocationCache = {};
- this.framebuffer = null;
-
- this.buffer = null;
- this.program = null;
- this.outputToTexture = settings.outputToTexture;
- this.endianness = utils.systemEndianness();
- this.subKernelOutputTextures = null;
- this.subKernelOutputVariableNames = null;
- this.argumentsLength = 0;
- this.ext = null;
- this.compiledFragShaderString = null;
- this.compiledVertShaderString = null;
- this.extDrawBuffersMap = null;
- this.outputTexture = null;
- this.maxTexSize = null;
- if (!this._webGl) this._webGl = utils.initWebGl(this.getCanvas());
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name validateOptions
- *
- * @desc Validate options related to Kernel, such as
- * floatOutputs and Textures, texSize, output,
- * graphical output.
- *
- */
- validateOptions() {
- const isReadPixel = utils.isFloatReadPixelsSupported();
- if (this.floatTextures === true && !utils.OES_texture_float) {
- throw 'Float textures are not supported on this browser';
- } else if (this.floatOutput === true && this.floatOutputForce !== true && !isReadPixel) {
- throw 'Float texture outputs are not supported on this browser';
- } else if (this.floatTextures === null && !isReadPixel && !this.graphical) {
- //NOTE: handle
- this.floatTextures = true;
- this.floatOutput = false;
- }
-
- if (!this.output || this.output.length === 0) {
- if (arguments.length !== 1) {
- throw 'Auto output only supported for kernels with only one input';
- }
-
- const argType = utils.getArgumentType(arguments[0]);
- if (argType === 'Array') {
- this.output = utils.getDimensions(argType);
- } else if (argType === 'Texture') {
- this.output = arguments[0].output;
- } else {
- throw 'Auto output not supported for input type: ' + argType;
- }
- }
-
- this.texSize = utils.dimToTexSize({
- floatTextures: this.floatTextures,
- floatOutput: this.floatOutput
- }, this.output, true);
-
- if (this.graphical) {
- if (this.output.length !== 2) {
- throw 'Output must have 2 dimensions on graphical mode';
- }
-
- if (this.floatOutput) {
- throw 'Cannot use graphical mode and float output at the same time';
- }
-
- this.texSize = utils.clone(this.output);
- } else if (this.floatOutput === undefined && utils.OES_texture_float) {
- this.floatOutput = true;
- }
- }
-
- updateMaxTexSize() {
- const texSize = this.texSize;
- const canvas = this._canvas;
- if (this.maxTexSize === null) {
- let canvasIndex = canvases.indexOf(canvas);
- if (canvasIndex === -1) {
- canvasIndex = canvases.length;
- canvases.push(canvas);
- maxTexSizes[canvasIndex] = [texSize[0], texSize[1]];
- }
- this.maxTexSize = maxTexSizes[canvasIndex];
- }
- if (this.maxTexSize[0] < texSize[0]) {
- this.maxTexSize[0] = texSize[0];
- }
- if (this.maxTexSize[1] < texSize[1]) {
- this.maxTexSize[1] = texSize[1];
- }
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name build
- *
- * @desc Builds the Kernel, by compiling Fragment and Vertical Shaders,
- * and instantiates the program.
- *
- */
-
- build() {
- this.validateOptions();
- this.setupParams(arguments);
- this.updateMaxTexSize();
- const texSize = this.texSize;
- const gl = this._webGl;
- const canvas = this._canvas;
- gl.enable(gl.SCISSOR_TEST);
- gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);
- canvas.width = this.maxTexSize[0];
- canvas.height = this.maxTexSize[1];
- const threadDim = this.threadDim = utils.clone(this.output);
- while (threadDim.length < 3) {
- threadDim.push(1);
- }
-
- if (this.functionBuilder) this._addKernels();
-
- const compiledVertShaderString = this._getVertShaderString(arguments);
- const vertShader = gl.createShader(gl.VERTEX_SHADER);
- gl.shaderSource(vertShader, compiledVertShaderString);
- gl.compileShader(vertShader);
-
- const compiledFragShaderString = this._getFragShaderString(arguments);
- const fragShader = gl.createShader(gl.FRAGMENT_SHADER);
- gl.shaderSource(fragShader, compiledFragShaderString);
- gl.compileShader(fragShader);
-
- if (!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) {
- console.log(compiledVertShaderString);
- console.error('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(vertShader));
- throw 'Error compiling vertex shader';
- }
- if (!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) {
- console.log(compiledFragShaderString);
- console.error('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(fragShader));
- throw 'Error compiling fragment shader';
- }
-
- if (this.debug) {
- console.log('Options:');
- console.dir(this);
- console.log('GLSL Shader Output:');
- console.log(compiledFragShaderString);
- }
-
- const program = this.program = gl.createProgram();
- gl.attachShader(program, vertShader);
- gl.attachShader(program, fragShader);
- gl.linkProgram(program);
- this.framebuffer = gl.createFramebuffer();
- this.framebuffer.width = texSize[0];
- this.framebuffer.height = texSize[1];
-
- const vertices = new Float32Array([-1, -1,
- 1, -1, -1, 1,
- 1, 1
- ]);
- const texCoords = new Float32Array([
- 0, 0,
- 1, 0,
- 0, 1,
- 1, 1
- ]);
-
- const texCoordOffset = vertices.byteLength;
-
- let buffer = this.buffer;
- if (!buffer) {
- buffer = this.buffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
- gl.bufferData(gl.ARRAY_BUFFER, vertices.byteLength + texCoords.byteLength, gl.STATIC_DRAW);
- } else {
- gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
- }
-
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices);
- gl.bufferSubData(gl.ARRAY_BUFFER, texCoordOffset, texCoords);
-
- const aPosLoc = gl.getAttribLocation(this.program, 'aPos');
- gl.enableVertexAttribArray(aPosLoc);
- gl.vertexAttribPointer(aPosLoc, 2, gl.FLOAT, gl.FALSE, 0, 0);
- const aTexCoordLoc = gl.getAttribLocation(this.program, 'aTexCoord');
- gl.enableVertexAttribArray(aTexCoordLoc);
- gl.vertexAttribPointer(aTexCoordLoc, 2, gl.FLOAT, gl.FALSE, 0, texCoordOffset);
-
- this.setupOutputTexture();
-
- if (this.subKernelOutputTextures !== null) {
- const extDrawBuffersMap = this.extDrawBuffersMap = [gl.COLOR_ATTACHMENT0];
- for (let i = 0; i < this.subKernelOutputTextures.length; i++) {
- const subKernelOutputTexture = this.subKernelOutputTextures[i];
- extDrawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1);
- gl.activeTexture(gl.TEXTURE0 + arguments.length + i);
- gl.bindTexture(gl.TEXTURE_2D, subKernelOutputTexture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
- if (this.floatOutput) {
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);
- } else {
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
- }
- }
- }
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name run
- *
- * @desc Run the kernel program, and send the output to renderOutput
- *
- * This method calls a helper method *renderOutput* to return the result.
- *
- * @returns {Object} Result The final output of the program, as float, and as Textures for reuse.
- *
- *
- */
- run() {
- if (this.program === null) {
- this.build.apply(this, arguments);
- }
- const paramNames = this.paramNames;
- const paramTypes = this.paramTypes;
- const texSize = this.texSize;
- const gl = this._webGl;
-
- gl.useProgram(this.program);
- gl.scissor(0, 0, texSize[0], texSize[1]);
-
- if (!this.hardcodeConstants) {
- const uOutputDimLoc = this.getUniformLocation('uOutputDim');
- gl.uniform3fv(uOutputDimLoc, this.threadDim);
- const uTexSizeLoc = this.getUniformLocation('uTexSize');
- gl.uniform2fv(uTexSizeLoc, texSize);
- }
-
- const ratioLoc = this.getUniformLocation('ratio');
- gl.uniform2f(ratioLoc, texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]);
-
- this.argumentsLength = 0;
- for (let texIndex = 0; texIndex < paramNames.length; texIndex++) {
- this._addArgument(arguments[texIndex], paramTypes[texIndex], paramNames[texIndex]);
- }
-
- if (this.graphical) {
- gl.bindRenderbuffer(gl.RENDERBUFFER, null);
- gl.bindFramebuffer(gl.FRAMEBUFFER, null);
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
- return;
- }
-
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
- //the call to this._addArgument may rewrite the outputTexture, keep this here
- const outputTexture = this.outputTexture;
- gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, outputTexture, 0);
-
- if (this.subKernelOutputTextures !== null) {
- for (let i = 0; i < this.subKernelOutputTextures.length; i++) {
- const subKernelOutputTexture = this.subKernelOutputTextures[i];
- gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, subKernelOutputTexture, 0);
- }
- this.ext.drawBuffersWEBGL(this.extDrawBuffersMap);
- }
-
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
-
- if (this.subKernelOutputTextures !== null) {
- if (this.subKernels !== null) {
- const output = [];
- output.result = this.renderOutput(outputTexture);
- for (let i = 0; i < this.subKernels.length; i++) {
- output.push(new Texture(this.subKernelOutputTextures[i], texSize, this.output, this._webGl));
- }
- return output;
- } else if (this.subKernelProperties !== null) {
- const output = {
- result: this.renderOutput(outputTexture)
- };
- let i = 0;
- for (let p in this.subKernelProperties) {
- if (!this.subKernelProperties.hasOwnProperty(p)) continue;
- output[p] = new Texture(this.subKernelOutputTextures[i], texSize, this.output, this._webGl);
- i++;
- }
- return output;
- }
- }
-
- return this.renderOutput(outputTexture);
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name renderOutput
- *
- *
- * @desc Helper function to return webGl function's output.
- * Since the program runs on GPU, we need to get the
- * output of the program back to CPU and then return them.
- *
- * *Note*: This should not be called directly.
- *
- * @param {Object} outputTexture - Output Texture returned by webGl program
- *
- * @returns {Object|Array} result
- *
- *
- */
- renderOutput(outputTexture) {
- const texSize = this.texSize;
- const gl = this._webGl;
- const threadDim = this.threadDim;
- const output = this.output;
- if (this.outputToTexture) {
- return new Texture(outputTexture, texSize, output, this._webGl);
- } else {
- let result;
- if (this.floatOutput) {
- result = new Float32Array(texSize[0] * texSize[1] * 4);
- gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.FLOAT, result);
- } else {
- const bytes = new Uint8Array(texSize[0] * texSize[1] * 4);
- gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, bytes);
- result = new Float32Array(bytes.buffer);
- }
-
- result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]);
-
- if (output.length === 1) {
- return result;
- } else if (output.length === 2) {
- return utils.splitArray(result, output[0]);
- } else if (output.length === 3) {
- const cube = utils.splitArray(result, output[0] * output[1]);
- return cube.map(function(x) {
- return utils.splitArray(x, output[0]);
- });
- }
- }
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name getOutputTexture
- *
- * @desc This uses *getTextureCache* to get the Texture Cache of the Output
- *
- * @returns {Object} Ouptut Texture Cache
- *
- */
- getOutputTexture() {
- return this.getTextureCache('OUTPUT');
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name detachOutputTexture
- *
- * @desc Detaches output texture
- *
- *
- */
- detachOutputTexture() {
- this.detachTextureCache('OUTPUT');
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name setupOutputTexture
- *
- * @desc Detaches a texture from cache if exists, and sets up output texture
- */
- setupOutputTexture() {
- const gl = this._webGl;
- const texSize = this.texSize;
- this.detachOutputTexture();
- this.outputTexture = this.getOutputTexture();
- gl.activeTexture(gl.TEXTURE0 + this.paramNames.length);
- gl.bindTexture(gl.TEXTURE_2D, this.outputTexture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
- if (this.floatOutput) {
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);
- } else {
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
- }
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name getArgumentTexture
- *
- * @desc This uses *getTextureCache** to get the Texture Cache of the argument supplied
- *
- * @param {String} name - Name of the argument
- *
- * Texture cache for the supplied argument
- *
- */
- getArgumentTexture(name) {
- return this.getTextureCache(`ARGUMENT_${ name }`);
- }
-
- /**
- * @memberOf WebGLKernel#
- * @name getSubKernelTexture
- * @function
- *
- * @desc This uses *getTextureCache* to get the Texture Cache of the sub-kernel
- *
- * @param {String} name - Name of the subKernel
- *
- * @returns {Object} Texture cache for the subKernel
- *
- */
- getSubKernelTexture(name) {
- return this.getTextureCache(`SUB_KERNEL_${ name }`);
- }
-
- /**
- * @memberOf WebGLKernel#
- * @name getTextureCache
- * @function
- *
- * @desc Returns the Texture Cache of the supplied parameter (can be kernel, sub-kernel or argument)
- *
- * @param {String} name - Name of the subkernel, argument, or kernel.
- *
- * @returns {Object} Texture cache
- *
- */
- getTextureCache(name) {
- if (this.outputToTexture) {
- // Don't retain a handle on the output texture, we might need to render on the same texture later
- return this._webGl.createTexture();
- }
- if (this.textureCache.hasOwnProperty(name)) {
- return this.textureCache[name];
- }
- return this.textureCache[name] = this._webGl.createTexture();
- }
-
- /**
- * @memberOf WebGLKernel#
- * @name detachTextureCache
- * @function
- * @desc removes a texture from the kernel's cache
- * @param {String} name - Name of texture
- */
- detachTextureCache(name) {
- delete this.textureCache[name];
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name getUniformLocation
- *
- * @desc Return WebGlUniformLocation for various variables
- * related to webGl program, such as user-defiend variables,
- * as well as, dimension sizes, etc.
- *
- */
- getUniformLocation(name) {
- let location = this.programUniformLocationCache[name];
- if (!location) {
- location = this._webGl.getUniformLocation(this.program, name);
- this.programUniformLocationCache[name] = location;
- }
- return location;
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getFragShaderArtifactMap
- *
- * @desc Generate Shader artifacts for the kernel program.
- * The final object contains HEADER, KERNEL, MAIN_RESULT, and others.
- *
- * @param {Array} args - The actual parameters sent to the Kernel
- *
- * @returns {Object} An object containing the Shader Artifacts(CONSTANTS, HEADER, KERNEL, etc.)
- *
- */
- _getFragShaderArtifactMap(args) {
- return {
- HEADER: this._getHeaderString(),
- LOOP_MAX: this._getLoopMaxString(),
- CONSTANTS: this._getConstantsString(),
- DECODE32_ENDIANNESS: this._getDecode32EndiannessString(),
- ENCODE32_ENDIANNESS: this._getEncode32EndiannessString(),
- GET_WRAPAROUND: this._getGetWraparoundString(),
- GET_TEXTURE_CHANNEL: this._getGetTextureChannelString(),
- GET_TEXTURE_INDEX: this._getGetTextureIndexString(),
- GET_RESULT: this._getGetResultString(),
- MAIN_PARAMS: this._getMainParamsString(args),
- MAIN_CONSTANTS: this._getMainConstantsString(),
- KERNEL: this._getKernelString(),
- MAIN_RESULT: this._getMainResultString()
- };
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _addArgument
- *
- * @desc Adds kernel parameters to the Argument Texture,
- * binding it to the webGl instance, etc.
- *
- * @param {Array|Texture|Number} value - The actual argument supplied to the kernel
- * @param {String} type - Type of the argument
- * @param {String} name - Name of the argument
- *
- */
- _addArgument(value, type, name) {
- const gl = this._webGl;
- const argumentTexture = this.getArgumentTexture(name);
- if (value instanceof Texture) {
- type = 'Texture';
- }
- switch (type) {
- case 'Array':
- {
- const dim = utils.getDimensions(value, true);
- const size = utils.dimToTexSize({
- floatTextures: this.floatTextures,
- floatOutput: this.floatOutput
- }, dim);
- gl.activeTexture(gl.TEXTURE0 + this.argumentsLength);
- gl.bindTexture(gl.TEXTURE_2D, argumentTexture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
-
- let length = size[0] * size[1];
- if (this.floatTextures) {
- length *= 4;
- }
-
- const valuesFlat = new Float32Array(length);
- utils.flattenTo(value, valuesFlat);
-
- let buffer;
- if (this.floatTextures) {
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size[0], size[1], 0, gl.RGBA, gl.FLOAT, valuesFlat);
- } else {
- buffer = new Uint8Array(valuesFlat.buffer);
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size[0], size[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, buffer);
- }
-
- const loc = this.getUniformLocation('user_' + name);
- const locSize = this.getUniformLocation('user_' + name + 'Size');
- const dimLoc = this.getUniformLocation('user_' + name + 'Dim');
-
- if (!this.hardcodeConstants) {
- gl.uniform3fv(dimLoc, dim);
- gl.uniform2fv(locSize, size);
- }
- gl.uniform1i(loc, this.argumentsLength);
- break;
- }
- case 'Number':
- {
- const loc = this.getUniformLocation('user_' + name);
- gl.uniform1f(loc, value);
- break;
- }
- case 'Input':
- {
- const input = value;
- const dim = input.size;
- const size = utils.dimToTexSize({
- floatTextures: this.floatTextures,
- floatOutput: this.floatOutput
- }, dim);
- gl.activeTexture(gl.TEXTURE0 + this.argumentsLength);
- gl.bindTexture(gl.TEXTURE_2D, argumentTexture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
-
- let length = size[0] * size[1];
- let inputArray;
- if (this.floatTextures) {
- length *= 4;
- inputArray = new Float32Array(length);
- inputArray.set(input.value);
- } else {
- inputArray = input.value;
- }
-
- if (this.floatTextures) {
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size[0], size[1], 0, gl.RGBA, gl.FLOAT, inputArray);
- } else {
- const buffer = new Uint8Array(inputArray.buffer);
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size[0], size[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, buffer);
- }
-
- const loc = this.getUniformLocation('user_' + name);
- const locSize = this.getUniformLocation('user_' + name + 'Size');
- const dimLoc = this.getUniformLocation('user_' + name + 'Dim');
-
- if (!this.hardcodeConstants) {
- gl.uniform3fv(dimLoc, dim);
- gl.uniform2fv(locSize, size);
- }
- gl.uniform1i(loc, this.argumentsLength);
- break;
- }
- case 'Texture':
- {
- const inputTexture = value;
- const dim = utils.getDimensions(inputTexture, true);
-
- const size = inputTexture.size;
-
- if (inputTexture.texture === this.outputTexture) {
- this.setupOutputTexture();
- }
-
- gl.activeTexture(gl.TEXTURE0 + this.argumentsLength);
- gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture);
-
- const loc = this.getUniformLocation('user_' + name);
- const locSize = this.getUniformLocation('user_' + name + 'Size');
- const dimLoc = this.getUniformLocation('user_' + name + 'Dim');
-
- gl.uniform3fv(dimLoc, dim);
- gl.uniform2fv(locSize, size);
- gl.uniform1i(loc, this.argumentsLength);
- break;
- }
- default:
- throw 'Input type not supported (WebGL): ' + value;
- }
- this.argumentsLength++;
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getHeaderString
- *
- * @desc Get the header string for the program.
- * This returns an empty string if no sub-kernels are defined.
- *
- * @returns {String} result
- *
- */
- _getHeaderString() {
- return (
- this.subKernels !== null || this.subKernelProperties !== null ?
- //webgl2 '#version 300 es\n' :
- '#extension GL_EXT_draw_buffers : require\n' :
- ''
- );
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getLoopMaxString
- *
- * @desc Get the maximum loop size String.
- *
- * @returns {String} result
- *
- */
- _getLoopMaxString() {
- return (
- this.loopMaxIterations ?
- ` ${ parseInt(this.loopMaxIterations) }.0;\n` :
- ' 1000.0;\n'
- );
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getConstantsString
- *
- * @desc Generate transpiled glsl Strings for constant parameters sent to a kernel
- *
- * They can be defined by *hardcodeConstants*
- *
- * @returns {String} result
- *
- */
- _getConstantsString() {
- const result = [];
- const threadDim = this.threadDim;
- const texSize = this.texSize;
- if (this.hardcodeConstants) {
- result.push(
- `highp vec3 uOutputDim = vec3(${ threadDim[0] },${ threadDim[1] }, ${ threadDim[2] })`,
- `highp vec2 uTexSize = vec2(${ texSize[0] }, ${ texSize[1] })`
- );
- } else {
- result.push(
- 'uniform highp vec3 uOutputDim',
- 'uniform highp vec2 uTexSize'
- );
- }
-
- return this._linesToString(result);
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getTextureCoordinate
- *
- * @desc Get texture coordinate string for the program
- *
- * @returns {String} result
- *
- */
- _getTextureCoordinate() {
- const names = this.subKernelOutputVariableNames;
- if (names === null || names.length < 1) {
- return 'varying highp vec2 vTexCoord;\n';
- } else {
- return 'out highp vec2 vTexCoord;\n';
- }
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getDecode32EndiannessString
- *
- * @desc Get Decode32 endianness string for little-endian and big-endian
- *
- * @returns {String} result
- *
- */
- _getDecode32EndiannessString() {
- return (
- this.endianness === 'LE' ?
- '' :
- ' rgba.rgba = rgba.abgr;\n'
- );
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getEncode32EndiannessString
- *
- * @desc Get Encode32 endianness string for little-endian and big-endian
- *
- * @returns {String} result
- *
- */
- _getEncode32EndiannessString() {
- return (
- this.endianness === 'LE' ?
- '' :
- ' rgba.rgba = rgba.abgr;\n'
- );
- }
-
- /**
- * @function
- * @memberOf WebGLKernel#
- * @name _getGetWraparoundString
- *
- * @returns {String} wraparound string
- */
- _getGetWraparoundString() {
- return (
- this.wraparound ?
- ' xyz = mod(xyz, texDim);\n' :
- ''
- );
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getGetTextureChannelString
- *
- */
- _getGetTextureChannelString() {
- if (!this.floatTextures) return '';
-
- return this._linesToString([
- ' int channel = int(integerMod(index, 4.0))',
- ' index = float(int(index) / 4)'
- ]);
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getGetTextureIndexString
- *
- * @desc Get generic texture index string, if floatTextures flag is true.
- *
- * @example
- * ' index = float(int(index)/4);\n'
- *
- */
- _getGetTextureIndexString() {
- return (
- this.floatTextures ?
- ' index = float(int(index)/4);\n' :
- ''
- );
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getGetResultString
- *
- */
- _getGetResultString() {
- if (!this.floatTextures) return ' return decode32(texel);\n';
- return this._linesToString([
- ' if (channel == 0) return texel.r',
- ' if (channel == 1) return texel.g',
- ' if (channel == 2) return texel.b',
- ' if (channel == 3) return texel.a'
- ]);
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getMainParamsString
- *
- * @desc Generate transpiled glsl Strings for user-defined parameters sent to a kernel
- *
- * @param {Array} args - The actual parameters sent to the Kernel
- *
- * @returns {String} result
- *
- */
- _getMainParamsString(args) {
- const result = [];
- const paramTypes = this.paramTypes;
- const paramNames = this.paramNames;
- for (let i = 0; i < paramNames.length; i++) {
- const param = args[i];
- const paramName = paramNames[i];
- const paramType = paramTypes[i];
- if (this.hardcodeConstants) {
- if (paramType === 'Array' || paramType === 'Texture') {
- const paramDim = utils.getDimensions(param, true);
- const paramSize = utils.dimToTexSize({
- floatTextures: this.floatTextures,
- floatOutput: this.floatOutput
- }, paramDim);
-
- result.push(
- `uniform highp sampler2D user_${ paramName }`,
- `highp vec2 user_${ paramName }Size = vec2(${ paramSize[0] }.0, ${ paramSize[1] }.0)`,
- `highp vec3 user_${ paramName }Dim = vec3(${ paramDim[0] }.0, ${ paramDim[1]}.0, ${ paramDim[2] }.0)`
- );
- } else if (paramType === 'Number' && Number.isInteger(param)) {
- result.push(`highp float user_${ paramName } = ${ param }.0`);
- } else if (paramType === 'Number') {
- result.push(`highp float user_${ paramName } = ${ param }`);
- }
- } else {
- if (paramType === 'Array' || paramType === 'Texture' || paramType === 'Input') {
- result.push(
- `uniform highp sampler2D user_${ paramName }`,
- `uniform highp vec2 user_${ paramName }Size`,
- `uniform highp vec3 user_${ paramName }Dim`
- );
- } else if (paramType === 'Number') {
- result.push(`uniform highp float user_${ paramName }`);
- }
- }
- }
- return this._linesToString(result);
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getMainConstantsString
- *
- */
- _getMainConstantsString() {
- const result = [];
- if (this.constants) {
- for (let name in this.constants) {
- if (!this.constants.hasOwnProperty(name)) continue;
- let value = parseFloat(this.constants[name]);
-
- if (Number.isInteger(value)) {
- result.push('const float constants_' + name + ' = ' + parseInt(value) + '.0');
- } else {
- result.push('const float constants_' + name + ' = ' + parseFloat(value));
- }
- }
- }
- return this._linesToString(result);
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getKernelString
- *
- * @desc Get Kernel program string (in *glsl*) for a kernel.
- *
- * @returns {String} result
- *
- */
- _getKernelString() {
- const result = [];
- const names = this.subKernelOutputVariableNames;
- if (names !== null) {
- result.push('highp float kernelResult = 0.0');
- for (let i = 0; i < names.length; i++) {
- result.push(
- `highp float ${ names[i] } = 0.0`
- );
- }
-
- /* this is v2 prep
- result.push('highp float kernelResult = 0.0');
- result.push('layout(location = 0) out highp float fradData0 = 0.0');
- for (let i = 0; i < names.length; i++) {
- result.push(
- `highp float ${ names[i] } = 0.0`,
- `layout(location = ${ i + 1 }) out highp float fragData${ i + 1 } = 0.0`
+
+
+/**
+ * @desc Kernel Implementation for WebGL.
+ * This builds the shaders and runs them on the GPU,
+ * the outputs the result back as float(enabled by default) and Texture.
+ *
+ * @property {WebGLTexture[]} textureCache - webGl Texture cache
+ * @property {Object.} programUniformLocationCache - Location of program variables in memory
+ * @property {WebGLFramebuffer} framebuffer - Webgl frameBuffer
+ * @property {WebGLBuffer} buffer - WebGL buffer
+ * @property {WebGLProgram} program - The webGl Program
+ * @property {FunctionBuilder} functionBuilder - Function Builder instance bound to this Kernel
+ * @property {Boolean} pipeline - Set output type to FAST mode (GPU to GPU via Textures), instead of float
+ * @property {string} endianness - Endian information like Little-endian, Big-endian.
+ * @property {string[]} argumentTypes - Types of parameters sent to the Kernel
+ * @property {string|null} compiledFragmentShader - Compiled fragment shader string
+ * @property {string|null} compiledVertexShader - Compiled Vertical shader string
+ * @extends GLKernel
+ */
+class WebGLKernel extends GLKernel {
+ static get isSupported() {
+ if (isSupported !== null) {
+ return isSupported;
+ }
+ this.setupFeatureChecks();
+ isSupported = this.isContextMatch(testContext);
+ return isSupported;
+ }
+
+ static setupFeatureChecks() {
+ if (typeof document !== 'undefined') {
+ testCanvas = document.createElement('canvas');
+ } else if (typeof OffscreenCanvas !== 'undefined') {
+ testCanvas = new OffscreenCanvas(0, 0);
+ }
+ if (!testCanvas) return;
+ testContext = testCanvas.getContext('webgl') || testCanvas.getContext('experimental-webgl');
+ if (!testContext || !testContext.getExtension) return;
+ testExtensions = {
+ OES_texture_float: testContext.getExtension('OES_texture_float'),
+ OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'),
+ OES_element_index_uint: testContext.getExtension('OES_element_index_uint'),
+ WEBGL_draw_buffers: testContext.getExtension('WEBGL_draw_buffers'),
+ };
+ features = this.getFeatures();
+ }
+
+ static isContextMatch(context) {
+ if (typeof WebGLRenderingContext !== 'undefined') {
+ return context instanceof WebGLRenderingContext;
+ }
+ return false;
+ }
+
+ static getIsTextureFloat() {
+ return Boolean(testExtensions.OES_texture_float);
+ }
+
+ static getIsDrawBuffers() {
+ return Boolean(testExtensions.WEBGL_draw_buffers);
+ }
+
+ static getChannelCount() {
+ return testExtensions.WEBGL_draw_buffers ?
+ testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) :
+ 1;
+ }
+
+ static getMaxTextureSize() {
+ return testContext.getParameter(testContext.MAX_TEXTURE_SIZE);
+ }
+
+ /**
+ *
+ * @param type
+ * @param dynamic
+ * @param precision
+ * @param value
+ * @returns {KernelValue}
+ */
+ static lookupKernelValueType(type, dynamic, precision, value) {
+ return lookupKernelValueType(type, dynamic, precision, value);
+ }
+
+ static get testCanvas() {
+ return testCanvas;
+ }
+
+ static get testContext() {
+ return testContext;
+ }
+
+ static get features() {
+ return features;
+ }
+
+ static get fragmentShader() {
+ return fragmentShader;
+ }
+
+ static get vertexShader() {
+ return vertexShader;
+ }
+
+ /**
+ *
+ * @param {String|IKernelJSON} source
+ * @param {IDirectKernelSettings} settings
+ */
+ constructor(source, settings) {
+ super(source, settings);
+ this.program = null;
+ this.pipeline = settings.pipeline;
+ this.endianness = utils.systemEndianness();
+ this.extensions = {};
+ this.argumentTextureCount = 0;
+ this.constantTextureCount = 0;
+ this.fragShader = null;
+ this.vertShader = null;
+ this.drawBuffersMap = null;
+
+ /**
+ *
+ * @type {Int32Array|null}
+ */
+ this.maxTexSize = null;
+ this.onRequestSwitchKernel = null;
+
+ this.texture = null;
+ this.mappedTextures = null;
+ this.mergeSettings(source.settings || settings);
+
+ /**
+ * The thread dimensions, x, y and z
+ * @type {Array|null}
+ */
+ 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 (typeof document !== 'undefined') {
+ const canvas = document.createElement('canvas');
+ // Default width and height, to fix webgl issue in safari
+ canvas.width = 2;
+ canvas.height = 2;
+ return canvas;
+ } else if (typeof OffscreenCanvas !== 'undefined') {
+ return new OffscreenCanvas(0, 0);
+ }
+ }
+
+ /**
+ *
+ * @return {WebGLRenderingContext}
+ */
+ initContext() {
+ const settings = {
+ alpha: false,
+ depth: false,
+ antialias: false
+ };
+ return this.canvas.getContext('webgl', settings) || this.canvas.getContext('experimental-webgl', settings);
+ }
+
+ /**
+ *
+ * @param {IDirectKernelSettings} settings
+ * @return {string[]}
+ */
+ initPlugins(settings) {
+ // default plugins
+ const pluginsToUse = [];
+ const { source } = this;
+ if (typeof source === 'string') {
+ for (let i = 0; i < plugins.length; i++) {
+ const plugin = plugins[i];
+ if (source.match(plugin.functionMatch)) {
+ pluginsToUse.push(plugin);
+ }
+ }
+ } else if (typeof source === 'object') {
+ // `source` is from object, json
+ if (settings.pluginNames) { //TODO: in context of JSON support, pluginNames may not exist here
+ for (let i = 0; i < plugins.length; i++) {
+ const plugin = plugins[i];
+ const usePlugin = settings.pluginNames.some(pluginName => pluginName === plugin.name);
+ if (usePlugin) {
+ pluginsToUse.push(plugin);
+ }
+ }
+ }
+ }
+ return pluginsToUse;
+ }
+
+ 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'),
+ };
+ }
+
+ /**
+ * @desc Validate settings related to Kernel, such as dimensions size, and auto output support.
+ * @param {IArguments} args
+ */
+ validateSettings(args) {
+ if (!this.validate) {
+ this.texSize = utils.getKernelTextureSize({
+ optimizeFloatMemory: this.optimizeFloatMemory,
+ precision: this.precision,
+ }, this.output);
+ return;
+ }
+
+ const { features } = this.constructor;
+
+ if (this.optimizeFloatMemory === true && !features.isTextureFloat) {
+ throw new Error('Float textures are not supported');
+ } else if (this.precision === 'single' && !features.isFloatRead) {
+ throw new Error('Single precision not supported');
+ } else if (!this.graphical && this.precision === null && features.isTextureFloat) {
+ this.precision = features.isFloatRead ? 'single' : 'unsigned';
+ }
+
+ if (this.subKernels && this.subKernels.length > 0 && !this.extensions.WEBGL_draw_buffers) {
+ throw new Error('could not instantiate draw buffers extension');
+ }
+
+ if (this.fixIntegerDivisionAccuracy === null) {
+ this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate;
+ } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) {
+ this.fixIntegerDivisionAccuracy = false;
+ }
+
+ this.checkOutput();
+
+ 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);
+ switch (argType) {
+ case 'Array':
+ this.output = utils.getDimensions(argType);
+ break;
+ case 'NumberTexture':
+ case 'MemoryOptimizedNumberTexture':
+ case 'ArrayTexture(1)':
+ case 'ArrayTexture(2)':
+ case 'ArrayTexture(3)':
+ case 'ArrayTexture(4)':
+ this.output = args[0].output;
+ break;
+ default:
+ throw new Error('Auto output not supported for input type: ' + argType);
+ }
+ }
+
+ if (this.graphical) {
+ if (this.output.length !== 2) {
+ throw new Error('Output must have 2 dimensions on graphical mode');
+ }
+
+ if (this.precision === 'precision') {
+ this.precision = 'unsigned';
+ console.warn('Cannot use graphical mode and single precision at the same time');
+ }
+
+ this.texSize = utils.clone(this.output);
+ return;
+ } else if (this.precision === null && features.isTextureFloat) {
+ this.precision = 'single';
+ }
+
+ this.texSize = utils.getKernelTextureSize({
+ optimizeFloatMemory: this.optimizeFloatMemory,
+ precision: this.precision,
+ }, this.output);
+
+ this.checkTextureSize();
+ }
+
+ updateMaxTexSize() {
+ const { texSize, canvas } = this;
+ if (this.maxTexSize === null) {
+ let canvasIndex = canvases.indexOf(canvas);
+ if (canvasIndex === -1) {
+ canvasIndex = canvases.length;
+ canvases.push(canvas);
+ maxTexSizes[canvasIndex] = [texSize[0], texSize[1]];
+ }
+ this.maxTexSize = maxTexSizes[canvasIndex];
+ }
+ if (this.maxTexSize[0] < texSize[0]) {
+ this.maxTexSize[0] = texSize[0];
+ }
+ if (this.maxTexSize[1] < texSize[1]) {
+ this.maxTexSize[1] = texSize[1];
+ }
+ }
+
+ setupArguments(args) {
+ this.kernelArguments = [];
+ this.argumentTextureCount = 0;
+ const needsArgumentTypes = this.argumentTypes === null;
+ // TODO: remove
+ if (needsArgumentTypes) {
+ this.argumentTypes = [];
+ }
+ this.argumentSizes = [];
+ this.argumentBitRatios = [];
+ // TODO: end remove
+
+ if (args.length < this.argumentNames.length) {
+ throw new Error('not enough arguments for kernel');
+ } else if (args.length > this.argumentNames.length) {
+ throw new Error('too many arguments for kernel');
+ }
+
+ const { context: gl } = this;
+ let textureIndexes = 0;
+
+ const onRequestTexture = () => {
+ return this.createTexture();
+ };
+ const onRequestIndex = () => {
+ return this.constantTextureCount + textureIndexes++;
+ };
+ const onUpdateValueMismatch = (constructor) => {
+ this.switchKernels({
+ type: 'argumentMismatch',
+ needed: constructor
+ });
+ };
+ const onRequestContextHandle = () => {
+ return gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount++;
+ };
+
+ for (let index = 0; index < args.length; index++) {
+ const value = args[index];
+ const name = this.argumentNames[index];
+ let type;
+ if (needsArgumentTypes) {
+ type = utils.getVariableType(value, this.strictIntegers);
+ this.argumentTypes.push(type);
+ } else {
+ type = this.argumentTypes[index];
+ }
+ const KernelValue = this.constructor.lookupKernelValueType(type, this.dynamicArguments ? 'dynamic' : 'static', this.precision, args[index]);
+ if (KernelValue === null) {
+ return this.requestFallback(args);
+ }
+ const kernelArgument = new KernelValue(value, {
+ name,
+ type,
+ tactic: this.tactic,
+ origin: 'user',
+ context: gl,
+ checkContext: this.checkContext,
+ kernel: this,
+ strictIntegers: this.strictIntegers,
+ onRequestTexture,
+ onRequestIndex,
+ onUpdateValueMismatch,
+ onRequestContextHandle,
+ });
+ this.kernelArguments.push(kernelArgument);
+ kernelArgument.setup();
+ this.argumentSizes.push(kernelArgument.textureSize);
+ this.argumentBitRatios[index] = kernelArgument.bitRatio;
+ }
+ }
+
+ createTexture() {
+ const texture = this.context.createTexture();
+ this.textureCache.push(texture);
+ return texture;
+ }
+
+ setupConstants(args) {
+ const { context: gl } = this;
+ this.kernelConstants = [];
+ this.forceUploadKernelConstants = [];
+ let needsConstantTypes = this.constantTypes === null;
+ if (needsConstantTypes) {
+ this.constantTypes = {};
+ }
+ this.constantBitRatios = {};
+ let textureIndexes = 0;
+ for (const name in this.constants) {
+ const value = this.constants[name];
+ let type;
+ if (needsConstantTypes) {
+ type = utils.getVariableType(value, this.strictIntegers);
+ this.constantTypes[name] = type;
+ } else {
+ type = this.constantTypes[name];
+ }
+ const KernelValue = this.constructor.lookupKernelValueType(type, 'static', this.precision, value);
+ if (KernelValue === null) {
+ return this.requestFallback(args);
+ }
+ const kernelValue = new KernelValue(value, {
+ name,
+ type,
+ tactic: this.tactic,
+ origin: 'constants',
+ context: this.context,
+ checkContext: this.checkContext,
+ kernel: this,
+ strictIntegers: this.strictIntegers,
+ onRequestTexture: () => {
+ return this.createTexture();
+ },
+ onRequestIndex: () => {
+ return textureIndexes++;
+ },
+ onRequestContextHandle: () => {
+ return gl.TEXTURE0 + this.constantTextureCount++;
+ }
+ });
+ this.constantBitRatios[name] = kernelValue.bitRatio;
+ this.kernelConstants.push(kernelValue);
+ kernelValue.setup();
+ if (kernelValue.forceUploadEachRun) {
+ this.forceUploadKernelConstants.push(kernelValue);
+ }
+ }
+ }
+
+ build() {
+ if (this.built) return;
+ this.initExtensions();
+ this.validateSettings(arguments);
+ this.setupConstants(arguments);
+ if (this.fallbackRequested) return;
+ this.setupArguments(arguments);
+ if (this.fallbackRequested) return;
+ this.updateMaxTexSize();
+ this.translateSource();
+ const failureResult = this.pickRenderStrategy(arguments);
+ if (failureResult) {
+ return failureResult;
+ }
+ const { texSize, context: gl, canvas } = this;
+ gl.enable(gl.SCISSOR_TEST);
+ if (this.pipeline && this.precision === 'single') {
+ gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);
+ canvas.width = this.maxTexSize[0];
+ canvas.height = this.maxTexSize[1];
+ } else {
+ gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);
+ canvas.width = this.maxTexSize[0];
+ canvas.height = this.maxTexSize[1];
+ }
+ const threadDim = this.threadDim = Array.from(this.output);
+ while (threadDim.length < 3) {
+ threadDim.push(1);
+ }
+
+ const compiledVertexShader = this.getVertexShader(arguments);
+ const vertShader = gl.createShader(gl.VERTEX_SHADER);
+ gl.shaderSource(vertShader, compiledVertexShader);
+ gl.compileShader(vertShader);
+ this.vertShader = vertShader;
+
+ const compiledFragmentShader = this.getFragmentShader(arguments);
+ const fragShader = gl.createShader(gl.FRAGMENT_SHADER);
+ gl.shaderSource(fragShader, compiledFragmentShader);
+ gl.compileShader(fragShader);
+ this.fragShader = fragShader;
+
+ if (this.debug) {
+ console.log('GLSL Shader Output:');
+ console.log(compiledFragmentShader);
+ }
+
+ if (!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) {
+ throw new Error('Error compiling vertex shader: ' + gl.getShaderInfoLog(vertShader));
+ }
+ if (!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) {
+ throw new Error('Error compiling fragment shader: ' + gl.getShaderInfoLog(fragShader));
+ }
+
+ const program = this.program = gl.createProgram();
+ gl.attachShader(program, vertShader);
+ gl.attachShader(program, fragShader);
+ gl.linkProgram(program);
+ this.framebuffer = gl.createFramebuffer();
+ this.framebuffer.width = texSize[0];
+ this.framebuffer.height = texSize[1];
+ this.rawValueFramebuffers = {};
+
+ const vertices = new Float32Array([-1, -1,
+ 1, -1, -1, 1,
+ 1, 1
+ ]);
+ const texCoords = new Float32Array([
+ 0, 0,
+ 1, 0,
+ 0, 1,
+ 1, 1
+ ]);
+
+ const texCoordOffset = vertices.byteLength;
+
+ let buffer = this.buffer;
+ if (!buffer) {
+ buffer = this.buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, vertices.byteLength + texCoords.byteLength, gl.STATIC_DRAW);
+ } else {
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ }
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices);
+ gl.bufferSubData(gl.ARRAY_BUFFER, texCoordOffset, texCoords);
+
+ const aPosLoc = gl.getAttribLocation(this.program, 'aPos');
+ gl.enableVertexAttribArray(aPosLoc);
+ gl.vertexAttribPointer(aPosLoc, 2, gl.FLOAT, false, 0, 0);
+ const aTexCoordLoc = gl.getAttribLocation(this.program, 'aTexCoord');
+ gl.enableVertexAttribArray(aTexCoordLoc);
+ gl.vertexAttribPointer(aTexCoordLoc, 2, gl.FLOAT, false, 0, texCoordOffset);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
+
+ let i = 0;
+ gl.useProgram(this.program);
+ for (let p in this.constants) {
+ this.kernelConstants[i++].updateValue(this.constants[p]);
+ }
+
+ this._setupOutputTexture();
+ if (
+ this.subKernels !== null &&
+ this.subKernels.length > 0
+ ) {
+ this._mappedTextureSwitched = {};
+ this._setupSubOutputTextures();
+ }
+ this.buildSignature(arguments);
+ this.built = true;
+ }
+
+ translateSource() {
+ const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, {
+ fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy
+ });
+ this.translatedSource = functionBuilder.getPrototypeString('kernel');
+ this.setupReturnTypes(functionBuilder);
+ }
+
+ setupReturnTypes(functionBuilder) {
+ if (!this.graphical && !this.returnType) {
+ this.returnType = functionBuilder.getKernelResultType();
+ }
+
+ if (this.subKernels && this.subKernels.length > 0) {
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const subKernel = this.subKernels[i];
+ if (!subKernel.returnType) {
+ subKernel.returnType = functionBuilder.getSubKernelResultType(i);
+ }
+ }
+ }
+ }
+
+ run() {
+ const { kernelArguments, texSize, forceUploadKernelConstants, context: gl } = this;
+
+ gl.useProgram(this.program);
+ gl.scissor(0, 0, texSize[0], texSize[1]);
+ if (this.dynamicOutput) {
+ this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim));
+ this.setUniform2iv('uTexSize', texSize);
+ }
+
+ this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]);
+
+ for (let i = 0; i < forceUploadKernelConstants.length; i++) {
+ const constant = forceUploadKernelConstants[i];
+ constant.updateValue(this.constants[constant.name]);
+ if (this.switchingKernels) return;
+ }
+ for (let i = 0; i < kernelArguments.length; i++) {
+ kernelArguments[i].updateValue(arguments[i]);
+ if (this.switchingKernels) return;
+ }
+
+ if (this.plugins) {
+ for (let i = 0; i < this.plugins.length; i++) {
+ const plugin = this.plugins[i];
+ if (plugin.onBeforeRun) {
+ plugin.onBeforeRun(this);
+ }
+ }
+ }
+
+ if (this.graphical) {
+ if (this.pipeline) {
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
+ if (this.immutable) {
+ this._replaceOutputTexture();
+ }
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+ return this.immutable ? this.texture.clone() : this.texture;
+ }
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+ return;
+ }
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
+ if (this.immutable) {
+ this._replaceOutputTexture();
+ }
+
+ if (this.subKernels !== null) {
+ if (this.immutable) {
+ this._replaceSubOutputTextures();
+ }
+ this.drawBuffers();
+ }
+
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+ }
+
+ drawBuffers() {
+ this.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(this.drawBuffersMap);
+ }
+
+ getInternalFormat() {
+ return this.context.RGBA;
+ }
+ getTextureFormat() {
+ const { context: gl } = this;
+ switch (this.getInternalFormat()) {
+ case gl.RGBA:
+ return gl.RGBA;
+ default:
+ throw new Error('Unknown internal format');
+ }
+ }
+
+ /**
+ *
+ * @desc replace output textures where arguments my be the same values
+ */
+ _replaceOutputTexture() {
+ if (this.texture.beforeMutate() || this._textureSwitched) {
+ const gl = this.context;
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture.texture, 0);
+ this._textureSwitched = false;
+ }
+ }
+
+ /**
+ * @desc Setup output texture
+ */
+ _setupOutputTexture() {
+ const gl = this.context;
+ const texSize = this.texSize;
+ if (this.texture) {
+ // here we inherit from an already existing kernel, so go ahead and just bind textures to the framebuffer
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture.texture, 0);
+ return;
+ }
+ const texture = this.createTexture();
+ gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ const format = this.getInternalFormat();
+ if (this.precision === 'single') {
+ gl.texImage2D(gl.TEXTURE_2D, 0, format, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);
+ } else {
+ gl.texImage2D(gl.TEXTURE_2D, 0, format, texSize[0], texSize[1], 0, format, gl.UNSIGNED_BYTE, null);
+ }
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ this.texture = new this.TextureConstructor({
+ texture,
+ size: texSize,
+ dimensions: this.threadDim,
+ output: this.output,
+ context: this.context,
+ internalFormat: this.getInternalFormat(),
+ textureFormat: this.getTextureFormat(),
+ kernel: this,
+ });
+ }
+
+ /**
+ *
+ * @desc replace sub-output textures where arguments my be the same values
+ */
+ _replaceSubOutputTextures() {
+ const gl = this.context;
+ for (let i = 0; i < this.mappedTextures.length; i++) {
+ const mappedTexture = this.mappedTextures[i];
+ if (mappedTexture.beforeMutate() || this._mappedTextureSwitched[i]) {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, mappedTexture.texture, 0);
+ this._mappedTextureSwitched[i] = false;
+ }
+ }
+ }
+
+ /**
+ * @desc Setup on inherit sub-output textures
+ */
+ _setupSubOutputTextures() {
+ const gl = this.context;
+ if (this.mappedTextures) {
+ // here we inherit from an already existing kernel, so go ahead and just bind textures to the framebuffer
+ for (let i = 0; i < this.subKernels.length; i++) {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, this.mappedTextures[i].texture, 0);
+ }
+ return;
+ }
+ const texSize = this.texSize;
+ this.drawBuffersMap = [gl.COLOR_ATTACHMENT0];
+ this.mappedTextures = [];
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const texture = this.createTexture();
+ this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1);
+ gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ if (this.precision === 'single') {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);
+ } else {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ }
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0);
+
+ this.mappedTextures.push(new this.TextureConstructor({
+ texture,
+ size: texSize,
+ dimensions: this.threadDim,
+ output: this.output,
+ context: this.context,
+ internalFormat: this.getInternalFormat(),
+ textureFormat: this.getTextureFormat(),
+ kernel: this,
+ }));
+ }
+ }
+
+ setUniform1f(name, value) {
+ if (this.uniform1fCache.hasOwnProperty(name)) {
+ const cache = this.uniform1fCache[name];
+ if (value === cache) {
+ return;
+ }
+ }
+ this.uniform1fCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform1f(loc, value);
+ }
+
+ setUniform1i(name, value) {
+ if (this.uniform1iCache.hasOwnProperty(name)) {
+ const cache = this.uniform1iCache[name];
+ if (value === cache) {
+ return;
+ }
+ }
+ this.uniform1iCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform1i(loc, value);
+ }
+
+ setUniform2f(name, value1, value2) {
+ if (this.uniform2fCache.hasOwnProperty(name)) {
+ const cache = this.uniform2fCache[name];
+ if (
+ value1 === cache[0] &&
+ value2 === cache[1]
+ ) {
+ return;
+ }
+ }
+ this.uniform2fCache[name] = [value1, value2];
+ const loc = this.getUniformLocation(name);
+ this.context.uniform2f(loc, value1, value2);
+ }
+
+ setUniform2fv(name, value) {
+ if (this.uniform2fvCache.hasOwnProperty(name)) {
+ const cache = this.uniform2fvCache[name];
+ if (
+ value[0] === cache[0] &&
+ value[1] === cache[1]
+ ) {
+ return;
+ }
+ }
+ this.uniform2fvCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform2fv(loc, value);
+ }
+
+ setUniform2iv(name, value) {
+ if (this.uniform2ivCache.hasOwnProperty(name)) {
+ const cache = this.uniform2ivCache[name];
+ if (
+ value[0] === cache[0] &&
+ value[1] === cache[1]
+ ) {
+ return;
+ }
+ }
+ this.uniform2ivCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform2iv(loc, value);
+ }
+
+ setUniform3fv(name, value) {
+ if (this.uniform3fvCache.hasOwnProperty(name)) {
+ const cache = this.uniform3fvCache[name];
+ if (
+ value[0] === cache[0] &&
+ value[1] === cache[1] &&
+ value[2] === cache[2]
+ ) {
+ return;
+ }
+ }
+ this.uniform3fvCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform3fv(loc, value);
+ }
+
+ setUniform3iv(name, value) {
+ if (this.uniform3ivCache.hasOwnProperty(name)) {
+ const cache = this.uniform3ivCache[name];
+ if (
+ value[0] === cache[0] &&
+ value[1] === cache[1] &&
+ value[2] === cache[2]
+ ) {
+ return;
+ }
+ }
+ this.uniform3ivCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform3iv(loc, value);
+ }
+
+ setUniform4fv(name, value) {
+ if (this.uniform4fvCache.hasOwnProperty(name)) {
+ const cache = this.uniform4fvCache[name];
+ if (
+ value[0] === cache[0] &&
+ value[1] === cache[1] &&
+ value[2] === cache[2] &&
+ value[3] === cache[3]
+ ) {
+ return;
+ }
+ }
+ this.uniform4fvCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform4fv(loc, value);
+ }
+
+ setUniform4iv(name, value) {
+ if (this.uniform4ivCache.hasOwnProperty(name)) {
+ const cache = this.uniform4ivCache[name];
+ if (
+ value[0] === cache[0] &&
+ value[1] === cache[1] &&
+ value[2] === cache[2] &&
+ value[3] === cache[3]
+ ) {
+ return;
+ }
+ }
+ this.uniform4ivCache[name] = value;
+ const loc = this.getUniformLocation(name);
+ this.context.uniform4iv(loc, value);
+ }
+
+ /**
+ * @desc Return WebGlUniformLocation for various variables
+ * related to webGl program, such as user-defined variables,
+ * as well as, dimension sizes, etc.
+ */
+ getUniformLocation(name) {
+ if (this.programUniformLocationCache.hasOwnProperty(name)) {
+ return this.programUniformLocationCache[name];
+ }
+ return this.programUniformLocationCache[name] = this.context.getUniformLocation(this.program, name);
+ }
+
+ /**
+ * @desc Generate Shader artifacts for the kernel program.
+ * The final object contains HEADER, KERNEL, MAIN_RESULT, and others.
+ *
+ * @param {Array} args - The actual parameters sent to the Kernel
+ * @returns {Object} An object containing the Shader Artifacts(CONSTANTS, HEADER, KERNEL, etc.)
+ */
+ _getFragShaderArtifactMap(args) {
+ return {
+ HEADER: this._getHeaderString(),
+ LOOP_MAX: this._getLoopMaxString(),
+ PLUGINS: this._getPluginsString(),
+ CONSTANTS: this._getConstantsString(),
+ DECODE32_ENDIANNESS: this._getDecode32EndiannessString(),
+ ENCODE32_ENDIANNESS: this._getEncode32EndiannessString(),
+ DIVIDE_WITH_INTEGER_CHECK: this._getDivideWithIntegerCheckString(),
+ INJECTED_NATIVE: this._getInjectedNative(),
+ MAIN_CONSTANTS: this._getMainConstantsString(),
+ MAIN_ARGUMENTS: this._getMainArgumentsString(args),
+ KERNEL: this.getKernelString(),
+ MAIN_RESULT: this.getMainResultString(),
+ FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(),
+ INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(),
+ SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(),
+ SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(),
+ };
+ }
+
+ /**
+ * @desc Generate Shader artifacts for the kernel program.
+ * The final object contains HEADER, KERNEL, MAIN_RESULT, and others.
+ *
+ * @param {Array} args - The actual parameters sent to the Kernel
+ * @returns {Object} An object containing the Shader Artifacts(CONSTANTS, HEADER, KERNEL, etc.)
+ */
+ _getVertShaderArtifactMap(args) {
+ return {
+ FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(),
+ INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(),
+ SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(),
+ SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(),
+ };
+ }
+
+ /**
+ * @desc Get the header string for the program.
+ * This returns an empty string if no sub-kernels are defined.
+ *
+ * @returns {String} result
+ */
+ _getHeaderString() {
+ return (
+ this.subKernels !== null ?
+ '#extension GL_EXT_draw_buffers : require\n' :
+ ''
+ );
+ }
+
+ /**
+ * @desc Get the maximum loop size String.
+ * @returns {String} result
+ */
+ _getLoopMaxString() {
+ return (
+ this.loopMaxIterations ?
+ ` ${parseInt(this.loopMaxIterations)};\n` :
+ ' 1000;\n'
+ );
+ }
+
+ _getPluginsString() {
+ if (!this.plugins) return '\n';
+ return this.plugins.map(plugin => plugin.source && this.source.match(plugin.functionMatch) ? plugin.source : '').join('\n');
+ }
+
+ /**
+ * @desc Generate transpiled glsl Strings for constant parameters sent to a kernel
+ * @returns {String} result
+ */
+ _getConstantsString() {
+ const result = [];
+ const { threadDim, texSize } = this;
+ if (this.dynamicOutput) {
+ result.push(
+ 'uniform ivec3 uOutputDim',
+ 'uniform ivec2 uTexSize'
+ );
+ } else {
+ result.push(
+ `ivec3 uOutputDim = ivec3(${threadDim[0]}, ${threadDim[1]}, ${threadDim[2]})`,
+ `ivec2 uTexSize = ivec2(${texSize[0]}, ${texSize[1]})`
+ );
+ }
+ return utils.linesToString(result);
+ }
+
+ /**
+ * @desc Get texture coordinate string for the program
+ * @returns {String} result
+ */
+ _getTextureCoordinate() {
+ const subKernels = this.subKernels;
+ if (subKernels === null || subKernels.length < 1) {
+ return 'varying vec2 vTexCoord;\n';
+ } else {
+ return 'out vec2 vTexCoord;\n';
+ }
+ }
+
+ /**
+ * @desc Get Decode32 endianness string for little-endian and big-endian
+ * @returns {String} result
+ */
+ _getDecode32EndiannessString() {
+ return (
+ this.endianness === 'LE' ?
+ '' :
+ ' texel.rgba = texel.abgr;\n'
+ );
+ }
+
+ /**
+ * @desc Get Encode32 endianness string for little-endian and big-endian
+ * @returns {String} result
+ */
+ _getEncode32EndiannessString() {
+ return (
+ this.endianness === 'LE' ?
+ '' :
+ ' texel.rgba = texel.abgr;\n'
+ );
+ }
+
+ /**
+ * @desc if fixIntegerDivisionAccuracy provide method to replace /
+ * @returns {String} result
+ */
+ _getDivideWithIntegerCheckString() {
+ return this.fixIntegerDivisionAccuracy ?
+ `float divWithIntCheck(float x, float y) {
+ if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) {
+ return float(int(x) / int(y));
+ }
+ return x / y;
+}
+
+float integerCorrectionModulo(float number, float divisor) {
+ if (number < 0.0) {
+ number = abs(number);
+ if (divisor < 0.0) {
+ divisor = abs(divisor);
+ }
+ return -(number - (divisor * floor(divWithIntCheck(number, divisor))));
+ }
+ if (divisor < 0.0) {
+ divisor = abs(divisor);
+ }
+ return number - (divisor * floor(divWithIntCheck(number, divisor)));
+}` :
+ '';
+ }
+
+ /**
+ * @desc Generate transpiled glsl Strings for user-defined parameters sent to a kernel
+ * @param {Array} args - The actual parameters sent to the Kernel
+ * @returns {String} result
+ */
+ _getMainArgumentsString(args) {
+ const results = [];
+ const { argumentNames } = this;
+ for (let i = 0; i < argumentNames.length; i++) {
+ results.push(this.kernelArguments[i].getSource(args[i]));
+ }
+ return results.join('');
+ }
+
+ _getInjectedNative() {
+ return this.injectedNative || '';
+ }
+
+ _getMainConstantsString() {
+ const result = [];
+ const { constants } = this;
+ if (constants) {
+ let i = 0;
+ for (const name in constants) {
+ if (!this.constants.hasOwnProperty(name)) continue;
+ result.push(this.kernelConstants[i++].getSource(this.constants[name]));
+ }
+ }
+ return result.join('');
+ }
+
+ getRawValueFramebuffer(width, height) {
+ if (!this.rawValueFramebuffers[width]) {
+ this.rawValueFramebuffers[width] = {};
+ }
+ if (!this.rawValueFramebuffers[width][height]) {
+ const framebuffer = this.context.createFramebuffer();
+ framebuffer.width = width;
+ framebuffer.height = height;
+ this.rawValueFramebuffers[width][height] = framebuffer;
+ }
+ return this.rawValueFramebuffers[width][height];
+ }
+
+ getKernelResultDeclaration() {
+ switch (this.returnType) {
+ case 'Array(2)':
+ return 'vec2 kernelResult';
+ case 'Array(3)':
+ return 'vec3 kernelResult';
+ case 'Array(4)':
+ return 'vec4 kernelResult';
+ case 'LiteralInteger':
+ case 'Float':
+ case 'Number':
+ case 'Integer':
+ return 'float kernelResult';
+ default:
+ if (this.graphical) {
+ return 'float kernelResult';
+ } else {
+ throw new Error(`unrecognized output type "${ this.returnType }"`);
+ }
+ }
+ }
+ /**
+ * @desc Get Kernel program string (in *glsl*) for a kernel.
+ * @returns {String} result
+ */
+ getKernelString() {
+ const result = [this.getKernelResultDeclaration()];
+ const { subKernels } = this;
+ if (subKernels !== null) {
+ switch (this.returnType) {
+ case 'Number':
+ case 'Float':
+ case 'Integer':
+ for (let i = 0; i < subKernels.length; i++) {
+ const subKernel = subKernels[i];
+ result.push(
+ subKernel.returnType === 'Integer' ?
+ `int subKernelResult_${ subKernel.name } = 0` :
+ `float subKernelResult_${ subKernel.name } = 0.0`
+ );
+ }
+ break;
+ case 'Array(2)':
+ for (let i = 0; i < subKernels.length; i++) {
+ result.push(
+ `vec2 subKernelResult_${ subKernels[i].name }`
+ );
+ }
+ break;
+ case 'Array(3)':
+ for (let i = 0; i < subKernels.length; i++) {
+ result.push(
+ `vec3 subKernelResult_${ subKernels[i].name }`
+ );
+ }
+ break;
+ case 'Array(4)':
+ for (let i = 0; i < subKernels.length; i++) {
+ result.push(
+ `vec4 subKernelResult_${ subKernels[i].name }`
+ );
+ }
+ break;
+ }
+ }
+
+ return utils.linesToString(result) + this.translatedSource;
+ }
+
+ getMainResultGraphical() {
+ return utils.linesToString([
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' gl_FragColor = actualColor',
+ ]);
+ }
+
+ getMainResultPackedPixels() {
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ return this.getMainResultKernelPackedPixels() +
+ this.getMainResultSubKernelPackedPixels();
+ default:
+ throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`);
+ }
+ }
+
+ /**
+ * @return {String}
+ */
+ getMainResultKernelPackedPixels() {
+ return utils.linesToString([
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ` gl_FragData[0] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)`
+ ]);
+ }
+
+ /**
+ * @return {String}
+ */
+ getMainResultSubKernelPackedPixels() {
+ const result = [];
+ if (!this.subKernels) return '';
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const subKernel = this.subKernels[i];
+ if (subKernel.returnType === 'Integer') {
+ result.push(
+ ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))`
+ );
+ } else {
+ result.push(
+ ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})`
+ );
+ }
+ }
+ return utils.linesToString(result);
+ }
+
+ getMainResultMemoryOptimizedFloats() {
+ const result = [
+ ' index *= 4',
+ ];
+
+ switch (this.returnType) {
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ const channels = ['r', 'g', 'b', 'a'];
+ for (let i = 0; i < channels.length; i++) {
+ const channel = channels[i];
+ this.getMainResultKernelMemoryOptimizedFloats(result, channel);
+ this.getMainResultSubKernelMemoryOptimizedFloats(result, channel);
+ if (i + 1 < channels.length) {
+ result.push(' index += 1');
+ }
+ }
+ break;
+ default:
+ throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`);
+ }
+
+ return utils.linesToString(result);
+ }
+
+ getMainResultKernelMemoryOptimizedFloats(result, channel) {
+ result.push(
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ` gl_FragData[0].${channel} = kernelResult`
+ );
+ }
+
+ getMainResultSubKernelMemoryOptimizedFloats(result, channel) {
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const subKernel = this.subKernels[i];
+ if (subKernel.returnType === 'Integer') {
+ result.push(
+ ` gl_FragData[${i + 1}].${channel} = float(subKernelResult_${this.subKernels[i].name})`
+ );
+ } else {
+ result.push(
+ ` gl_FragData[${i + 1}].${channel} = subKernelResult_${this.subKernels[i].name}`
+ );
+ }
+ }
+ }
+
+ getMainResultKernelNumberTexture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' gl_FragData[0][0] = kernelResult',
+ ];
+ }
+
+ getMainResultSubKernelNumberTexture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ const subKernel = this.subKernels[i];
+ if (subKernel.returnType === 'Integer') {
+ result.push(
+ ` gl_FragData[${i + 1}][0] = float(subKernelResult_${subKernel.name})`
+ );
+ } else {
+ result.push(
+ ` gl_FragData[${i + 1}][0] = subKernelResult_${subKernel.name}`
);
- }*/
- } else {
- result.push('highp float kernelResult = 0.0');
- }
-
- return this._linesToString(result) + this.functionBuilder.getPrototypeString('kernel');
- }
-
- /**
- *
- * @memberOf WebGLKernel#
- * @function
- * @name _getMainResultString
- *
- * @desc Get main result string with checks for floatOutput, graphical, subKernelsOutputs, etc.
- *
- * @returns {String} result
- *
- */
- _getMainResultString() {
- const names = this.subKernelOutputVariableNames;
- const result = [];
- if (this.floatOutput) {
- result.push(' index *= 4.0');
- }
-
- if (this.graphical) {
- result.push(
- ' threadId = indexTo3D(index, uOutputDim)',
- ' kernel()',
- ' gl_FragColor = actualColor'
- );
- } else if (this.floatOutput) {
- result.push(
- ' threadId = indexTo3D(index, uOutputDim)',
- ' kernel()',
- ' gl_FragColor.r = kernelResult',
- ' index += 1.0',
- ' threadId = indexTo3D(index, uOutputDim)',
- ' kernel()',
- ' gl_FragColor.g = kernelResult',
- ' index += 1.0',
- ' threadId = indexTo3D(index, uOutputDim)',
- ' kernel()',
- ' gl_FragColor.b = kernelResult',
- ' index += 1.0',
- ' threadId = indexTo3D(index, uOutputDim)',
- ' kernel()',
- ' gl_FragColor.a = kernelResult'
- );
- } else if (names !== null) {
- result.push(' threadId = indexTo3D(index, uOutputDim)');
- result.push(' kernel()');
- result.push(' gl_FragData[0] = encode32(kernelResult)');
- for (let i = 0; i < names.length; i++) {
- result.push(` gl_FragData[${ i + 1 }] = encode32(${ names[i] })`);
- }
- /* this is v2 prep
- * result.push(' kernel()');
- result.push(' fragData0 = encode32(kernelResult)');
- for (let i = 0; i < names.length; i++) {
- result.push(` fragData${ i + 1 } = encode32(${ names[i] })`);
- }*/
- } else {
- result.push(
- ' threadId = indexTo3D(index, uOutputDim)',
- ' kernel()',
- ' gl_FragColor = encode32(kernelResult)'
- );
- }
-
- return this._linesToString(result);
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _linesToString
- *
- * @param {Array} lines - An Array of strings
- *
- * @returns {String} Single combined String, seperated by *\n*
- *
- */
- _linesToString(lines) {
- if (lines.length > 0) {
- return lines.join(';\n') + ';\n';
- } else {
- return '\n';
- }
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _replaceArtifacts
- *
- * @param {String} src - Shader string
- * @param {Array} map - Variables/Constants associated with shader
- *
- */
- _replaceArtifacts(src, map) {
- return src.replace(/[ ]*__([A-Z]+[0-9]*([_]?[A-Z])*)__;\n/g, (match, artifact) => {
- if (map.hasOwnProperty(artifact)) {
- return map[artifact];
- }
- throw `unhandled artifact ${ artifact }`;
- });
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _addKernels
- *
- * @desc Adds all the sub-kernels supplied with this Kernel instance.
- *
- */
- _addKernels() {
- const builder = this.functionBuilder;
- const gl = this._webGl;
-
- builder.addFunctions(this.functions, {
- constants: this.constants,
- output: this.output
- });
- builder.addNativeFunctions(this.nativeFunctions);
-
- builder.addKernel(this.fnString, {
- prototypeOnly: false,
- constants: this.constants,
- output: this.output,
- debug: this.debug,
- loopMaxIterations: this.loopMaxIterations
- }, this.paramNames, this.paramTypes);
-
- if (this.subKernels !== null) {
- const ext = this.ext = gl.getExtension('WEBGL_draw_buffers');
- if (!ext) throw new Error('could not instantiate draw buffers extension');
- this.subKernelOutputTextures = [];
- this.subKernelOutputVariableNames = [];
- for (let i = 0; i < this.subKernels.length; i++) {
- const subKernel = this.subKernels[i];
- builder.addSubKernel(subKernel, {
- prototypeOnly: false,
- constants: this.constants,
- output: this.output,
- debug: this.debug,
- loopMaxIterations: this.loopMaxIterations
- });
- this.subKernelOutputTextures.push(this.getSubKernelTexture(i));
- this.subKernelOutputVariableNames.push(subKernel.name + 'Result');
- }
-
- } else if (this.subKernelProperties !== null) {
- const ext = this.ext = gl.getExtension('WEBGL_draw_buffers');
- if (!ext) throw new Error('could not instantiate draw buffers extension');
- this.subKernelOutputTextures = [];
- this.subKernelOutputVariableNames = [];
- let i = 0;
- for (let p in this.subKernelProperties) {
- if (!this.subKernelProperties.hasOwnProperty(p)) continue;
- const subKernel = this.subKernelProperties[p];
- builder.addSubKernel(subKernel, {
- prototypeOnly: false,
- constants: this.constants,
- output: this.output,
- debug: this.debug,
- loopMaxIterations: this.loopMaxIterations
- });
- this.subKernelOutputTextures.push(this.getSubKernelTexture(p));
- this.subKernelOutputVariableNames.push(subKernel.name + 'Result');
- i++;
- }
- }
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getFragShaderString
- *
- * @desc Get the fragment shader String.
- * If the String hasn't been compiled yet,
- * then this method compiles it as well
- *
- * @param {Array} args - The actual parameters sent to the Kernel
- *
- * @returns {String} Fragment Shader string
- *
- */
- _getFragShaderString(args) {
- if (this.compiledFragShaderString !== null) {
- return this.compiledFragShaderString;
- }
- return this.compiledFragShaderString = this._replaceArtifacts(fragShaderString, this._getFragShaderArtifactMap(args));
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name _getVertShaderString
- *
- * @desc Get the vertical shader String
- *
- * @param {Array} args - The actual parameters sent to the Kernel
- *
- * @returns {String} Vertical Shader string
- *
- */
- _getVertShaderString(args) {
- if (this.compiledVertShaderString !== null) {
- return this.compiledVertShaderString;
- }
- //TODO: webgl2 compile like frag shader
- return this.compiledVertShaderString = vertShaderString;
- }
-
- /**
- * @memberOf WebGLKernel#
- * @function
- * @name toString
- *
- * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused.
- *
- */
- toString() {
- return kernelString(this);
- }
-
- addFunction(fn) {
- this.functionBuilder.addFunction(null, fn);
- }
+ }
+ }
+ return result;
+ }
+
+ getMainResultKernelArray2Texture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' gl_FragData[0][0] = kernelResult[0]',
+ ' gl_FragData[0][1] = kernelResult[1]',
+ ];
+ }
+
+ getMainResultSubKernelArray2Texture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ result.push(
+ ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,
+ ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`
+ );
+ }
+ return result;
+ }
+
+ getMainResultKernelArray3Texture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' gl_FragData[0][0] = kernelResult[0]',
+ ' gl_FragData[0][1] = kernelResult[1]',
+ ' gl_FragData[0][2] = kernelResult[2]',
+ ];
+ }
+
+ getMainResultSubKernelArray3Texture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ result.push(
+ ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,
+ ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,
+ ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`
+ );
+ }
+ return result;
+ }
+
+ getMainResultKernelArray4Texture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' gl_FragData[0] = kernelResult',
+ ];
+ }
+
+ getMainResultSubKernelArray4Texture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ switch (this.returnType) {
+ case 'Number':
+ case 'Float':
+ case 'Integer':
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ const subKernel = this.subKernels[i];
+ if (subKernel.returnType === 'Integer') {
+ result.push(
+ ` gl_FragData[${i + 1}] = float(subKernelResult_${this.subKernels[i].name})`
+ );
+ } else {
+ result.push(
+ ` gl_FragData[${i + 1}] = subKernelResult_${this.subKernels[i].name}`
+ );
+ }
+ }
+ break;
+ case 'Array(2)':
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ result.push(
+ ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,
+ ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`
+ );
+ }
+ break;
+ case 'Array(3)':
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ result.push(
+ ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,
+ ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,
+ ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`
+ );
+ }
+ break;
+ case 'Array(4)':
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ result.push(
+ ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,
+ ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,
+ ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`,
+ ` gl_FragData[${i + 1}][3] = subKernelResult_${this.subKernels[i].name}[3]`
+ );
+ }
+ break;
+ }
+
+ return result;
+ }
+
+ /**
+ * @param {String} src - Shader string
+ * @param {Object} map - Variables/Constants associated with shader
+ */
+ replaceArtifacts(src, map) {
+ return src.replace(/[ ]*__([A-Z]+[0-9]*([_]?[A-Z]*[0-9]?)*)__;\n/g, (match, artifact) => {
+ if (map.hasOwnProperty(artifact)) {
+ return map[artifact];
+ }
+ throw `unhandled artifact ${artifact}`;
+ });
+ }
+
+ /**
+ * @desc Get the fragment shader String.
+ * If the String hasn't been compiled yet,
+ * then this method compiles it as well
+ *
+ * @param {Array} args - The actual parameters sent to the Kernel
+ * @returns {string} Fragment Shader string
+ */
+ getFragmentShader(args) {
+ if (this.compiledFragmentShader !== null) {
+ return this.compiledFragmentShader;
+ }
+ return this.compiledFragmentShader = this.replaceArtifacts(this.constructor.fragmentShader, this._getFragShaderArtifactMap(args));
+ }
+
+ /**
+ * @desc Get the vertical shader String
+ * @param {Array|IArguments} args - The actual parameters sent to the Kernel
+ * @returns {string} Vertical Shader string
+ */
+ getVertexShader(args) {
+ if (this.compiledVertexShader !== null) {
+ return this.compiledVertexShader;
+ }
+ return this.compiledVertexShader = this.replaceArtifacts(this.constructor.vertexShader, this._getVertShaderArtifactMap(args));
+ }
+
+ /**
+ * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused.
+ */
+ toString() {
+ const setupContextString = utils.linesToString([
+ `const gl = context`,
+ ]);
+ return glKernelString(this.constructor, arguments, this, setupContextString);
+ }
+
+ destroy(removeCanvasReferences) {
+ if (!this.context) return;
+ if (this.buffer) {
+ this.context.deleteBuffer(this.buffer);
+ }
+ if (this.framebuffer) {
+ this.context.deleteFramebuffer(this.framebuffer);
+ }
+ for (const width in this.rawValueFramebuffers) {
+ for (const height in this.rawValueFramebuffers[width]) {
+ this.context.deleteFramebuffer(this.rawValueFramebuffers[width][height]);
+ delete this.rawValueFramebuffers[width][height];
+ }
+ delete this.rawValueFramebuffers[width];
+ }
+ if (this.vertShader) {
+ this.context.deleteShader(this.vertShader);
+ }
+ if (this.fragShader) {
+ this.context.deleteShader(this.fragShader);
+ }
+ if (this.program) {
+ this.context.deleteProgram(this.program);
+ }
+ if (this.texture) {
+ this.texture.delete();
+ const textureCacheIndex = this.textureCache.indexOf(this.texture.texture);
+ if (textureCacheIndex > -1) {
+ this.textureCache.splice(textureCacheIndex, 1);
+ }
+ this.texture = null;
+ }
+ if (this.mappedTextures && this.mappedTextures.length) {
+ for (let i = 0; i < this.mappedTextures.length; i++) {
+ const mappedTexture = this.mappedTextures[i];
+ mappedTexture.delete();
+ const textureCacheIndex = this.textureCache.indexOf(mappedTexture.texture);
+ if (textureCacheIndex > -1) {
+ this.textureCache.splice(textureCacheIndex, 1);
+ }
+ }
+ this.mappedTextures = null;
+ }
+ if (this.kernelArguments) {
+ for (let i = 0; i < this.kernelArguments.length; i++) {
+ this.kernelArguments[i].destroy();
+ }
+ }
+ if (this.kernelConstants) {
+ for (let i = 0; i < this.kernelConstants.length; i++) {
+ this.kernelConstants[i].destroy();
+ }
+ }
+ while (this.textureCache.length > 0) {
+ const texture = this.textureCache.pop();
+ this.context.deleteTexture(texture);
+ }
+ if (removeCanvasReferences) {
+ const idx = canvases.indexOf(this.canvas);
+ if (idx >= 0) {
+ canvases[idx] = null;
+ maxTexSizes[idx] = null;
+ }
+ }
+ this.destroyExtensions();
+ delete this.context;
+ delete this.canvas;
+ if (!this.gpu) return;
+ const i = this.gpu.kernels.indexOf(this);
+ if (i === -1) return;
+ this.gpu.kernels.splice(i, 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(context) {
+ const extension = context.getExtension('WEBGL_lose_context');
+ if (extension) {
+ extension.loseContext();
+ }
+ }
+
+ /**
+ * @return {IKernelJSON}
+ */
+ toJSON() {
+ const json = super.toJSON();
+ json.functionNodes = FunctionBuilder.fromKernel(this, WebGLFunctionNode).toJSON();
+ json.settings.threadDim = this.threadDim;
+ return json;
+ }
+}
+
+module.exports = {
+ WebGLKernel
};
\ No newline at end of file
diff --git a/src/backend/web-gl/runner.js b/src/backend/web-gl/runner.js
deleted file mode 100644
index 6e9a54d4..00000000
--- a/src/backend/web-gl/runner.js
+++ /dev/null
@@ -1,40 +0,0 @@
-'use strict';
-
-const RunnerBase = require('../runner-base');
-const WebGLKernel = require('./kernel');
-const utils = require('../../core/utils');
-const WebGLFunctionBuilder = require('./function-builder');
-
-
-module.exports = class WebGLRunner extends RunnerBase {
-
- /**
- * @constructor WebGLRunner
- *
- * @extends RunnerBase
-
- * @desc Instantiates a Runner instance for the kernel.
- *
- * @param {Object} settings - Settings to instantiate properties in RunnerBase, with given values
- *
- */
- constructor(settings) {
- super(new WebGLFunctionBuilder(), settings);
- this.Kernel = WebGLKernel;
- this.kernel = null;
- }
-
- /**
- * @memberOf WebGLRunner#
- * @function
- * @name getMode
- *
- * @desc Return the current mode in which gpu.js is executing.
- *
- * @returns {String} The current mode; "cpu".
- *
- */
- getMode() {
- return 'gpu';
- }
-};
\ No newline at end of file
diff --git a/src/backend/web-gl/shader-frag.js b/src/backend/web-gl/shader-frag.js
deleted file mode 100644
index 544bdd7f..00000000
--- a/src/backend/web-gl/shader-frag.js
+++ /dev/null
@@ -1,132 +0,0 @@
-module.exports = `__HEADER__;
-precision highp float;
-precision highp int;
-precision highp sampler2D;
-
-const float LOOP_MAX = __LOOP_MAX__;
-#define EPSILON 0.0000001;
-
-__CONSTANTS__;
-
-varying highp vec2 vTexCoord;
-
-vec4 round(vec4 x) {
- return floor(x + 0.5);
-}
-
-highp float round(highp float x) {
- return floor(x + 0.5);
-}
-
-vec2 integerMod(vec2 x, float y) {
- vec2 res = floor(mod(x, y));
- return res * step(1.0 - floor(y), -res);
-}
-
-vec3 integerMod(vec3 x, float y) {
- vec3 res = floor(mod(x, y));
- return res * step(1.0 - floor(y), -res);
-}
-
-vec4 integerMod(vec4 x, vec4 y) {
- vec4 res = floor(mod(x, y));
- return res * step(1.0 - floor(y), -res);
-}
-
-highp float integerMod(highp float x, highp float y) {
- highp float res = floor(mod(x, y));
- return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);
-}
-
-highp int integerMod(highp int x, highp int y) {
- return int(integerMod(float(x), float(y)));
-}
-
-// Here be dragons!
-// DO NOT OPTIMIZE THIS CODE
-// YOU WILL BREAK SOMETHING ON SOMEBODY\'S MACHINE
-// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME
-const vec2 MAGIC_VEC = vec2(1.0, -256.0);
-const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);
-const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536
-highp float decode32(highp vec4 rgba) {
- __DECODE32_ENDIANNESS__;
- rgba *= 255.0;
- vec2 gte128;
- gte128.x = rgba.b >= 128.0 ? 1.0 : 0.0;
- gte128.y = rgba.a >= 128.0 ? 1.0 : 0.0;
- float exponent = 2.0 * rgba.a - 127.0 + dot(gte128, MAGIC_VEC);
- float res = exp2(round(exponent));
- rgba.b = rgba.b - 128.0 * gte128.x;
- res = dot(rgba, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;
- res *= gte128.y * -2.0 + 1.0;
- return res;
-}
-
-highp vec4 encode32(highp float f) {
- highp float F = abs(f);
- highp float sign = f < 0.0 ? 1.0 : 0.0;
- highp float exponent = floor(log2(F));
- highp float mantissa = (exp2(-exponent) * F);
- // exponent += floor(log2(mantissa));
- vec4 rgba = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;
- rgba.rg = integerMod(rgba.rg, 256.0);
- rgba.b = integerMod(rgba.b, 128.0);
- rgba.a = exponent*0.5 + 63.5;
- rgba.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;
- rgba = floor(rgba);
- rgba *= 0.003921569; // 1/255
- __ENCODE32_ENDIANNESS__;
- return rgba;
-}
-// Dragons end here
-
-highp float index;
-highp vec3 threadId;
-
-highp vec3 indexTo3D(highp float idx, highp vec3 texDim) {
- highp float z = floor(idx / (texDim.x * texDim.y));
- idx -= z * texDim.x * texDim.y;
- highp float y = floor(idx / texDim.x);
- highp float x = integerMod(idx, texDim.x);
- return vec3(x, y, z);
-}
-
-highp float get(highp sampler2D tex, highp vec2 texSize, highp vec3 texDim, highp float z, highp float y, highp float x) {
- highp vec3 xyz = vec3(x, y, z);
- xyz = floor(xyz + 0.5);
- __GET_WRAPAROUND__;
- highp float index = round(xyz.x + texDim.x * (xyz.y + texDim.y * xyz.z));
- __GET_TEXTURE_CHANNEL__;
- highp float w = round(texSize.x);
- vec2 st = vec2(integerMod(index, w), float(int(index) / int(w))) + 0.5;
- __GET_TEXTURE_INDEX__;
- highp vec4 texel = texture2D(tex, st / texSize);
- __GET_RESULT__;
-}
-
-highp float get(highp sampler2D tex, highp vec2 texSize, highp vec3 texDim, highp float y, highp float x) {
- return get(tex, texSize, texDim, 0.0, y, x);
-}
-
-highp float get(highp sampler2D tex, highp vec2 texSize, highp vec3 texDim, highp float x) {
- return get(tex, texSize, texDim, 0.0, 0.0, x);
-}
-
-highp vec4 actualColor;
-void color(float r, float g, float b, float a) {
- actualColor = vec4(r,g,b,a);
-}
-
-void color(float r, float g, float b) {
- color(r,g,b,1.0);
-}
-
-__MAIN_PARAMS__;
-__MAIN_CONSTANTS__;
-__KERNEL__;
-
-void main(void) {
- index = floor(vTexCoord.s * float(uTexSize.x)) + floor(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;
- __MAIN_RESULT__;
-}`;
\ No newline at end of file
diff --git a/src/backend/web-gl/shader-vert.js b/src/backend/web-gl/shader-vert.js
deleted file mode 100644
index 5e3df566..00000000
--- a/src/backend/web-gl/shader-vert.js
+++ /dev/null
@@ -1,14 +0,0 @@
-module.exports = `precision highp float;
-precision highp int;
-precision highp sampler2D;
-
-attribute highp vec2 aPos;
-attribute highp vec2 aTexCoord;
-
-varying highp vec2 vTexCoord;
-uniform vec2 ratio;
-
-void main(void) {
- gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);
- vTexCoord = aTexCoord;
-}`;
\ No newline at end of file
diff --git a/src/backend/web-gl/validator-kernel.js b/src/backend/web-gl/validator-kernel.js
deleted file mode 100644
index e88d0321..00000000
--- a/src/backend/web-gl/validator-kernel.js
+++ /dev/null
@@ -1,26 +0,0 @@
-'use strict';
-
-const WebGLKernel = require('./kernel');
-const utils = require('../../core/utils');
-
-/**
- * @class WebGLValidatorKernel
- *
- * @desc Helper class for WebGLKernel to validate texture size and dimensions.
- *
- */
-module.exports = class WebGLValidatorKernel extends WebGLKernel {
-
- /**
- * @memberOf WebGLValidatorKernel#
- * @function
- * @name validateOptions
- *
- */
- validateOptions() {
- this.texSize = utils.dimToTexSize({
- floatTextures: this.floatTextures,
- floatOutput: this.floatOutput
- }, this.output, true);
- }
-};
\ No newline at end of file
diff --git a/src/backend/web-gl/vertex-shader.js b/src/backend/web-gl/vertex-shader.js
new file mode 100644
index 00000000..88647d73
--- /dev/null
+++ b/src/backend/web-gl/vertex-shader.js
@@ -0,0 +1,19 @@
+// language=GLSL
+const vertexShader = `__FLOAT_TACTIC_DECLARATION__;
+__INT_TACTIC_DECLARATION__;
+__SAMPLER_2D_TACTIC_DECLARATION__;
+
+attribute vec2 aPos;
+attribute vec2 aTexCoord;
+
+varying vec2 vTexCoord;
+uniform vec2 ratio;
+
+void main(void) {
+ gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);
+ vTexCoord = aTexCoord;
+}`;
+
+module.exports = {
+ vertexShader
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/fragment-shader.js b/src/backend/web-gl2/fragment-shader.js
new file mode 100644
index 00000000..b45a8706
--- /dev/null
+++ b/src/backend/web-gl2/fragment-shader.js
@@ -0,0 +1,452 @@
+// language=GLSL
+const fragmentShader = `#version 300 es
+__HEADER__;
+__FLOAT_TACTIC_DECLARATION__;
+__INT_TACTIC_DECLARATION__;
+__SAMPLER_2D_TACTIC_DECLARATION__;
+__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__;
+
+const int LOOP_MAX = __LOOP_MAX__;
+
+__PLUGINS__;
+__CONSTANTS__;
+
+in vec2 vTexCoord;
+
+float atan2(float v1, float v2) {
+ if (v1 == 0.0 || v2 == 0.0) return 0.0;
+ return atan(v1 / v2);
+}
+
+float cbrt(float x) {
+ if (x >= 0.0) {
+ return pow(x, 1.0 / 3.0);
+ } else {
+ return -pow(x, 1.0 / 3.0);
+ }
+}
+
+float expm1(float x) {
+ return pow(${Math.E}, x) - 1.0;
+}
+
+float fround(highp float x) {
+ return x;
+}
+
+float imul(float v1, float v2) {
+ return float(int(v1) * int(v2));
+}
+
+float log10(float x) {
+ return log2(x) * (1.0 / log2(10.0));
+}
+
+float log1p(float x) {
+ return log(1.0 + x);
+}
+
+float _pow(float v1, float v2) {
+ if (v2 == 0.0) return 1.0;
+ return pow(v1, v2);
+}
+
+float _round(float x) {
+ return floor(x + 0.5);
+}
+
+
+const int BIT_COUNT = 32;
+int modi(int x, int y) {
+ return x - y * (x / y);
+}
+
+int bitwiseOr(int a, int b) {
+ int result = 0;
+ int n = 1;
+
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {
+ result += n;
+ }
+ a = a / 2;
+ b = b / 2;
+ n = n * 2;
+ if(!(a > 0 || b > 0)) {
+ break;
+ }
+ }
+ return result;
+}
+int bitwiseXOR(int a, int b) {
+ int result = 0;
+ int n = 1;
+
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {
+ result += n;
+ }
+ a = a / 2;
+ b = b / 2;
+ n = n * 2;
+ if(!(a > 0 || b > 0)) {
+ break;
+ }
+ }
+ return result;
+}
+int bitwiseAnd(int a, int b) {
+ int result = 0;
+ int n = 1;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {
+ result += n;
+ }
+ a = a / 2;
+ b = b / 2;
+ n = n * 2;
+ if(!(a > 0 && b > 0)) {
+ break;
+ }
+ }
+ return result;
+}
+int bitwiseNot(int a) {
+ int result = 0;
+ int n = 1;
+
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (modi(a, 2) == 0) {
+ result += n;
+ }
+ a = a / 2;
+ n = n * 2;
+ }
+ return result;
+}
+int bitwiseZeroFillLeftShift(int n, int shift) {
+ int maxBytes = BIT_COUNT;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (maxBytes >= n) {
+ break;
+ }
+ maxBytes *= 2;
+ }
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= shift) {
+ break;
+ }
+ n *= 2;
+ }
+
+ int result = 0;
+ int byteVal = 1;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= maxBytes) break;
+ if (modi(n, 2) > 0) { result += byteVal; }
+ n = int(n / 2);
+ byteVal *= 2;
+ }
+ return result;
+}
+
+int bitwiseSignedRightShift(int num, int shifts) {
+ return int(floor(float(num) / pow(2.0, float(shifts))));
+}
+
+int bitwiseZeroFillRightShift(int n, int shift) {
+ int maxBytes = BIT_COUNT;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (maxBytes >= n) {
+ break;
+ }
+ maxBytes *= 2;
+ }
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= shift) {
+ break;
+ }
+ n /= 2;
+ }
+ int result = 0;
+ int byteVal = 1;
+ for (int i = 0; i < BIT_COUNT; i++) {
+ if (i >= maxBytes) break;
+ if (modi(n, 2) > 0) { result += byteVal; }
+ n = int(n / 2);
+ byteVal *= 2;
+ }
+ return result;
+}
+
+vec2 integerMod(vec2 x, float y) {
+ vec2 res = floor(mod(x, y));
+ return res * step(1.0 - floor(y), -res);
+}
+
+vec3 integerMod(vec3 x, float y) {
+ vec3 res = floor(mod(x, y));
+ return res * step(1.0 - floor(y), -res);
+}
+
+vec4 integerMod(vec4 x, vec4 y) {
+ vec4 res = floor(mod(x, y));
+ return res * step(1.0 - floor(y), -res);
+}
+
+float integerMod(float x, float y) {
+ float res = floor(mod(x, y));
+ return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);
+}
+
+int integerMod(int x, int y) {
+ return x - (y * int(x/y));
+}
+
+__DIVIDE_WITH_INTEGER_CHECK__;
+
+// Here be dragons!
+// DO NOT OPTIMIZE THIS CODE
+// YOU WILL BREAK SOMETHING ON SOMEBODY\'S MACHINE
+// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME
+const vec2 MAGIC_VEC = vec2(1.0, -256.0);
+const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);
+const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536
+float decode32(vec4 texel) {
+ __DECODE32_ENDIANNESS__;
+ texel *= 255.0;
+ vec2 gte128;
+ gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;
+ gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;
+ float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);
+ float res = exp2(round(exponent));
+ texel.b = texel.b - 128.0 * gte128.x;
+ res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;
+ res *= gte128.y * -2.0 + 1.0;
+ return res;
+}
+
+float decode16(vec4 texel, int index) {
+ int channel = integerMod(index, 2);
+ return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0;
+}
+
+float decode8(vec4 texel, int index) {
+ int channel = integerMod(index, 4);
+ return texel[channel] * 255.0;
+}
+
+vec4 legacyEncode32(float f) {
+ float F = abs(f);
+ float sign = f < 0.0 ? 1.0 : 0.0;
+ float exponent = floor(log2(F));
+ float mantissa = (exp2(-exponent) * F);
+ // exponent += floor(log2(mantissa));
+ vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;
+ texel.rg = integerMod(texel.rg, 256.0);
+ texel.b = integerMod(texel.b, 128.0);
+ texel.a = exponent*0.5 + 63.5;
+ texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;
+ texel = floor(texel);
+ texel *= 0.003921569; // 1/255
+ __ENCODE32_ENDIANNESS__;
+ return texel;
+}
+
+// https://github.com/gpujs/gpu.js/wiki/Encoder-details
+vec4 encode32(float value) {
+ if (value == 0.0) return vec4(0, 0, 0, 0);
+
+ float exponent;
+ float mantissa;
+ vec4 result;
+ float sgn;
+
+ sgn = step(0.0, -value);
+ value = abs(value);
+
+ exponent = floor(log2(value));
+
+ mantissa = value*pow(2.0, -exponent)-1.0;
+ exponent = exponent+127.0;
+ result = vec4(0,0,0,0);
+
+ result.a = floor(exponent/2.0);
+ exponent = exponent - result.a*2.0;
+ result.a = result.a + 128.0*sgn;
+
+ result.b = floor(mantissa * 128.0);
+ mantissa = mantissa - result.b / 128.0;
+ result.b = result.b + exponent*128.0;
+
+ result.g = floor(mantissa*32768.0);
+ mantissa = mantissa - result.g/32768.0;
+
+ result.r = floor(mantissa*8388608.0);
+ return result/255.0;
+}
+// Dragons end here
+
+int index;
+ivec3 threadId;
+
+ivec3 indexTo3D(int idx, ivec3 texDim) {
+ int z = int(idx / (texDim.x * texDim.y));
+ idx -= z * int(texDim.x * texDim.y);
+ int y = int(idx / texDim.x);
+ int x = int(integerMod(idx, texDim.x));
+ return ivec3(x, y, z);
+}
+
+float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture(tex, st / vec2(texSize));
+ return decode32(texel);
+}
+
+float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + (texDim.x * (y + (texDim.y * z)));
+ int w = texSize.x * 2;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y));
+ return decode16(texel, index);
+}
+
+float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + (texDim.x * (y + (texDim.y * z)));
+ int w = texSize.x * 4;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y));
+ return decode8(texel, index);
+}
+
+float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + (texDim.x * (y + (texDim.y * z)));
+ int channel = integerMod(index, 4);
+ index = index / 4;
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ index = index / 4;
+ vec4 texel = texture(tex, st / vec2(texSize));
+ return texel[channel];
+}
+
+vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ return texture(tex, st / vec2(texSize));
+}
+
+vec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ return texture(tex, vec3(st / vec2(texSize), z));
+}
+
+float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
+ return result[0];
+}
+
+vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
+ return vec2(result[0], result[1]);
+}
+
+vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int channel = integerMod(index, 2);
+ index = index / 2;
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture(tex, st / vec2(texSize));
+ if (channel == 0) return vec2(texel.r, texel.g);
+ if (channel == 1) return vec2(texel.b, texel.a);
+ return vec2(0.0, 0.0);
+}
+
+vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
+ return vec3(result[0], result[1], result[2]);
+}
+
+vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));
+ int vectorIndex = fieldIndex / 4;
+ int vectorOffset = fieldIndex - vectorIndex * 4;
+ int readY = vectorIndex / texSize.x;
+ int readX = vectorIndex - readY * texSize.x;
+ vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));
+
+ if (vectorOffset == 0) {
+ return tex1.xyz;
+ } else if (vectorOffset == 1) {
+ return tex1.yzw;
+ } else {
+ readX++;
+ if (readX >= texSize.x) {
+ readX = 0;
+ readY++;
+ }
+ vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize));
+ if (vectorOffset == 2) {
+ return vec3(tex1.z, tex1.w, tex2.x);
+ } else {
+ return vec3(tex1.w, tex2.x, tex2.y);
+ }
+ }
+}
+
+vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ return getImage2D(tex, texSize, texDim, z, y, x);
+}
+
+vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
+ int index = x + texDim.x * (y + texDim.y * z);
+ int channel = integerMod(index, 2);
+ int w = texSize.x;
+ vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
+ vec4 texel = texture(tex, st / vec2(texSize));
+ return vec4(texel.r, texel.g, texel.b, texel.a);
+}
+
+vec4 actualColor;
+void color(float r, float g, float b, float a) {
+ actualColor = vec4(r,g,b,a);
+}
+
+void color(float r, float g, float b) {
+ color(r,g,b,1.0);
+}
+
+float modulo(float number, float divisor) {
+ if (number < 0.0) {
+ number = abs(number);
+ if (divisor < 0.0) {
+ divisor = abs(divisor);
+ }
+ return -mod(number, divisor);
+ }
+ if (divisor < 0.0) {
+ divisor = abs(divisor);
+ }
+ return mod(number, divisor);
+}
+
+__INJECTED_NATIVE__;
+__MAIN_CONSTANTS__;
+__MAIN_ARGUMENTS__;
+__KERNEL__;
+
+void main(void) {
+ index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;
+ __MAIN_RESULT__;
+}`;
+
+module.exports = {
+ fragmentShader
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/function-node.js b/src/backend/web-gl2/function-node.js
new file mode 100644
index 00000000..69b96e14
--- /dev/null
+++ b/src/backend/web-gl2/function-node.js
@@ -0,0 +1,47 @@
+const { utils } = require('../../utils');
+const { WebGLFunctionNode } = require('../web-gl/function-node');
+
+/**
+ * @class WebGL2FunctionNode
+ * @desc [INTERNAL] Takes in a function node, and does all the AST voodoo required to toString its respective webGL code.
+ * @extends WebGLFunctionNode
+ * @returns the converted webGL function string
+ */
+class WebGL2FunctionNode extends WebGLFunctionNode {
+
+ /**
+ * @desc Parses the abstract syntax tree for *identifier* expression
+ * @param {Object} idtNode - An ast Node
+ * @param {Array} retArr - return array string
+ * @returns {Array} the append 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('intBitsToFloat(2139095039)');
+ } else if (type === 'Boolean') {
+ if (this.argumentNames.indexOf(name) > -1) {
+ retArr.push(`bool(user_${name})`);
+ } else {
+ retArr.push(`user_${name}`);
+ }
+ } else {
+ retArr.push(`user_${name}`);
+ }
+
+ return retArr;
+ }
+}
+
+module.exports = {
+ WebGL2FunctionNode
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value-maps.js b/src/backend/web-gl2/kernel-value-maps.js
new file mode 100644
index 00000000..728f592c
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value-maps.js
@@ -0,0 +1,205 @@
+const { WebGL2KernelValueBoolean } = require('./kernel-value/boolean');
+const { WebGL2KernelValueFloat } = require('./kernel-value/float');
+const { WebGL2KernelValueInteger } = require('./kernel-value/integer');
+
+const { WebGL2KernelValueHTMLImage } = require('./kernel-value/html-image');
+const { WebGL2KernelValueDynamicHTMLImage } = require('./kernel-value/dynamic-html-image');
+
+const { WebGL2KernelValueHTMLImageArray } = require('./kernel-value/html-image-array');
+const { WebGL2KernelValueDynamicHTMLImageArray } = require('./kernel-value/dynamic-html-image-array');
+
+const { WebGL2KernelValueHTMLVideo } = require('./kernel-value/html-video');
+const { WebGL2KernelValueDynamicHTMLVideo } = require('./kernel-value/dynamic-html-video');
+
+const { WebGL2KernelValueSingleInput } = require('./kernel-value/single-input');
+const { WebGL2KernelValueDynamicSingleInput } = require('./kernel-value/dynamic-single-input');
+
+const { WebGL2KernelValueUnsignedInput } = require('./kernel-value/unsigned-input');
+const { WebGL2KernelValueDynamicUnsignedInput } = require('./kernel-value/dynamic-unsigned-input');
+
+const { WebGL2KernelValueMemoryOptimizedNumberTexture } = require('./kernel-value/memory-optimized-number-texture');
+const { WebGL2KernelValueDynamicMemoryOptimizedNumberTexture } = require('./kernel-value/dynamic-memory-optimized-number-texture');
+
+const { WebGL2KernelValueNumberTexture } = require('./kernel-value/number-texture');
+const { WebGL2KernelValueDynamicNumberTexture } = require('./kernel-value/dynamic-number-texture');
+
+const { WebGL2KernelValueSingleArray } = require('./kernel-value/single-array');
+const { WebGL2KernelValueDynamicSingleArray } = require('./kernel-value/dynamic-single-array');
+
+const { WebGL2KernelValueSingleArray1DI } = require('./kernel-value/single-array1d-i');
+const { WebGL2KernelValueDynamicSingleArray1DI } = require('./kernel-value/dynamic-single-array1d-i');
+
+const { WebGL2KernelValueSingleArray2DI } = require('./kernel-value/single-array2d-i');
+const { WebGL2KernelValueDynamicSingleArray2DI } = require('./kernel-value/dynamic-single-array2d-i');
+
+const { WebGL2KernelValueSingleArray3DI } = require('./kernel-value/single-array3d-i');
+const { WebGL2KernelValueDynamicSingleArray3DI } = require('./kernel-value/dynamic-single-array3d-i');
+
+const { WebGL2KernelValueArray2 } = require('./kernel-value/array2');
+const { WebGL2KernelValueArray3 } = require('./kernel-value/array3');
+const { WebGL2KernelValueArray4 } = require('./kernel-value/array4');
+
+const { WebGL2KernelValueUnsignedArray } = require('./kernel-value/unsigned-array');
+const { WebGL2KernelValueDynamicUnsignedArray } = require('./kernel-value/dynamic-unsigned-array');
+
+const kernelValueMaps = {
+ unsigned: {
+ dynamic: {
+ 'Boolean': WebGL2KernelValueBoolean,
+ 'Integer': WebGL2KernelValueInteger,
+ 'Float': WebGL2KernelValueFloat,
+ 'Array': WebGL2KernelValueDynamicUnsignedArray,
+ 'Array(2)': WebGL2KernelValueArray2,
+ 'Array(3)': WebGL2KernelValueArray3,
+ 'Array(4)': WebGL2KernelValueArray4,
+ 'Array1D(2)': false,
+ 'Array1D(3)': false,
+ 'Array1D(4)': false,
+ 'Array2D(2)': false,
+ 'Array2D(3)': false,
+ 'Array2D(4)': false,
+ 'Array3D(2)': false,
+ 'Array3D(3)': false,
+ 'Array3D(4)': false,
+ 'Input': WebGL2KernelValueDynamicUnsignedInput,
+ 'NumberTexture': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGL2KernelValueDynamicHTMLImage,
+ 'OffscreenCanvas': WebGL2KernelValueDynamicHTMLImage,
+ 'HTMLImage': WebGL2KernelValueDynamicHTMLImage,
+ 'ImageBitmap': WebGL2KernelValueDynamicHTMLImage,
+ 'ImageData': WebGL2KernelValueDynamicHTMLImage,
+ 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray,
+ 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo,
+ },
+ static: {
+ 'Boolean': WebGL2KernelValueBoolean,
+ 'Float': WebGL2KernelValueFloat,
+ 'Integer': WebGL2KernelValueInteger,
+ 'Array': WebGL2KernelValueUnsignedArray,
+ 'Array(2)': WebGL2KernelValueArray2,
+ 'Array(3)': WebGL2KernelValueArray3,
+ 'Array(4)': WebGL2KernelValueArray4,
+ 'Array1D(2)': false,
+ 'Array1D(3)': false,
+ 'Array1D(4)': false,
+ 'Array2D(2)': false,
+ 'Array2D(3)': false,
+ 'Array2D(4)': false,
+ 'Array3D(2)': false,
+ 'Array3D(3)': false,
+ 'Array3D(4)': false,
+ 'Input': WebGL2KernelValueUnsignedInput,
+ 'NumberTexture': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(1)': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(2)': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(3)': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(4)': WebGL2KernelValueNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGL2KernelValueHTMLImage,
+ 'OffscreenCanvas': WebGL2KernelValueHTMLImage,
+ 'HTMLImage': WebGL2KernelValueHTMLImage,
+ 'ImageBitmap': WebGL2KernelValueHTMLImage,
+ 'ImageData': WebGL2KernelValueHTMLImage,
+ 'HTMLImageArray': WebGL2KernelValueHTMLImageArray,
+ 'HTMLVideo': WebGL2KernelValueHTMLVideo,
+ }
+ },
+ single: {
+ dynamic: {
+ 'Boolean': WebGL2KernelValueBoolean,
+ 'Integer': WebGL2KernelValueInteger,
+ 'Float': WebGL2KernelValueFloat,
+ 'Array': WebGL2KernelValueDynamicSingleArray,
+ 'Array(2)': WebGL2KernelValueArray2,
+ 'Array(3)': WebGL2KernelValueArray3,
+ 'Array(4)': WebGL2KernelValueArray4,
+ 'Array1D(2)': WebGL2KernelValueDynamicSingleArray1DI,
+ 'Array1D(3)': WebGL2KernelValueDynamicSingleArray1DI,
+ 'Array1D(4)': WebGL2KernelValueDynamicSingleArray1DI,
+ 'Array2D(2)': WebGL2KernelValueDynamicSingleArray2DI,
+ 'Array2D(3)': WebGL2KernelValueDynamicSingleArray2DI,
+ 'Array2D(4)': WebGL2KernelValueDynamicSingleArray2DI,
+ 'Array3D(2)': WebGL2KernelValueDynamicSingleArray3DI,
+ 'Array3D(3)': WebGL2KernelValueDynamicSingleArray3DI,
+ 'Array3D(4)': WebGL2KernelValueDynamicSingleArray3DI,
+ 'Input': WebGL2KernelValueDynamicSingleInput,
+ 'NumberTexture': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture,
+ 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGL2KernelValueDynamicHTMLImage,
+ 'OffscreenCanvas': WebGL2KernelValueDynamicHTMLImage,
+ 'HTMLImage': WebGL2KernelValueDynamicHTMLImage,
+ 'ImageBitmap': WebGL2KernelValueDynamicHTMLImage,
+ 'ImageData': WebGL2KernelValueDynamicHTMLImage,
+ 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray,
+ 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo,
+ },
+ static: {
+ 'Boolean': WebGL2KernelValueBoolean,
+ 'Float': WebGL2KernelValueFloat,
+ 'Integer': WebGL2KernelValueInteger,
+ 'Array': WebGL2KernelValueSingleArray,
+ 'Array(2)': WebGL2KernelValueArray2,
+ 'Array(3)': WebGL2KernelValueArray3,
+ 'Array(4)': WebGL2KernelValueArray4,
+ 'Array1D(2)': WebGL2KernelValueSingleArray1DI,
+ 'Array1D(3)': WebGL2KernelValueSingleArray1DI,
+ 'Array1D(4)': WebGL2KernelValueSingleArray1DI,
+ 'Array2D(2)': WebGL2KernelValueSingleArray2DI,
+ 'Array2D(3)': WebGL2KernelValueSingleArray2DI,
+ 'Array2D(4)': WebGL2KernelValueSingleArray2DI,
+ 'Array3D(2)': WebGL2KernelValueSingleArray3DI,
+ 'Array3D(3)': WebGL2KernelValueSingleArray3DI,
+ 'Array3D(4)': WebGL2KernelValueSingleArray3DI,
+ 'Input': WebGL2KernelValueSingleInput,
+ 'NumberTexture': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(1)': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(2)': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(3)': WebGL2KernelValueNumberTexture,
+ 'ArrayTexture(4)': WebGL2KernelValueNumberTexture,
+ 'MemoryOptimizedNumberTexture': WebGL2KernelValueMemoryOptimizedNumberTexture,
+ 'HTMLCanvas': WebGL2KernelValueHTMLImage,
+ 'OffscreenCanvas': WebGL2KernelValueHTMLImage,
+ 'HTMLImage': WebGL2KernelValueHTMLImage,
+ 'ImageBitmap': WebGL2KernelValueHTMLImage,
+ 'ImageData': WebGL2KernelValueHTMLImage,
+ 'HTMLImageArray': WebGL2KernelValueHTMLImageArray,
+ 'HTMLVideo': WebGL2KernelValueHTMLVideo,
+ }
+ },
+};
+
+function lookupKernelValueType(type, dynamic, precision, value) {
+ if (!type) {
+ throw new Error('type missing');
+ }
+ if (!dynamic) {
+ throw new Error('dynamic missing');
+ }
+ if (!precision) {
+ throw new Error('precision missing');
+ }
+ if (value.type) {
+ type = value.type;
+ }
+ const types = kernelValueMaps[precision][dynamic];
+ if (types[type] === false) {
+ return null;
+ } else if (types[type] === undefined) {
+ throw new Error(`Could not find a KernelValue for ${ type }`);
+ }
+ return types[type];
+}
+
+module.exports = {
+ kernelValueMaps,
+ lookupKernelValueType
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/array2.js b/src/backend/web-gl2/kernel-value/array2.js
new file mode 100644
index 00000000..dc4ffab6
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/array2.js
@@ -0,0 +1,7 @@
+const { WebGLKernelValueArray2 } = require('../../web-gl/kernel-value/array2');
+
+class WebGL2KernelValueArray2 extends WebGLKernelValueArray2 {}
+
+module.exports = {
+ WebGL2KernelValueArray2
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/array3.js b/src/backend/web-gl2/kernel-value/array3.js
new file mode 100644
index 00000000..6cf3e26a
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/array3.js
@@ -0,0 +1,7 @@
+const { WebGLKernelValueArray3 } = require('../../web-gl/kernel-value/array3');
+
+class WebGL2KernelValueArray3 extends WebGLKernelValueArray3 {}
+
+module.exports = {
+ WebGL2KernelValueArray3
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/array4.js b/src/backend/web-gl2/kernel-value/array4.js
new file mode 100644
index 00000000..839613ca
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/array4.js
@@ -0,0 +1,7 @@
+const { WebGLKernelValueArray4 } = require('../../web-gl/kernel-value/array4');
+
+class WebGL2KernelValueArray4 extends WebGLKernelValueArray4 {}
+
+module.exports = {
+ WebGL2KernelValueArray4
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/boolean.js b/src/backend/web-gl2/kernel-value/boolean.js
new file mode 100644
index 00000000..c91a61a9
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/boolean.js
@@ -0,0 +1,7 @@
+const { WebGLKernelValueBoolean } = require('../../web-gl/kernel-value/boolean');
+
+class WebGL2KernelValueBoolean extends WebGLKernelValueBoolean {}
+
+module.exports = {
+ WebGL2KernelValueBoolean
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/dynamic-html-image-array.js b/src/backend/web-gl2/kernel-value/dynamic-html-image-array.js
new file mode 100644
index 00000000..2ee88b4f
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/dynamic-html-image-array.js
@@ -0,0 +1,27 @@
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueHTMLImageArray } = require('./html-image-array');
+
+class WebGL2KernelValueDynamicHTMLImageArray extends WebGL2KernelValueHTMLImageArray {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2DArray ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(images) {
+ const { width, height } = images[0];
+ this.checkSize(width, height);
+ this.dimensions = [width, height, images.length];
+ this.textureSize = [width, height];
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(images);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicHTMLImageArray
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/dynamic-html-image.js b/src/backend/web-gl2/kernel-value/dynamic-html-image.js
new file mode 100644
index 00000000..f1ba34eb
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/dynamic-html-image.js
@@ -0,0 +1,17 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueDynamicHTMLImage } = require('../../web-gl/kernel-value/dynamic-html-image');
+
+class WebGL2KernelValueDynamicHTMLImage extends WebGLKernelValueDynamicHTMLImage {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicHTMLImage
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/dynamic-html-video.js b/src/backend/web-gl2/kernel-value/dynamic-html-video.js
new file mode 100644
index 00000000..00f723d1
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/dynamic-html-video.js
@@ -0,0 +1,8 @@
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueDynamicHTMLImage } = require('./dynamic-html-image');
+
+class WebGL2KernelValueDynamicHTMLVideo extends WebGL2KernelValueDynamicHTMLImage {}
+
+module.exports = {
+ WebGL2KernelValueDynamicHTMLVideo
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/dynamic-memory-optimized-number-texture.js b/src/backend/web-gl2/kernel-value/dynamic-memory-optimized-number-texture.js
new file mode 100644
index 00000000..5e3cff4b
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/dynamic-memory-optimized-number-texture.js
@@ -0,0 +1,16 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } = require('../../web-gl/kernel-value/dynamic-memory-optimized-number-texture');
+
+class WebGL2KernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueDynamicMemoryOptimizedNumberTexture {
+ getSource() {
+ return utils.linesToString([
+ `uniform sampler2D ${this.id}`,
+ `uniform ivec2 ${this.sizeId}`,
+ `uniform ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicMemoryOptimizedNumberTexture
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/dynamic-number-texture.js b/src/backend/web-gl2/kernel-value/dynamic-number-texture.js
new file mode 100644
index 00000000..e3820a56
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/dynamic-number-texture.js
@@ -0,0 +1,17 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueDynamicNumberTexture } = require('../../web-gl/kernel-value/dynamic-number-texture');
+
+class WebGL2KernelValueDynamicNumberTexture extends WebGLKernelValueDynamicNumberTexture {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicNumberTexture
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/dynamic-single-array.js b/src/backend/web-gl2/kernel-value/dynamic-single-array.js
new file mode 100644
index 00000000..7278317d
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/dynamic-single-array.js
@@ -0,0 +1,28 @@
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueSingleArray } = require('../../web-gl2/kernel-value/single-array');
+
+class WebGL2KernelValueDynamicSingleArray extends WebGL2KernelValueSingleArray {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.dimensions = utils.getDimensions(value, true);
+ this.textureSize = utils.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(value);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicSingleArray
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/dynamic-single-array1d-i.js b/src/backend/web-gl2/kernel-value/dynamic-single-array1d-i.js
new file mode 100644
index 00000000..45203f92
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/dynamic-single-array1d-i.js
@@ -0,0 +1,24 @@
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueSingleArray1DI } = require('../../web-gl2/kernel-value/single-array1d-i');
+
+class WebGL2KernelValueDynamicSingleArray1DI extends WebGL2KernelValueSingleArray1DI {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.setShape(value);
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicSingleArray1DI
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/dynamic-single-array2d-i.js b/src/backend/web-gl2/kernel-value/dynamic-single-array2d-i.js
new file mode 100644
index 00000000..d80f712d
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/dynamic-single-array2d-i.js
@@ -0,0 +1,24 @@
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueSingleArray2DI } = require('../../web-gl2/kernel-value/single-array2d-i');
+
+class WebGL2KernelValueDynamicSingleArray2DI extends WebGL2KernelValueSingleArray2DI {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.setShape(value);
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicSingleArray2DI
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/dynamic-single-array3d-i.js b/src/backend/web-gl2/kernel-value/dynamic-single-array3d-i.js
new file mode 100644
index 00000000..15f79ba4
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/dynamic-single-array3d-i.js
@@ -0,0 +1,24 @@
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueSingleArray3DI } = require('../../web-gl2/kernel-value/single-array3d-i');
+
+class WebGL2KernelValueDynamicSingleArray3DI extends WebGL2KernelValueSingleArray3DI {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ this.setShape(value);
+ this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);
+ this.kernel.setUniform2iv(this.sizeId, this.textureSize);
+ super.updateValue(value);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicSingleArray3DI
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/dynamic-single-input.js b/src/backend/web-gl2/kernel-value/dynamic-single-input.js
new file mode 100644
index 00000000..21fa5b31
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/dynamic-single-input.js
@@ -0,0 +1,29 @@
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueSingleInput } = require('../../web-gl2/kernel-value/single-input');
+
+class WebGL2KernelValueDynamicSingleInput extends WebGL2KernelValueSingleInput {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+
+ updateValue(value) {
+ let [w, h, d] = value.size;
+ this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);
+ this.textureSize = utils.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(value);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicSingleInput
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/dynamic-unsigned-array.js b/src/backend/web-gl2/kernel-value/dynamic-unsigned-array.js
new file mode 100644
index 00000000..514682c5
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/dynamic-unsigned-array.js
@@ -0,0 +1,17 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueDynamicUnsignedArray } = require('../../web-gl/kernel-value/dynamic-unsigned-array');
+
+class WebGL2KernelValueDynamicUnsignedArray extends WebGLKernelValueDynamicUnsignedArray {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicUnsignedArray
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/dynamic-unsigned-input.js b/src/backend/web-gl2/kernel-value/dynamic-unsigned-input.js
new file mode 100644
index 00000000..9c79330a
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/dynamic-unsigned-input.js
@@ -0,0 +1,17 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueDynamicUnsignedInput } = require('../../web-gl/kernel-value/dynamic-unsigned-input');
+
+class WebGL2KernelValueDynamicUnsignedInput extends WebGLKernelValueDynamicUnsignedInput {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,
+ `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueDynamicUnsignedInput
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/float.js b/src/backend/web-gl2/kernel-value/float.js
new file mode 100644
index 00000000..b3fc5a78
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/float.js
@@ -0,0 +1,8 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueFloat } = require('../../web-gl/kernel-value/float');
+
+class WebGL2KernelValueFloat extends WebGLKernelValueFloat {}
+
+module.exports = {
+ WebGL2KernelValueFloat
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/html-image-array.js b/src/backend/web-gl2/kernel-value/html-image-array.js
new file mode 100644
index 00000000..b7707a57
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/html-image-array.js
@@ -0,0 +1,73 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelArray } = require('../../web-gl/kernel-value/array');
+
+class WebGL2KernelValueHTMLImageArray extends WebGLKernelArray {
+ constructor(value, settings) {
+ super(value, settings);
+ this.checkSize(value[0].width, value[0].height);
+ this.dimensions = [value[0].width, value[0].height, value.length];
+ this.textureSize = [value[0].width, value[0].height];
+ }
+ defineTexture() {
+ const { context: gl } = this;
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.texture);
+ gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ }
+
+ getStringValueHandler() {
+ return `const uploadValue_${this.name} = ${this.varName};\n`;
+ }
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2DArray ${this.id}`,
+ `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,
+ ]);
+ }
+
+ updateValue(images) {
+ const { context: gl } = this;
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
+ // Upload the images into the texture.
+ gl.texImage3D(
+ gl.TEXTURE_2D_ARRAY,
+ 0,
+ gl.RGBA,
+ images[0].width,
+ images[0].height,
+ images.length,
+ 0,
+ gl.RGBA,
+ gl.UNSIGNED_BYTE,
+ null
+ );
+ for (let i = 0; i < images.length; i++) {
+ const xOffset = 0;
+ const yOffset = 0;
+ const imageDepth = 1;
+ gl.texSubImage3D(
+ gl.TEXTURE_2D_ARRAY,
+ 0,
+ xOffset,
+ yOffset,
+ i,
+ images[i].width,
+ images[i].height,
+ imageDepth,
+ gl.RGBA,
+ gl.UNSIGNED_BYTE,
+ this.uploadValue = images[i]
+ );
+ }
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueHTMLImageArray
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/html-image.js b/src/backend/web-gl2/kernel-value/html-image.js
new file mode 100644
index 00000000..637182a0
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/html-image.js
@@ -0,0 +1,17 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueHTMLImage } = require('../../web-gl/kernel-value/html-image');
+
+class WebGL2KernelValueHTMLImage extends WebGLKernelValueHTMLImage {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueHTMLImage
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/html-video.js b/src/backend/web-gl2/kernel-value/html-video.js
new file mode 100644
index 00000000..85fb3953
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/html-video.js
@@ -0,0 +1,8 @@
+const { utils } = require('../../../utils');
+const { WebGL2KernelValueHTMLImage } = require('./html-image');
+
+class WebGL2KernelValueHTMLVideo extends WebGL2KernelValueHTMLImage {}
+
+module.exports = {
+ WebGL2KernelValueHTMLVideo
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/integer.js b/src/backend/web-gl2/kernel-value/integer.js
new file mode 100644
index 00000000..8b0467c8
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/integer.js
@@ -0,0 +1,20 @@
+const { WebGLKernelValueInteger } = require('../../web-gl/kernel-value/integer');
+
+class WebGL2KernelValueInteger extends WebGLKernelValueInteger {
+ getSource(value) {
+ const variablePrecision = this.getVariablePrecisionString();
+ if (this.origin === 'constants') {
+ return `const ${ variablePrecision } int ${this.id} = ${ parseInt(value) };\n`;
+ }
+ return `uniform ${ variablePrecision } int ${this.id};\n`;
+ }
+
+ updateValue(value) {
+ if (this.origin === 'constants') return;
+ this.kernel.setUniform1i(this.id, this.uploadValue = value);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueInteger
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/memory-optimized-number-texture.js b/src/backend/web-gl2/kernel-value/memory-optimized-number-texture.js
new file mode 100644
index 00000000..7fd85798
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/memory-optimized-number-texture.js
@@ -0,0 +1,18 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueMemoryOptimizedNumberTexture } = require('../../web-gl/kernel-value/memory-optimized-number-texture');
+
+class WebGL2KernelValueMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture {
+ getSource() {
+ const { id, sizeId, textureSize, dimensionsId, dimensions } = this;
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform sampler2D ${id}`,
+ `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueMemoryOptimizedNumberTexture
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/number-texture.js b/src/backend/web-gl2/kernel-value/number-texture.js
new file mode 100644
index 00000000..440f1e4e
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/number-texture.js
@@ -0,0 +1,18 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueNumberTexture } = require('../../web-gl/kernel-value/number-texture');
+
+class WebGL2KernelValueNumberTexture extends WebGLKernelValueNumberTexture {
+ getSource() {
+ const { id, sizeId, textureSize, dimensionsId, dimensions } = this;
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${id}`,
+ `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueNumberTexture
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/single-array.js b/src/backend/web-gl2/kernel-value/single-array.js
new file mode 100644
index 00000000..c149f06f
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/single-array.js
@@ -0,0 +1,31 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray } = require('../../web-gl/kernel-value/single-array');
+
+class WebGL2KernelValueSingleArray extends WebGLKernelValueSingleArray {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,
+ ]);
+ }
+
+ updateValue(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueSingleArray
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/single-array1d-i.js b/src/backend/web-gl2/kernel-value/single-array1d-i.js
new file mode 100644
index 00000000..41de1187
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/single-array1d-i.js
@@ -0,0 +1,22 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray1DI } = require('../../web-gl/kernel-value/single-array1d-i');
+
+class WebGL2KernelValueSingleArray1DI extends WebGLKernelValueSingleArray1DI {
+ updateValue(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueSingleArray1DI
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/single-array2d-i.js b/src/backend/web-gl2/kernel-value/single-array2d-i.js
new file mode 100644
index 00000000..f7723860
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/single-array2d-i.js
@@ -0,0 +1,22 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray2DI } = require('../../web-gl/kernel-value/single-array2d-i');
+
+class WebGL2KernelValueSingleArray2DI extends WebGLKernelValueSingleArray2DI {
+ updateValue(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueSingleArray2DI
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/single-array3d-i.js b/src/backend/web-gl2/kernel-value/single-array3d-i.js
new file mode 100644
index 00000000..904f4bfd
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/single-array3d-i.js
@@ -0,0 +1,22 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleArray3DI } = require('../../web-gl/kernel-value/single-array3d-i');
+
+class WebGL2KernelValueSingleArray3DI extends WebGLKernelValueSingleArray3DI {
+ updateValue(value) {
+ if (value.constructor !== this.initialValueConstructor) {
+ this.onUpdateValueMismatch(value.constructor);
+ return;
+ }
+ const { context: gl } = this;
+ utils.flattenTo(value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueSingleArray3DI
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/single-input.js b/src/backend/web-gl2/kernel-value/single-input.js
new file mode 100644
index 00000000..261168e2
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/single-input.js
@@ -0,0 +1,27 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueSingleInput } = require('../../web-gl/kernel-value/single-input');
+
+class WebGL2KernelValueSingleInput extends WebGLKernelValueSingleInput {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,
+ ]);
+ }
+
+ updateValue(input) {
+ const { context: gl } = this;
+ utils.flattenTo(input.value, this.uploadValue);
+ gl.activeTexture(this.contextHandle);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);
+ this.kernel.setUniform1i(this.id, this.index);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueSingleInput
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/unsigned-array.js b/src/backend/web-gl2/kernel-value/unsigned-array.js
new file mode 100644
index 00000000..bac1e6f1
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/unsigned-array.js
@@ -0,0 +1,17 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueUnsignedArray } = require('../../web-gl/kernel-value/unsigned-array');
+
+class WebGL2KernelValueUnsignedArray extends WebGLKernelValueUnsignedArray {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueUnsignedArray
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel-value/unsigned-input.js b/src/backend/web-gl2/kernel-value/unsigned-input.js
new file mode 100644
index 00000000..ed933347
--- /dev/null
+++ b/src/backend/web-gl2/kernel-value/unsigned-input.js
@@ -0,0 +1,17 @@
+const { utils } = require('../../../utils');
+const { WebGLKernelValueUnsignedInput } = require('../../web-gl/kernel-value/unsigned-input');
+
+class WebGL2KernelValueUnsignedInput extends WebGLKernelValueUnsignedInput {
+ getSource() {
+ const variablePrecision = this.getVariablePrecisionString();
+ return utils.linesToString([
+ `uniform ${ variablePrecision } sampler2D ${this.id}`,
+ `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,
+ `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,
+ ]);
+ }
+}
+
+module.exports = {
+ WebGL2KernelValueUnsignedInput
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/kernel.js b/src/backend/web-gl2/kernel.js
new file mode 100644
index 00000000..52adbd60
--- /dev/null
+++ b/src/backend/web-gl2/kernel.js
@@ -0,0 +1,641 @@
+const { WebGLKernel } = require('../web-gl/kernel');
+const { WebGL2FunctionNode } = require('./function-node');
+const { FunctionBuilder } = require('../function-builder');
+const { utils } = require('../../utils');
+const { fragmentShader } = require('./fragment-shader');
+const { vertexShader } = require('./vertex-shader');
+const { lookupKernelValueType } = require('./kernel-value-maps');
+
+let isSupported = null;
+/**
+ *
+ * @type {HTMLCanvasElement|OffscreenCanvas}
+ */
+let testCanvas = null;
+/**
+ *
+ * @type {WebGLRenderingContext}
+ */
+let testContext = null;
+let testExtensions = null;
+
+/**
+ *
+ * @type {IKernelFeatures}
+ */
+let features = null;
+
+/**
+ * @extends WebGLKernel
+ */
+class WebGL2Kernel extends WebGLKernel {
+ static get isSupported() {
+ if (isSupported !== null) {
+ return isSupported;
+ }
+ this.setupFeatureChecks();
+ isSupported = this.isContextMatch(testContext);
+ return isSupported;
+ }
+
+ static setupFeatureChecks() {
+ if (typeof document !== 'undefined') {
+ testCanvas = document.createElement('canvas');
+ } else if (typeof OffscreenCanvas !== 'undefined') {
+ testCanvas = new OffscreenCanvas(0, 0);
+ }
+ if (!testCanvas) return;
+ testContext = testCanvas.getContext('webgl2');
+ if (!testContext || !testContext.getExtension) return;
+ testExtensions = {
+ EXT_color_buffer_float: testContext.getExtension('EXT_color_buffer_float'),
+ OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'),
+ };
+ features = this.getFeatures();
+ }
+
+ static isContextMatch(context) {
+ // from global
+ if (typeof WebGL2RenderingContext !== 'undefined') {
+ return context instanceof WebGL2RenderingContext;
+ }
+ return false;
+ }
+
+ /**
+ *
+ * @return {IKernelFeatures}
+ */
+ static getFeatures() {
+ const gl = this.testContext;
+ return Object.freeze({
+ isFloatRead: this.getIsFloatRead(),
+ isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(),
+ isSpeedTacticSupported: this.getIsSpeedTacticSupported(),
+ kernelMap: true,
+ isTextureFloat: true,
+ isDrawBuffers: true,
+ channelCount: this.getChannelCount(),
+ maxTextureSize: this.getMaxTextureSize(),
+ lowIntPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_INT),
+ lowFloatPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_FLOAT),
+ mediumIntPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_INT),
+ mediumFloatPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT),
+ highIntPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_INT),
+ highFloatPrecision: gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT),
+ });
+ }
+
+ static getIsTextureFloat() {
+ return true;
+ }
+
+ static getChannelCount() {
+ return testContext.getParameter(testContext.MAX_DRAW_BUFFERS);
+ }
+
+ static getMaxTextureSize() {
+ return testContext.getParameter(testContext.MAX_TEXTURE_SIZE);
+ }
+
+ static lookupKernelValueType(type, dynamic, precision, value) {
+ return lookupKernelValueType(type, dynamic, precision, value);
+ }
+
+ static get testCanvas() {
+ return testCanvas;
+ }
+
+ static get testContext() {
+ return testContext;
+ }
+
+ /**
+ *
+ * @returns {{isFloatRead: Boolean, isIntegerDivisionAccurate: Boolean, kernelMap: Boolean, isTextureFloat: Boolean}}
+ */
+ static get features() {
+ return features;
+ }
+
+ static get fragmentShader() {
+ return fragmentShader;
+ }
+ static get vertexShader() {
+ return vertexShader;
+ }
+
+ /**
+ *
+ * @return {WebGLRenderingContext|WebGL2RenderingContext}
+ */
+ initContext() {
+ const settings = {
+ alpha: false,
+ depth: false,
+ antialias: false
+ };
+ return this.canvas.getContext('webgl2', settings);
+ }
+
+ 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'),
+ };
+ }
+
+ /**
+ * @desc Validate settings related to Kernel, such as dimensions size, and auto output support.
+ * @param {IArguments} args
+ */
+ validateSettings(args) {
+ if (!this.validate) {
+ this.texSize = utils.getKernelTextureSize({
+ optimizeFloatMemory: this.optimizeFloatMemory,
+ precision: this.precision,
+ }, this.output);
+ return;
+ }
+
+ const { features } = this.constructor;
+ if (this.precision === 'single' && !features.isFloatRead) {
+ throw new Error('Float texture outputs are not supported');
+ } else if (!this.graphical && this.precision === null) {
+ this.precision = features.isFloatRead ? 'single' : 'unsigned';
+ }
+
+ if (this.fixIntegerDivisionAccuracy === null) {
+ this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate;
+ } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) {
+ this.fixIntegerDivisionAccuracy = false;
+ }
+
+ this.checkOutput();
+
+ 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);
+ switch (argType) {
+ case 'Array':
+ this.output = utils.getDimensions(argType);
+ break;
+ case 'NumberTexture':
+ case 'MemoryOptimizedNumberTexture':
+ case 'ArrayTexture(1)':
+ case 'ArrayTexture(2)':
+ case 'ArrayTexture(3)':
+ case 'ArrayTexture(4)':
+ this.output = args[0].output;
+ break;
+ default:
+ throw new Error('Auto output not supported for input type: ' + argType);
+ }
+ }
+
+ if (this.graphical) {
+ if (this.output.length !== 2) {
+ throw new Error('Output must have 2 dimensions on graphical mode');
+ }
+
+ if (this.precision === 'single') {
+ console.warn('Cannot use graphical mode and single precision at the same time');
+ this.precision = 'unsigned';
+ }
+
+ this.texSize = utils.clone(this.output);
+ return;
+ } else if (!this.graphical && this.precision === null && features.isTextureFloat) {
+ this.precision = 'single';
+ }
+
+ this.texSize = utils.getKernelTextureSize({
+ optimizeFloatMemory: this.optimizeFloatMemory,
+ precision: this.precision,
+ }, this.output);
+
+ this.checkTextureSize();
+ }
+
+ translateSource() {
+ const functionBuilder = FunctionBuilder.fromKernel(this, WebGL2FunctionNode, {
+ fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy
+ });
+ this.translatedSource = functionBuilder.getPrototypeString('kernel');
+ this.setupReturnTypes(functionBuilder);
+ }
+
+ drawBuffers() {
+ this.context.drawBuffers(this.drawBuffersMap);
+ }
+
+ getTextureFormat() {
+ const { context: gl } = this;
+ switch (this.getInternalFormat()) {
+ case gl.R32F:
+ return gl.RED;
+ case gl.RG32F:
+ return gl.RG;
+ case gl.RGBA32F:
+ return gl.RGBA;
+ case gl.RGBA:
+ return gl.RGBA;
+ default:
+ throw new Error('Unknown internal format');
+ }
+ }
+ getInternalFormat() {
+ const { context: gl } = this;
+
+ if (this.precision === 'single') {
+ if (this.pipeline) {
+ switch (this.returnType) {
+ case 'Number':
+ case 'Float':
+ case 'Integer':
+ if (this.optimizeFloatMemory) {
+ return gl.RGBA32F;
+ } else {
+ return gl.R32F;
+ }
+ case 'Array(2)':
+ return gl.RG32F;
+ case 'Array(3)': // there is _no_ 3 channel format which is guaranteed to be color-renderable
+ case 'Array(4)':
+ return gl.RGBA32F;
+ default:
+ throw new Error('Unhandled return type');
+ }
+ }
+ return gl.RGBA32F;
+ }
+ return gl.RGBA;
+ }
+
+ _setupOutputTexture() {
+ const gl = this.context;
+ if (this.texture) {
+ // here we inherit from an already existing kernel, so go ahead and just bind textures to the framebuffer
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture.texture, 0);
+ return;
+ }
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
+ const texture = gl.createTexture();
+ const texSize = this.texSize;
+ gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ const format = this.getInternalFormat();
+ if (this.precision === 'single') {
+ gl.texStorage2D(gl.TEXTURE_2D, 1, format, texSize[0], texSize[1]);
+ } else {
+ gl.texImage2D(gl.TEXTURE_2D, 0, format, texSize[0], texSize[1], 0, format, gl.UNSIGNED_BYTE, null);
+ }
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ this.texture = new this.TextureConstructor({
+ texture,
+ size: texSize,
+ dimensions: this.threadDim,
+ output: this.output,
+ context: this.context,
+ internalFormat: this.getInternalFormat(),
+ textureFormat: this.getTextureFormat(),
+ kernel: this,
+ });
+ }
+
+ _setupSubOutputTextures() {
+ const gl = this.context;
+ if (this.mappedTextures) {
+ // here we inherit from an already existing kernel, so go ahead and just bind textures to the framebuffer
+ for (let i = 0; i < this.subKernels.length; i++) {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, this.mappedTextures[i].texture, 0);
+ }
+ return;
+ }
+ const texSize = this.texSize;
+ this.drawBuffersMap = [gl.COLOR_ATTACHMENT0];
+ this.mappedTextures = [];
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const texture = this.createTexture();
+ this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1);
+ gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ // TODO: upgrade this
+ const format = this.getInternalFormat();
+ if (this.precision === 'single') {
+ gl.texStorage2D(gl.TEXTURE_2D, 1, format, texSize[0], texSize[1]);
+ // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);
+ } else {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ }
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0);
+
+ this.mappedTextures.push(new this.TextureConstructor({
+ texture,
+ size: texSize,
+ dimensions: this.threadDim,
+ output: this.output,
+ context: this.context,
+ internalFormat: this.getInternalFormat(),
+ textureFormat: this.getTextureFormat(),
+ kernel: this,
+ }));
+ }
+ }
+
+ /**
+ *
+ * @desc Get the header string for the program.
+ * This returns an empty string if no sub-kernels are defined.
+ *
+ * @returns {String} result
+ */
+ _getHeaderString() {
+ return '';
+ }
+
+ /**
+ * @desc Get texture coordinate string for the program
+ * @returns {String} result
+ */
+ _getTextureCoordinate() {
+ const subKernels = this.subKernels;
+ const variablePrecision = this.getVariablePrecisionString(this.texSize, this.tactic);
+ if (subKernels === null || subKernels.length < 1) {
+ return `in ${ variablePrecision } vec2 vTexCoord;\n`;
+ } else {
+ return `out ${ variablePrecision } vec2 vTexCoord;\n`;
+ }
+ }
+
+ /**
+ * @desc Generate transpiled glsl Strings for user-defined parameters sent to a kernel
+ * @param {Array} args - The actual parameters sent to the Kernel
+ * @returns {String} result
+ */
+ _getMainArgumentsString(args) {
+ const result = [];
+ const argumentNames = this.argumentNames;
+ for (let i = 0; i < argumentNames.length; i++) {
+ result.push(this.kernelArguments[i].getSource(args[i]));
+ }
+ return result.join('');
+ }
+
+ /**
+ * @desc Get Kernel program string (in *glsl*) for a kernel.
+ * @returns {String} result
+ */
+ getKernelString() {
+ const result = [this.getKernelResultDeclaration()];
+ const subKernels = this.subKernels;
+ if (subKernels !== null) {
+ result.push(
+ 'layout(location = 0) out vec4 data0'
+ );
+ switch (this.returnType) {
+ case 'Number':
+ case 'Float':
+ case 'Integer':
+ for (let i = 0; i < subKernels.length; i++) {
+ const subKernel = subKernels[i];
+ result.push(
+ subKernel.returnType === 'Integer' ?
+ `int subKernelResult_${ subKernel.name } = 0` :
+ `float subKernelResult_${ subKernel.name } = 0.0`,
+ `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }`
+ );
+ }
+ break;
+ case 'Array(2)':
+ for (let i = 0; i < subKernels.length; i++) {
+ result.push(
+ `vec2 subKernelResult_${ subKernels[i].name }`,
+ `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }`
+ );
+ }
+ break;
+ case 'Array(3)':
+ for (let i = 0; i < subKernels.length; i++) {
+ result.push(
+ `vec3 subKernelResult_${ subKernels[i].name }`,
+ `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }`
+ );
+ }
+ break;
+ case 'Array(4)':
+ for (let i = 0; i < subKernels.length; i++) {
+ result.push(
+ `vec4 subKernelResult_${ subKernels[i].name }`,
+ `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }`
+ );
+ }
+ break;
+ }
+ } else {
+ result.push(
+ 'out vec4 data0'
+ );
+ }
+
+ return utils.linesToString(result) + this.translatedSource;
+ }
+
+ getMainResultGraphical() {
+ return utils.linesToString([
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' data0 = actualColor',
+ ]);
+ }
+
+ getMainResultPackedPixels() {
+ switch (this.returnType) {
+ case 'LiteralInteger':
+ case 'Number':
+ case 'Integer':
+ case 'Float':
+ return this.getMainResultKernelPackedPixels() +
+ this.getMainResultSubKernelPackedPixels();
+ default:
+ throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`);
+ }
+ }
+
+ /**
+ * @return {String}
+ */
+ getMainResultKernelPackedPixels() {
+ return utils.linesToString([
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ` data0 = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)`
+ ]);
+ }
+
+ /**
+ * @return {String}
+ */
+ getMainResultSubKernelPackedPixels() {
+ const result = [];
+ if (!this.subKernels) return '';
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const subKernel = this.subKernels[i];
+ if (subKernel.returnType === 'Integer') {
+ result.push(
+ ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))`
+ );
+ } else {
+ result.push(
+ ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})`
+ );
+ }
+ }
+ return utils.linesToString(result);
+ }
+
+ getMainResultKernelMemoryOptimizedFloats(result, channel) {
+ result.push(
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ` data0.${channel} = kernelResult`
+ );
+ }
+
+ getMainResultSubKernelMemoryOptimizedFloats(result, channel) {
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; i++) {
+ const subKernel = this.subKernels[i];
+ if (subKernel.returnType === 'Integer') {
+ result.push(
+ ` data${i + 1}.${channel} = float(subKernelResult_${subKernel.name})`
+ );
+ } else {
+ result.push(
+ ` data${i + 1}.${channel} = subKernelResult_${subKernel.name}`
+ );
+ }
+ }
+ }
+
+ getMainResultKernelNumberTexture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' data0[0] = kernelResult',
+ ];
+ }
+
+ getMainResultSubKernelNumberTexture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ const subKernel = this.subKernels[i];
+ if (subKernel.returnType === 'Integer') {
+ result.push(
+ ` data${i + 1}[0] = float(subKernelResult_${subKernel.name})`
+ );
+ } else {
+ result.push(
+ ` data${i + 1}[0] = subKernelResult_${subKernel.name}`
+ );
+ }
+ }
+ return result;
+ }
+
+ getMainResultKernelArray2Texture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' data0[0] = kernelResult[0]',
+ ' data0[1] = kernelResult[1]',
+ ];
+ }
+
+ getMainResultSubKernelArray2Texture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ const subKernel = this.subKernels[i];
+ result.push(
+ ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`,
+ ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`
+ );
+ }
+ return result;
+ }
+
+ getMainResultKernelArray3Texture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' data0[0] = kernelResult[0]',
+ ' data0[1] = kernelResult[1]',
+ ' data0[2] = kernelResult[2]',
+ ];
+ }
+
+ getMainResultSubKernelArray3Texture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ const subKernel = this.subKernels[i];
+ result.push(
+ ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`,
+ ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`,
+ ` data${i + 1}[2] = subKernelResult_${subKernel.name}[2]`
+ );
+ }
+ return result;
+ }
+
+ getMainResultKernelArray4Texture() {
+ return [
+ ' threadId = indexTo3D(index, uOutputDim)',
+ ' kernel()',
+ ' data0 = kernelResult',
+ ];
+ }
+
+ getMainResultSubKernelArray4Texture() {
+ const result = [];
+ if (!this.subKernels) return result;
+ for (let i = 0; i < this.subKernels.length; ++i) {
+ result.push(
+ ` data${i + 1} = subKernelResult_${this.subKernels[i].name}`
+ );
+ }
+ return result;
+ }
+
+ destroyExtensions() {
+ this.extensions.EXT_color_buffer_float = null;
+ this.extensions.OES_texture_float_linear = null;
+ }
+
+ /**
+ * @return {IKernelJSON}
+ */
+ toJSON() {
+ const json = super.toJSON();
+ json.functionNodes = FunctionBuilder.fromKernel(this, WebGL2FunctionNode).toJSON();
+ json.settings.threadDim = this.threadDim;
+ return json;
+ }
+}
+
+module.exports = {
+ WebGL2Kernel
+};
\ No newline at end of file
diff --git a/src/backend/web-gl2/vertex-shader.js b/src/backend/web-gl2/vertex-shader.js
new file mode 100644
index 00000000..e44dc986
--- /dev/null
+++ b/src/backend/web-gl2/vertex-shader.js
@@ -0,0 +1,20 @@
+// language=GLSL
+const vertexShader = `#version 300 es
+__FLOAT_TACTIC_DECLARATION__;
+__INT_TACTIC_DECLARATION__;
+__SAMPLER_2D_TACTIC_DECLARATION__;
+
+in vec2 aPos;
+in vec2 aTexCoord;
+
+out vec2 vTexCoord;
+uniform vec2 ratio;
+
+void main(void) {
+ gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);
+ vTexCoord = aTexCoord;
+}`;
+
+module.exports = {
+ vertexShader
+};
\ No newline at end of file
diff --git a/src/wrapper/header.js b/src/browser-header.txt
similarity index 100%
rename from src/wrapper/header.js
rename to src/browser-header.txt
diff --git a/src/browser.js b/src/browser.js
new file mode 100644
index 00000000..740a38dc
--- /dev/null
+++ b/src/browser.js
@@ -0,0 +1,25 @@
+const lib = require('./index');
+const GPU = lib.GPU;
+for (const p in lib) {
+ if (!lib.hasOwnProperty(p)) continue;
+ if (p === 'GPU') continue; //prevent recursive reference
+ GPU[p] = lib[p];
+}
+
+if (typeof window !== 'undefined') {
+ bindTo(window);
+}
+if (typeof self !== 'undefined') {
+ bindTo(self);
+}
+
+function bindTo(target) {
+ if (target.GPU) return;
+ Object.defineProperty(target, 'GPU', {
+ get() {
+ return GPU;
+ }
+ });
+}
+
+module.exports = lib;
\ No newline at end of file
diff --git a/src/core/alias.js b/src/core/alias.js
deleted file mode 100644
index 39a60afb..00000000
--- a/src/core/alias.js
+++ /dev/null
@@ -1,7 +0,0 @@
-'use strict';
-
-const utils = require('./utils');
-module.exports = function alias(name, fn) {
- const fnString = fn.toString();
- return new Function(`return function ${ name } (${ utils.getParamNamesFromString(fnString).join(', ') }) {${ utils.getFunctionBodyFromString(fnString) }}`)();
-};
\ No newline at end of file
diff --git a/src/core/gpu-core.js b/src/core/gpu-core.js
deleted file mode 100644
index 77630435..00000000
--- a/src/core/gpu-core.js
+++ /dev/null
@@ -1,90 +0,0 @@
-'use strict';
-
-const UtilsCore = require("./utils-core");
-
-/**
- * This is a minimalistic version of GPU.js used
- * to run precompiled GPU.JS code.
- *
- * This intentionally excludes the JS AST compiller : which is 400kb alone/
- *
- * @class GPUCore
- */
-module.exports = class GPUCore {
-
- /**
- * @name validateKernelObj
- * @function
- * @static
- * @memberOf GPUCore
- *
- * @description Validates the KernelObj to comply with the defined format
- * Note that this does only a limited sanity check, and does not
- * guarantee a full working validation.
- *
- * For the kernel object format see :
- *
- * @param {Object|String} kernelObj - KernelObj used to validate
- *
- * @returns {Object} The validated kernel object, converted from JSON if needed
- *
- */
- static validateKernelObj(kernelObj) {
-
- // NULL validation
- if (kernelObj === null) {
- throw "KernelObj being validated is NULL";
- }
-
- // String JSON conversion
- if (typeof kernelObj === "string") {
- try {
- kernelObj = JSON.parse(kernelObj);
- } catch (e) {
- console.error(e);
- throw "Failed to convert KernelObj from JSON string";
- }
-
- // NULL validation
- if (kernelObj === null) {
- throw "Invalid (NULL) KernelObj JSON string representation";
- }
- }
-
- // Check for kernel obj flag
- if (kernelObj.isKernelObj !== true) {
- throw "Failed missing isKernelObj flag check";
- }
-
- // Return the validated kernelObj
- return kernelObj;
- }
-
- /**
- * @name loadKernelObj
- * @function
- * @static
- * @memberOf GPUCore
- *
- * @description Loads the precompiled kernel object. For GPUCore this is the ONLY way to create the kernel.
- * To generate the kernelObj use
- *
- * Note that this function calls internally, and throws an exception if it fails.
- *
- * @see GPUCore.validateKernelObj
- * @see Kernel.exportKernelObj
- *
- * @param {Object} kernelObj - The precompiled kernel object
- * @param {Object} inOpt - [Optional] the option overrides to use
- *
- * @returns {Function} The kernel function
- *
- */
- static loadKernelObj(kernelObj, inOpt) {
-
- // Validates the kernelObj, throws an exception if it fails
- kernelObj = validateKernelObj(kernelObj);
-
-
- }
-};
\ No newline at end of file
diff --git a/src/core/gpu.js b/src/core/gpu.js
deleted file mode 100644
index 192c3bc7..00000000
--- a/src/core/gpu.js
+++ /dev/null
@@ -1,346 +0,0 @@
-'use strict';
-
-const utils = require('./utils');
-const WebGLRunner = require('../backend/web-gl/runner');
-const CPURunner = require('../backend/cpu/runner');
-const WebGLValidatorKernel = require('../backend/web-gl/validator-kernel');
-const GPUCore = require("./gpu-core");
-
-/**
- * Initialises the GPU.js library class which manages the webGlContext for the created functions.
- * @class
- * @extends GPUCore
- */
-class GPU extends GPUCore {
- /**
- * Creates an instance of GPU.
- * @param {any} settings - Settings to set mode, andother properties. See #GPUCore
- * @memberOf GPU#
- */
- constructor(settings) {
- super(settings);
-
- settings = settings || {};
- this._canvas = settings.canvas || null;
- this._webGl = settings.webGl || null;
- let mode = settings.mode || 'webgl';
- if (!utils.isWebGlSupported()) {
- console.warn('Warning: gpu not supported, falling back to cpu support');
- mode = 'cpu';
- }
-
- this.kernels = [];
-
- const runnerSettings = {
- canvas: this._canvas,
- webGl: this._webGl
- };
-
- if (mode) {
- switch (mode.toLowerCase()) {
- case 'cpu':
- this._runner = new CPURunner(runnerSettings);
- break;
- case 'gpu':
- case 'webgl':
- this._runner = new WebGLRunner(runnerSettings);
- break;
- case 'webgl-validator':
- this._runner = new WebGLRunner(runnerSettings);
- this._runner.Kernel = WebGLValidatorKernel;
- break;
- default:
- throw new Error(`"${mode}" mode is not defined`);
- }
- }
- }
- /**
- *
- * This creates a callable function object to call the kernel function with the argument parameter set
- *
- * @name createKernel
- * @function
- * @memberOf GPU##
- *
- * @param {Function} inputFunction - The calling to perform the conversion
- * @param {Object} settings - The parameter configuration object
- * @property {String} settings.dimensions - Thread dimension array (Defeaults to [1024])
- * @property {String} settings.mode - CPU / GPU configuration mode (Defaults to null)
- *
- * The following modes are supported
- * *null* / *'auto'* : Attempts to build GPU mode, else fallbacks
- * *'gpu'* : Attempts to build GPU mode, else fallbacks
- * *'cpu'* : Forces JS fallback mode only
- *
- *
- * @returns {Function} callable function to run
- *
- */
- createKernel(fn, settings) {
- //
- // basic parameters safety checks
- //
- if (typeof fn === 'undefined') {
- throw 'Missing fn parameter';
- }
- if (!utils.isFunction(fn) && typeof fn !== 'string') {
- throw 'fn parameter not a function';
- }
-
- const kernel = this._runner.buildKernel(fn, settings || {});
-
- //if canvas didn't come from this, propagate from kernel
- if (!this._canvas) {
- this._canvas = kernel.getCanvas();
- }
- if (!this._runner.canvas) {
- this._runner.canvas = kernel.getCanvas();
- }
-
- this.kernels.push(kernel);
-
- return kernel;
- }
-
- /**
- *
- * Create a super kernel which executes sub kernels
- * and saves their output to be used with the next sub kernel.
- * This can be useful if we want to save the output on one kernel,
- * and then use it as an input to another kernel. *Machine Learning*
- *
- * @name createKernelMap
- * @function
- * @memberOf GPU#
- *
- * @param {Object|Array} subKernels - Sub kernels for this kernel
- * @param {Function} rootKernel - Root kernel
- *
- * @returns {Function} callable kernel function
- *
- * @example
- * const megaKernel = gpu.createKernelMap({
- * addResult: function add(a, b) {
- * return a[this.thread.x] + b[this.thread.x];
- * },
- * multiplyResult: function multiply(a, b) {
- * return a[this.thread.x] * b[this.thread.x];
- * },
- * }, function(a, b, c) {
- * return multiply(add(a, b), c);
- * });
- *
- * megaKernel(a, b, c);
- *
- * Note: You can also define subKernels as an array of functions.
- * > [add, multiply]
- *
- */
- createKernelMap() {
- let fn;
- let settings;
- if (typeof arguments[arguments.length - 2] === 'function') {
- fn = arguments[arguments.length - 2];
- settings = arguments[arguments.length - 1];
- } else {
- fn = arguments[arguments.length - 1];
- }
-
- if (!utils.isWebGlDrawBuffersSupported()) {
- this._runner = new CPURunner(settings);
- }
-
- const kernel = this.createKernel(fn, settings);
- if (Array.isArray(arguments[0])) {
- const functions = arguments[0];
- for (let i = 0; i < functions.length; i++) {
- kernel.addSubKernel(functions[i]);
- }
- } else {
- const functions = arguments[0];
- for (let p in functions) {
- if (!functions.hasOwnProperty(p)) continue;
- kernel.addSubKernelProperty(p, functions[p]);
- }
- }
-
- return kernel;
- }
-
- /**
- *
- * Combine different kernels into one super Kernel,
- * useful to perform multiple operations inside one
- * kernel without the penalty of data transfer between
- * cpu and gpu.
- *
- * The number of kernel functions sent to this method can be variable.
- * You can send in one, two, etc.
- *
- * @name combineKernels
- * @function
- * @memberOf GPU#
- *
- * @param {Function} subKernels - Kernel function(s) to combine.
- * @param {Function} rootKernel - Root kernel to combine kernels into
- *
- * @example
- * combineKernels(add, multiply, function(a,b,c){
- * return add(multiply(a,b), c)
- * })
- *
- * @returns {Function} Callable kernel function
- *
- */
- combineKernels() {
- const lastKernel = arguments[arguments.length - 2];
- const combinedKernel = arguments[arguments.length - 1];
- if (this.getMode() === 'cpu') return combinedKernel;
-
- const canvas = arguments[0].getCanvas();
- let webGl = arguments[0].getWebGl();
-
- for (let i = 0; i < arguments.length - 1; i++) {
- arguments[i]
- .setCanvas(canvas)
- .setWebGl(webGl)
- .setOutputToTexture(true);
- }
-
- return function() {
- combinedKernel.apply(null, arguments);
- const texSize = lastKernel.texSize;
- const gl = lastKernel.getWebGl();
- const threadDim = lastKernel.threadDim;
- let result;
- if (lastKernel.floatOutput) {
- result = new Float32Array(texSize[0] * texSize[1] * 4);
- gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.FLOAT, result);
- } else {
- const bytes = new Uint8Array(texSize[0] * texSize[1] * 4);
- gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, bytes);
- result = new Float32Array(bytes.buffer);
- }
-
- result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]);
-
- if (lastKernel.output.length === 1) {
- return result;
- } else if (lastKernel.output.length === 2) {
- return utils.splitArray(result, lastKernel.output[0]);
- } else if (lastKernel.output.length === 3) {
- const cube = utils.splitArray(result, lastKernel.output[0] * lastKernel.output[1]);
- return cube.map(function(x) {
- return utils.splitArray(x, lastKernel.output[0]);
- });
- }
- };
- }
-
-
- /**
- *
- * Adds additional functions, that the kernel may call.
- *
- * @name addFunction
- * @function
- * @memberOf GPU#
- *
- * @param {Function|String} fn - JS Function to do conversion
- * @param {String[]|Object} paramTypes - Parameter type array, assumes all parameters are 'float' if null
- * @param {String} returnType - The return type, assumes 'float' if null
- *
- * @returns {GPU} returns itself
- *
- */
- addFunction(fn, paramTypes, returnType) {
- this._runner.functionBuilder.addFunction(null, fn, paramTypes, returnType);
- return this;
- }
-
- /**
- *
- * Adds additional native functions, that the kernel may call.
- *
- * @name addNativeFunction
- * @function
- * @memberOf GPU#
- *
- * @param {String} name - native function name, used for reverse lookup
- * @param {String} nativeFunction - the native function implementation, as it would be defined in it's entirety
- *
- * @returns {GPU} returns itself
- *
- */
- addNativeFunction(name, nativeFunction) {
- this._runner.functionBuilder.addNativeFunction(name, nativeFunction);
- return this;
- }
-
- /**
- *
- * Return the current mode in which gpu.js is executing.
- * @name getMode
- * @function
- * @memberOf GPU#
- *
- * @returns {String} The current mode, "cpu", "webgl", etc.
- *
- */
- getMode() {
- return this._runner.getMode();
- }
-
- /**
- *
- * Return TRUE, if browser supports WebGl AND Canvas
- *
- * @name get isWebGlSupported
- * @function
- * @memberOf GPU#
- *
- * Note: This function can also be called directly `GPU.isWebGlSupported()`
- *
- * @returns {Boolean} TRUE if browser supports webGl
- *
- */
- isWebGlSupported() {
- return utils.isWebGlSupported();
- }
-
- /**
- *
- * Return the canvas object bound to this gpu instance.
- *
- * @name getCanvas
- * @function
- * @memberOf GPU#
- *
- * @returns {Object} Canvas object if present
- *
- */
- getCanvas() {
- return this._canvas;
- }
-
- /**
- *
- * Return the webGl object bound to this gpu instance.
- *
- * @name getWebGl
- * @function
- * @memberOf GPU#
- *
- * @returns {Object} WebGl object if present
- *
- */
- getWebGl() {
- return this._webGl;
- }
-};
-
-// This ensure static methods are "inherited"
-// See: https://stackoverflow.com/questions/5441508/how-to-inherit-static-methods-from-base-class-in-javascript
-Object.assign(GPU, GPUCore);
-
-module.exports = GPU;
\ No newline at end of file
diff --git a/src/core/input.js b/src/core/input.js
deleted file mode 100644
index c5c3fe89..00000000
--- a/src/core/input.js
+++ /dev/null
@@ -1,22 +0,0 @@
-module.exports = class Input {
- constructor(value, size) {
- this.value = value;
- if (Array.isArray(size)) {
- this.size = [];
- for (let i = 0; i < size.length; i++) {
- this.size[i] = size[i];
- }
- while (this.size.length < 3) {
- this.size.push(1);
- }
- } else {
- if (size.z) {
- this.size = [size.x, size.y, size.z];
- } else if (size.y) {
- this.size = [size.x, size.y, 1];
- } else {
- this.size = [size.x, 1, 1];
- }
- }
- }
-};
\ No newline at end of file
diff --git a/src/core/texture.js b/src/core/texture.js
deleted file mode 100644
index 31a64ac0..00000000
--- a/src/core/texture.js
+++ /dev/null
@@ -1,55 +0,0 @@
-'use strict';
-
-let gpu = null;
-
-module.exports = class Texture {
-
- /**
- * @desc WebGl Texture implementation in JS
- * @constructor Texture
- * @param {Object} texture
- * @param {Array} size
- * @param {Array} output
- * @param {Object} webGl
- */
- constructor(texture, size, output, webGl) {
- this.texture = texture;
- this.size = size;
- this.output = output;
- this.webGl = webGl;
- this.kernel = null;
- }
-
- /**
- * @name toArray
- * @function
- * @memberOf Texture#
- *
- * @desc Converts the Texture into a JavaScript Array.
- *
- * @param {Object} The `gpu` Object
- *
- */
- toArray(gpu) {
- if (!gpu) throw new Error('You need to pass the GPU object for toArray to work.');
- if (this.kernel) return this.kernel(this);
-
- this.kernel = gpu.createKernel(function(x) {
- return x[this.thread.z][this.thread.y][this.thread.x];
- }).setOutput(this.output);
-
- return this.kernel(this);
- }
-
- /**
- * @name delete
- * @desc Deletes the Texture.
- * @function
- * @memberOf Texture#
- *
- *
- */
- delete() {
- return this.webGl.deleteTexture(this.texture);
- }
-};
\ No newline at end of file
diff --git a/src/core/utils-core.js b/src/core/utils-core.js
deleted file mode 100644
index 8f0d7907..00000000
--- a/src/core/utils-core.js
+++ /dev/null
@@ -1,223 +0,0 @@
-'use strict';
-
-/**
- *
- * @desc Reduced subset of Utils, used exclusively in gpu-core.js
- * Various utility functions / snippets of code that GPU.JS uses internally.\
- * This covers various snippets of code that is not entirely gpu.js specific (ie. may find uses elsewhere)
- *
- * Note that all methods in this class is 'static' by nature `UtilsCore.functionName()`
- *
- * @class UtilsCore
- *
- */
-
-class UtilsCore {
-
- /**
- * @typedef {Object} webGlContext
- */
-
- /**
- * @typedef {Object} CanvasDOMObject
- */
-
- //-----------------------------------------------------------------------------
- //
- // Canvas validation and support
- //
- //-----------------------------------------------------------------------------
-
- /**
- * @name isCanvas
- * @static
- * @function
- * @memberOf UtilsCore
- *
- *
- * @desc Return TRUE, on a valid DOM canvas object
- *
- * Note: This does just a VERY simply sanity check. And may give false positives.
- *
- * @param {CanvasDOMObject} canvasObj - Object to validate
- *
- * @returns {Boolean} TRUE if the object is a DOM canvas
- *
- */
- static isCanvas(canvasObj) {
- return (
- canvasObj !== null &&
- canvasObj.nodeName &&
- canvasObj.getContext &&
- canvasObj.nodeName.toUpperCase() === 'CANVAS'
- );
- }
-
- /**
- * @name isCanvasSupported
- * @function
- * @static
- * @memberOf UtilsCore
- *
- * @desc Return TRUE, if browser supports canvas
- *
- * @returns {Boolean} TRUE if browser supports canvas
- *
- */
- static isCanvasSupported() {
- return _isCanvasSupported;
- }
-
- /**
- * @name initCanvas
- * @function
- * @static
- * @memberOf UtilsCore
- *
- * @desc Initiate and returns a canvas, for usage in init_webgl.
- * Returns only if canvas is supported by browser.
- *
- * @returns {CanvasDOMObject} CanvasDOMObject if supported by browser, else null
- *
- */
- static initCanvas() {
- // Fail fast if browser previously detected no support
- if (!_isCanvasSupported) {
- return null;
- }
-
- // Create a new canvas DOM
- const canvas = document.createElement('canvas');
-
- // Default width and height, to fix webgl issue in safari
- canvas.width = 2;
- canvas.height = 2;
-
- // Returns the canvas
- return canvas;
- }
-
- //-----------------------------------------------------------------------------
- //
- // Webgl validation and support
- //
- //-----------------------------------------------------------------------------
-
-
- /**
- *
- * @name isWebGl
- * @function
- * @static
- * @memberOf UtilsCore
- *
- * @desc Return TRUE, on a valid webGlContext object
- *
- * Note: This does just a VERY simply sanity check. And may give false positives.
- *
- * @param {webGlContext} webGlObj - Object to validate
- *
- * @returns {Boolean} TRUE if the object is a webGlContext object
- *
- */
- static isWebGl(webGlObj) {
- return webGlObj && typeof webGlObj.getExtension === 'function';
- }
-
- /**
- * @name isWebGlSupported
- * @function
- * @static
- * @memberOf UtilsCore
- *
- * @desc Return TRUE, if browser supports webgl
- *
- * @returns {Boolean} TRUE if browser supports webgl
- *
- */
- static isWebGlSupported() {
- return _isWebGlSupported;
- }
-
- static isWebGlDrawBuffersSupported() {
- return _isWebGlDrawBuffersSupported;
- }
-
- // Default webgl options to use
- static initWebGlDefaultOptions() {
- return {
- alpha: false,
- depth: false,
- antialias: false
- };
- }
-
- /**
- * @name initWebGl
- * @function
- * @static
- * @memberOf UtilsCore
- *
- * @desc Initiate and returns a webGl, from a canvas object
- * Returns only if webGl is supported by browser.
- *
- * @param {CanvasDOMObject} canvasObj - Object to validate
- *
- * @returns {CanvasDOMObject} CanvasDOMObject if supported by browser, else null
- *
- */
- static initWebGl(canvasObj) {
-
- // First time setup, does the browser support check memorizer
- if (typeof _isCanvasSupported !== 'undefined' || canvasObj === null) {
- if (!_isCanvasSupported) {
- return null;
- }
- }
-
- // Fail fast for invalid canvas object
- if (!UtilsCore.isCanvas(canvasObj)) {
- throw new Error('Invalid canvas object - ' + canvasObj);
- }
-
- // Create a new canvas DOM
- const webGl = (
- canvasObj.getContext('experimental-webgl', UtilsCore.initWebGlDefaultOptions()) ||
- canvasObj.getContext('webgl', UtilsCore.initWebGlDefaultOptions())
- );
-
- if (webGl) {
- // Get the extension that is needed
- webGl.OES_texture_float = webGl.getExtension('OES_texture_float');
- webGl.OES_texture_float_linear = webGl.getExtension('OES_texture_float_linear');
- webGl.OES_element_index_uint = webGl.getExtension('OES_element_index_uint');
- }
-
- // Returns the canvas
- return webGl;
- }
-
-}
-
-//-----------------------------------------------------------------------------
-//
-// Canvas & Webgl validation and support constants
-//
-//-----------------------------------------------------------------------------
-
-const _isCanvasSupported = typeof document !== 'undefined' ? UtilsCore.isCanvas(document.createElement('canvas')) : false;
-const _testingWebGl = UtilsCore.initWebGl(UtilsCore.initCanvas());
-const _isWebGlSupported = UtilsCore.isWebGl(_testingWebGl);
-const _isWebGlDrawBuffersSupported = _isWebGlSupported && Boolean(_testingWebGl.getExtension('WEBGL_draw_buffers'));
-
-if (_isWebGlSupported) {
- UtilsCore.OES_texture_float = _testingWebGl.OES_texture_float;
- UtilsCore.OES_texture_float_linear = _testingWebGl.OES_texture_float_linear;
- UtilsCore.OES_element_index_uint = _testingWebGl.OES_element_index_uint;
-} else {
- UtilsCore.OES_texture_float = false;
- UtilsCore.OES_texture_float_linear = false;
- UtilsCore.OES_element_index_uint = false;
-}
-
-module.exports = UtilsCore;
\ No newline at end of file
diff --git a/src/core/utils.js b/src/core/utils.js
deleted file mode 100644
index 6dae8c78..00000000
--- a/src/core/utils.js
+++ /dev/null
@@ -1,521 +0,0 @@
-'use strict';
-
-/**
- *
- * @classdesc Various utility functions / snippets of code that GPU.JS uses internally.\
- * This covers various snippets of code that is not entirely gpu.js specific (ie. may find uses elsewhere)
- *
- * Note that all methods in this class are *static* by nature `Utils.functionName()`
- *
- * @class Utils
- * @extends UtilsCore
- *
- */
-
-const UtilsCore = require("./utils-core");
-const Input = require('./input');
-const Texture = require('./texture');
-// FUNCTION_NAME regex
-const FUNCTION_NAME = /function ([^(]*)/;
-
-// STRIP COMMENTS regex
-const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
-
-// ARGUMENT NAMES regex
-const ARGUMENT_NAMES = /([^\s,]+)/g;
-
-const _systemEndianness = (() => {
- const b = new ArrayBuffer(4);
- const a = new Uint32Array(b);
- const c = new Uint8Array(b);
- a[0] = 0xdeadbeef;
- if (c[0] === 0xef) return 'LE';
- if (c[0] === 0xde) return 'BE';
- throw new Error('unknown endianness');
-})();
-
-let _isFloatReadPixelsSupported = null;
-
-class Utils extends UtilsCore {
-
- //-----------------------------------------------------------------------------
- //
- // System values support (currently only endianness)
- //
- //-----------------------------------------------------------------------------
-
- /**
- * @memberOf Utils
- * @name systemEndianness
- * @function
- * @static
- *
- * Gets the system endianness, and cache it
- *
- * @returns {String} 'LE' or 'BE' depending on system architecture
- *
- * Credit: https://gist.github.com/TooTallNate/4750953
- */
- static systemEndianness() {
- return _systemEndianness;
- }
-
- //-----------------------------------------------------------------------------
- //
- // Function and function string validations
- //
- //-----------------------------------------------------------------------------
-
- /**
- * @memberOf Utils
- * @name isFunction
- * @function
- * @static
- *
- * Return TRUE, on a JS function
- *
- * @param {Function} funcObj - Object to validate if its a function
- *
- * @returns {Boolean} TRUE if the object is a JS function
- *
- */
- static isFunction(funcObj) {
- return typeof(funcObj) === 'function';
- }
-
- /**
- * @memberOf Utils
- * @name isFunctionString
- * @function
- * @static
- *
- * Return TRUE, on a valid JS function string
- *
- * Note: This does just a VERY simply sanity check. And may give false positives.
- *
- * @param {String} funcStr - String of JS function to validate
- *
- * @returns {Boolean} TRUE if the string passes basic validation
- *
- */
- static isFunctionString(funcStr) {
- if (funcStr !== null) {
- return (funcStr.toString()
- .slice(0, 'function'.length)
- .toLowerCase() === 'function');
- }
- return false;
- }
-
- /**
- * @memberOf Utils
- * @name getFunctionName_fromString
- * @function
- * @static
- *
- * Return the function name from a JS function string
- *
- * @param {String} funcStr - String of JS function to validate
- *
- * @returns {String} Function name string (if found)
- *
- */
- static getFunctionNameFromString(funcStr) {
- return FUNCTION_NAME.exec(funcStr)[1];
- }
-
- static getFunctionBodyFromString(funcStr) {
- return funcStr.substring(funcStr.indexOf('{') + 1, funcStr.lastIndexOf('}'));
- }
-
- /**
- * @memberOf Utils
- * @name getParamNames_fromString
- * @function
- * @static
- *
- * Return list of parameter names extracted from the JS function string
- *
- * @param {String} funcStr - String of JS function to validate
- *
- * @returns {String[]} Array representing all the parameter names
- *
- */
- static getParamNamesFromString(func) {
- const fnStr = func.toString().replace(STRIP_COMMENTS, '');
- let result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
- if (result === null)
- result = [];
- return result;
- }
-
- //-----------------------------------------------------------------------------
- //
- // Object / function cloning and manipulation
- //
- //-----------------------------------------------------------------------------
-
- /**
- * @memberOf Utils
- * @name clone
- * @function
- * @static
- *
- * Returns a clone
- *
- * @param {Object} obj - Object to clone
- *
- * @returns {Object} Cloned object
- *
- */
- static clone(obj) {
- if (obj === null || typeof obj !== 'object' || obj.hasOwnProperty('isActiveClone')) return obj;
-
- const temp = obj.constructor(); // changed
-
- for (let key in obj) {
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
- obj.isActiveClone = null;
- temp[key] = Utils.clone(obj[key]);
- delete obj.isActiveClone;
- }
- }
-
- return temp;
- }
-
- /**
- * @memberOf Utils
- * @name newPromise
- * @function
- * @static
- *
- * Returns a `new Promise` object based on the underlying implmentation
- *
- * @param {Function} executor - Promise builder function
- *
- * @returns {Promise} Promise object
- *
- */
- static newPromise(executor) {
- const simple = Promise || small_promise;
- if (simple === null) {
- throw TypeError('Browser is missing Promise implementation. Consider adding small_promise.js polyfill');
- }
- return (new simple(executor));
- }
-
- /**
- * @memberOf Utils
- * @name functionBinder
- * @function
- * @static
- *
- * Limited implementation of Function.bind, with fallback
- *
- * @param {Function} inFunc - to setup bind on
- * @param {Object} thisObj - The this parameter to assume inside the binded function
- *
- * @returns {Function} The binded function
- *
- */
- static functionBinder(inFunc, thisObj) {
- if (inFunc.bind) {
- return inFunc.bind(thisObj);
- }
-
- return function() {
- const args = (arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments));
- return inFunc.apply(thisObj, args);
- }
- }
-
- /**
- * @memberOf Utils
- * @name isArray
- * @function
- * @static
- *
- * * Checks if is an array or Array-like object
- *
- * @param {Object} arg - The argument object to check if is array
- *
- * @returns {Boolean} true if is array or Array-like object
- *
- */
- static isArray(array) {
- if (isNaN(array.length)) {
- return false;
- }
-
- return true;
- }
-
- /**
- * @memberOf Utils
- * @name getArgumentType
- * @function
- * @static
- *
- * Evaluate the argument type, to apply respective logic for it
- *
- * @param {Object} arg - The argument object to evaluate type
- *
- * @returns {String} Argument type Array/Number/Texture/Unknown
- *
- */
- static getArgumentType(arg) {
- if (Utils.isArray(arg)) {
- return 'Array';
- } else if (typeof arg === 'number') {
- return 'Number';
- } else if (arg instanceof Texture) {
- return 'Texture';
- } else if (arg instanceof Input) {
- return 'Input';
- } else {
- return 'Unknown';
- }
- }
- /**
- * @typedef {Object} gpuJSObject
- */
-
- /**
- * @memberOf Utils
- * @name isFloatReadPixelsSupported
- * @function
- * @static
- *
- * Checks if the browser supports readPixels with float type
- *
- * @param {gpuJSObject} gpu - the gpu object
- *
- * @returns {Boolean} true if browser supports
- *
- */
- static isFloatReadPixelsSupported() {
- if (_isFloatReadPixelsSupported !== null) {
- return _isFloatReadPixelsSupported
- }
-
- const GPU = require('../index');
- const x = new GPU({
- mode: 'webgl-validator'
- }).createKernel(function() {
- return 1;
- }, {
- output: [2],
- floatTextures: true,
- floatOutput: true,
- floatOutputForce: true
- })();
-
- _isFloatReadPixelsSupported = x[0] === 1;
-
- return _isFloatReadPixelsSupported;
- }
-
-
- static dimToTexSize(opt, dimensions, output) {
- let numTexels = dimensions[0];
- for (let i = 1; i < dimensions.length; i++) {
- numTexels *= dimensions[i];
- }
-
- if (opt.floatTextures && (!output || opt.floatOutput)) {
- numTexels = Math.ceil(numTexels / 4);
- }
-
- const w = Math.ceil(Math.sqrt(numTexels));
- return [w, w];
- }
-
- /**
- * @memberOf Utils
- * @name getDimensions
- * @function
- * @static
- *
- * Return the dimension of an array.
- *
- * @param {Array} x - The array
- * @param {number} pad - To include padding in the dimension calculation [Optional]
- *
- *
- *
- */
-
- static getDimensions(x, pad) {
- let ret;
- if (Utils.isArray(x)) {
- const dim = [];
- let temp = x;
- while (Utils.isArray(temp)) {
- dim.push(temp.length);
- temp = temp[0];
- }
- ret = dim.reverse();
- } else if (x instanceof Texture) {
- ret = x.output;
- } else if (x instanceof Input) {
- ret = x.size;
- } else {
- throw 'Unknown dimensions of ' + x;
- }
-
- if (pad) {
- ret = Utils.clone(ret);
- while (ret.length < 3) {
- ret.push(1);
- }
- }
-
- return ret;
- }
-
- /**
- * @memberOf Utils
- * @name pad
- * @function
- * @static
- *
- * Pad an array AND its elements with leading and ending zeros
- *
- * @param {Array} arr - the array to pad zeros to
- * @param {number} padding - amount of padding
- *
- * @returns {Array} Array with leading and ending zeros, and all the elements padded by zeros.
- *
- */
- static pad(arr, padding) {
- function zeros(n) {
- return Array.apply(null, new Array(n)).map(Number.prototype.valueOf, 0);
- }
-
- const len = arr.length + padding * 2;
-
- let ret = arr.map(function(x) {
- return [].concat(zeros(padding), x, zeros(padding));
- });
-
- for (let i = 0; i < padding; i++) {
- ret = [].concat([zeros(len)], ret, [zeros(len)]);
- }
-
- return ret;
- }
-
- /**
- * @memberOf Utils
- * @name flatten2dArrayTo
- * @function
- * @static
- *
- * Puts a nested 2d array into a one-dimensional target array
- * @param {Array|*} array
- * @param {Float32Array|Float64Array} target
- */
- static flatten2dArrayTo(array, target) {
- let offset = 0;
- for (let y = 0; y < array.length; y++) {
- target.set(array[y], offset);
- offset += array[y].length;
- }
- }
-
- /**
- * @memberOf Utils
- * @name flatten3dArrayTo
- * @function
- * @static
- *
- * Puts a nested 3d array into a one-dimensional target array
- * @param {Array|*} array
- * @param {Float32Array|Float64Array} target
- */
- static flatten3dArrayTo(array, target) {
- let offset = 0;
- for (let z = 0; z < array.length; z++) {
- for (let y = 0; y < array[z].length; y++) {
- target.set(array[z][y], offset);
- offset += array[z][y].length;
- }
- }
- }
-
- /**
- * @memberOf Utils
- * @name flatten3dArrayTo
- * @function
- * @static
- *
- * Puts a nested 1d, 2d, or 3d array into a one-dimensional target array
- * @param {Array|*} array
- * @param {Float32Array|Float64Array} target
- */
- static flattenTo(array, target) {
- if (Utils.isArray(array[0])) {
- if (Utils.isArray(array[0][0])) {
- Utils.flatten3dArrayTo(array, target);
- } else {
- Utils.flatten2dArrayTo(array, target);
- }
- } else {
- target.set(array);
- }
- }
-
- /**
- * @memberOf Utils
- * @name splitArray
- * @function
- * @static
- *
- * Splits an array into smaller arrays.
- * Number of elements in one small chunk is given by `part`
- *
- * @param {Array} array - The array to split into chunks
- * @param {Array} part - elements in one chunk
- *
-
- * @returns {Array} An array of smaller chunks
- *
- */
- static splitArray(array, part) {
- const result = [];
- for (let i = 0; i < array.length; i += part) {
- result.push(Array.prototype.slice.call(array, i, i + part));
- }
- return result;
- }
-
- static getAstString(source, ast) {
- let lines = Array.isArray(source) ? source : source.split(/\r?\n/g);
- const start = ast.loc.start;
- const end = ast.loc.end;
- const result = [];
- result.push(lines[start.line - 1].slice(start.column));
- for (let i = start.line; i < end.line - 1; i++) {
- result.push(lines[i]);
- }
- result.push(lines[end.line - 1].slice(0, end.column));
- return result.join('\n');
- }
-
- static allPropertiesOf(obj) {
- const props = [];
-
- do {
- props.push.apply(props, Object.getOwnPropertyNames(obj));
- } while (obj = Object.getPrototypeOf(obj));
-
- return props;
- }
-}
-
-// This ensure static methods are "inherited"
-// See: https://stackoverflow.com/questions/5441508/how-to-inherit-static-methods-from-base-class-in-javascript
-Object.assign(Utils, UtilsCore);
-
-module.exports = Utils;
\ No newline at end of file
diff --git a/src/gpu.js b/src/gpu.js
new file mode 100644
index 00000000..c9b1166b
--- /dev/null
+++ b/src/gpu.js
@@ -0,0 +1,605 @@
+const { gpuMock } = require('gpu-mock.js');
+const { utils } = require('./utils');
+const { Kernel } = require('./backend/kernel');
+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 { kernelRunShortcut } = require('./kernel-run-shortcut');
+
+
+/**
+ *
+ * @type {Array.}
+ */
+const kernelOrder = [HeadlessGLKernel, WebGL2Kernel, WebGLKernel];
+
+/**
+ *
+ * @type {string[]}
+ */
+const kernelTypes = ['gpu', 'cpu'];
+
+const internalKernels = {
+ 'headlessgl': HeadlessGLKernel,
+ 'webgl2': WebGL2Kernel,
+ 'webgl': WebGLKernel,
+};
+
+let validate = true;
+
+/**
+ * The GPU.js library class which manages the GPU context for the creating kernels
+ * @class
+ * @return {GPU}
+ */
+class GPU {
+ static disableValidation() {
+ validate = false;
+ }
+
+ static enableValidation() {
+ validate = true;
+ }
+
+ static get isGPUSupported() {
+ return kernelOrder.some(Kernel => Kernel.isSupported);
+ }
+
+ /**
+ *
+ * @returns {boolean}
+ */
+ static get isKernelMapSupported() {
+ return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.kernelMap);
+ }
+
+ /**
+ * @desc TRUE is platform supports OffscreenCanvas
+ */
+ static get isOffscreenCanvasSupported() {
+ return (typeof Worker !== 'undefined' && typeof OffscreenCanvas !== 'undefined') || typeof importScripts !== 'undefined';
+ }
+
+ /**
+ * @desc TRUE if platform supports WebGL
+ */
+ static get isWebGLSupported() {
+ return WebGLKernel.isSupported;
+ }
+
+ /**
+ * @desc TRUE if platform supports WebGL2
+ */
+ static get isWebGL2Supported() {
+ return WebGL2Kernel.isSupported;
+ }
+
+ /**
+ * @desc TRUE if platform supports HeadlessGL
+ */
+ static get isHeadlessGLSupported() {
+ return HeadlessGLKernel.isSupported;
+ }
+
+ /**
+ *
+ * @desc TRUE if platform supports Canvas
+ */
+ static get isCanvasSupported() {
+ return typeof HTMLCanvasElement !== 'undefined';
+ }
+
+ /**
+ * @desc TRUE if platform supports HTMLImageArray}
+ */
+ static get isGPUHTMLImageArraySupported() {
+ return WebGL2Kernel.isSupported;
+ }
+
+ /**
+ * @desc TRUE if platform supports single precision}
+ * @returns {boolean}
+ */
+ static get isSinglePrecisionSupported() {
+ return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.isFloatRead && Kernel.features.isTextureFloat);
+ }
+
+ /**
+ * Creates an instance of GPU.
+ * @param {IGPUSettings} [settings] - Settings to set mode, and other properties
+ * @constructor
+ */
+ 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();
+ // add functions from settings
+ if (settings.functions) {
+ for (let i = 0; i < settings.functions.length; i++) {
+ this.addFunction(settings.functions[i]);
+ }
+ }
+
+ // add native functions from settings
+ if (settings.nativeFunctions) {
+ for (const p in settings.nativeFunctions) {
+ if (!settings.nativeFunctions.hasOwnProperty(p)) continue;
+ const s = settings.nativeFunctions[p];
+ const { name, source } = s;
+ this.addNativeFunction(name, source, s);
+ }
+ }
+ }
+
+ /**
+ * Choose kernel type and save on .Kernel property of GPU
+ */
+ chooseKernel() {
+ if (this.Kernel) return;
+
+ /**
+ *
+ * @type {WebGLKernel|WebGL2Kernel|HeadlessGLKernel|CPUKernel}
+ */
+ 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 === '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;
+ }
+
+ /**
+ * @desc This creates a callable function object to call the kernel function with the argument parameter set
+ * @param {Function|String|object} source - The calling to perform the conversion
+ * @param {IGPUKernelSettings} [settings] - The parameter configuration object
+ * @return {IKernelRunShortcut} callable function to run
+ */
+ 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 = {};
+ const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings) || {};
+ // handle conversion of argumentTypes
+ if (settings && typeof settings.argumentTypes === 'object') {
+ settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]);
+ }
+
+ function onRequestFallback(args) {
+ console.warn('Falling back to CPU');
+ const fallbackKernel = new CPUKernel(source, {
+ argumentTypes: kernelRun.argumentTypes,
+ constantTypes: kernelRun.constantTypes,
+ graphical: kernelRun.graphical,
+ loopMaxIterations: kernelRun.loopMaxIterations,
+ constants: kernelRun.constants,
+ dynamicOutput: kernelRun.dynamicOutput,
+ dynamicArgument: kernelRun.dynamicArguments,
+ output: kernelRun.output,
+ precision: kernelRun.precision,
+ pipeline: kernelRun.pipeline,
+ immutable: kernelRun.immutable,
+ optimizeFloatMemory: kernelRun.optimizeFloatMemory,
+ fixIntegerDivisionAccuracy: kernelRun.fixIntegerDivisionAccuracy,
+ functions: kernelRun.functions,
+ nativeFunctions: kernelRun.nativeFunctions,
+ injectedNative: kernelRun.injectedNative,
+ subKernels: kernelRun.subKernels,
+ strictIntegers: kernelRun.strictIntegers,
+ debug: kernelRun.debug,
+ });
+ fallbackKernel.build.apply(fallbackKernel, args);
+ const result = fallbackKernel.run.apply(fallbackKernel, args);
+ kernelRun.replaceKernel(fallbackKernel);
+ return result;
+ }
+
+ /**
+ *
+ * @param {IReason[]} reasons
+ * @param {IArguments} args
+ * @param {Kernel} _kernel
+ * @returns {*}
+ */
+ function onRequestSwitchKernel(reasons, args, _kernel) {
+ if (_kernel.debug) {
+ console.warn('Switching kernels');
+ }
+ let newOutput = null;
+ if (_kernel.signature && !switchableKernels[_kernel.signature]) {
+ switchableKernels[_kernel.signature] = _kernel;
+ }
+ if (_kernel.dynamicOutput) {
+ for (let i = reasons.length - 1; i >= 0; i--) {
+ const reason = reasons[i];
+ if (reason.type === 'outputPrecisionMismatch') {
+ newOutput = reason.needed;
+ }
+ }
+ }
+
+ const Constructor = _kernel.constructor;
+ const argumentTypes = Constructor.getArgumentTypes(_kernel, args);
+ const signature = Constructor.getSignature(_kernel, argumentTypes);
+ const existingKernel = switchableKernels[signature];
+ if (existingKernel) {
+ existingKernel.onActivate(_kernel);
+ return existingKernel;
+ }
+
+ const newKernel = switchableKernels[signature] = new Constructor(source, {
+ argumentTypes,
+ constantTypes: _kernel.constantTypes,
+ graphical: _kernel.graphical,
+ loopMaxIterations: _kernel.loopMaxIterations,
+ constants: _kernel.constants,
+ dynamicOutput: _kernel.dynamicOutput,
+ dynamicArgument: _kernel.dynamicArguments,
+ context: _kernel.context,
+ canvas: _kernel.canvas,
+ output: newOutput || _kernel.output,
+ precision: _kernel.precision,
+ pipeline: _kernel.pipeline,
+ immutable: _kernel.immutable,
+ optimizeFloatMemory: _kernel.optimizeFloatMemory,
+ fixIntegerDivisionAccuracy: _kernel.fixIntegerDivisionAccuracy,
+ functions: _kernel.functions,
+ nativeFunctions: _kernel.nativeFunctions,
+ injectedNative: _kernel.injectedNative,
+ subKernels: _kernel.subKernels,
+ strictIntegers: _kernel.strictIntegers,
+ debug: _kernel.debug,
+ gpu: _kernel.gpu,
+ validate,
+ returnType: _kernel.returnType,
+ tactic: _kernel.tactic,
+ onRequestFallback,
+ onRequestSwitchKernel,
+ texture: _kernel.texture,
+ mappedTextures: _kernel.mappedTextures,
+ drawBuffersMap: _kernel.drawBuffersMap,
+ });
+ newKernel.build.apply(newKernel, args);
+ kernelRun.replaceKernel(newKernel);
+ kernels.push(newKernel);
+ return newKernel;
+ }
+ const mergedSettings = Object.assign({
+ context: this.context,
+ canvas: this.canvas,
+ functions: this.functions,
+ nativeFunctions: this.nativeFunctions,
+ injectedNative: this.injectedNative,
+ gpu: this,
+ validate,
+ onRequestFallback,
+ onRequestSwitchKernel
+ }, settingsCopy);
+
+ const kernel = new this.Kernel(source, mergedSettings);
+ const kernelRun = kernelRunShortcut(kernel);
+
+ //if canvas didn't come from this, propagate from kernel
+ if (!this.canvas) {
+ this.canvas = kernel.canvas;
+ }
+
+ //if context didn't come from this, propagate from kernel
+ if (!this.context) {
+ this.context = kernel.context;
+ }
+
+ kernels.push(kernel);
+
+ return kernelRun;
+ }
+
+ /**
+ *
+ * Create a super kernel which executes sub kernels
+ * and saves their output to be used with the next sub kernel.
+ * This can be useful if we want to save the output on one kernel,
+ * and then use it as an input to another kernel. *Machine Learning*
+ *
+ * @param {Object|Array} subKernels - Sub kernels for this kernel
+ * @param {Function} rootKernel - Root kernel
+ *
+ * @returns {Function} callable kernel function
+ *
+ * @example
+ * const megaKernel = gpu.createKernelMap({
+ * addResult: function add(a, b) {
+ * return a[this.thread.x] + b[this.thread.x];
+ * },
+ * multiplyResult: function multiply(a, b) {
+ * return a[this.thread.x] * b[this.thread.x];
+ * },
+ * }, function(a, b, c) {
+ * return multiply(add(a, b), c);
+ * });
+ *
+ * megaKernel(a, b, c);
+ *
+ * Note: You can also define subKernels as an array of functions.
+ * > [add, multiply]
+ *
+ */
+ createKernelMap() {
+ let fn;
+ let settings;
+ const argument2Type = typeof arguments[arguments.length - 2];
+ if (argument2Type === 'function' || argument2Type === 'string') {
+ fn = arguments[arguments.length - 2];
+ settings = arguments[arguments.length - 1];
+ } else {
+ fn = arguments[arguments.length - 1];
+ }
+
+ if (this.mode !== 'dev') {
+ if (!this.Kernel.isSupported || !this.Kernel.features.kernelMap) {
+ if (this.mode && kernelTypes.indexOf(this.mode) < 0) {
+ throw new Error(`kernelMap not supported on ${this.Kernel.name}`);
+ }
+ }
+ }
+
+ const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings);
+ // handle conversion of argumentTypes
+ if (settings && typeof settings.argumentTypes === 'object') {
+ settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]);
+ }
+
+ if (Array.isArray(arguments[0])) {
+ settingsCopy.subKernels = [];
+ const functions = arguments[0];
+ for (let i = 0; i < functions.length; i++) {
+ const source = functions[i].toString();
+ const name = utils.getFunctionNameFromString(source);
+ settingsCopy.subKernels.push({
+ name,
+ source,
+ property: i,
+ });
+ }
+ } else {
+ settingsCopy.subKernels = [];
+ const functions = arguments[0];
+ for (let p in functions) {
+ if (!functions.hasOwnProperty(p)) continue;
+ const source = functions[p].toString();
+ const name = utils.getFunctionNameFromString(source);
+ settingsCopy.subKernels.push({
+ name: name || p,
+ source,
+ property: p,
+ });
+ }
+ }
+ return this.createKernel(fn, settingsCopy);
+ }
+
+ /**
+ *
+ * Combine different kernels into one super Kernel,
+ * useful to perform multiple operations inside one
+ * kernel without the penalty of data transfer between
+ * cpu and gpu.
+ *
+ * The number of kernel functions sent to this method can be variable.
+ * You can send in one, two, etc.
+ *
+ * @param {Function} subKernels - Kernel function(s) to combine.
+ * @param {Function} rootKernel - Root kernel to combine kernels into
+ *
+ * @example
+ * combineKernels(add, multiply, function(a,b,c){
+ * return add(multiply(a,b), c)
+ * })
+ *
+ * @returns {Function} Callable kernel function
+ *
+ */
+ combineKernels() {
+ const firstKernel = arguments[0];
+ const combinedKernel = arguments[arguments.length - 1];
+ if (firstKernel.kernel.constructor.mode === 'cpu') return combinedKernel;
+ const canvas = arguments[0].canvas;
+ const context = arguments[0].context;
+ const max = arguments.length - 1;
+ for (let i = 0; i < max; i++) {
+ arguments[i]
+ .setCanvas(canvas)
+ .setContext(context)
+ .setPipeline(true);
+ }
+
+ return function() {
+ const texture = combinedKernel.apply(this, arguments);
+ if (texture.toArray) {
+ return texture.toArray();
+ }
+ return texture;
+ };
+ }
+
+ setFunctions(functions) {
+ this.functions = functions;
+ return this;
+ }
+
+ setNativeFunctions(nativeFunctions) {
+ this.nativeFunctions = nativeFunctions;
+ return this;
+ }
+
+ /**
+ * @desc Adds additional functions, that the kernel may call.
+ * @param {Function|String} source - Javascript function to convert
+ * @param {IFunctionSettings} [settings]
+ * @returns {GPU} returns itself
+ */
+ addFunction(source, settings) {
+ this.functions.push({ source, settings });
+ return this;
+ }
+
+ /**
+ * @desc Adds additional native functions, that the kernel may call.
+ * @param {String} name - native function name, used for reverse lookup
+ * @param {String} source - the native function implementation, as it would be defined in it's entirety
+ * @param {object} [settings]
+ * @returns {GPU} returns itself
+ */
+ addNativeFunction(name, source, settings) {
+ if (this.kernels.length > 0) {
+ throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.');
+ }
+ this.nativeFunctions.push(Object.assign({ name, source }, settings));
+ return this;
+ }
+
+ /**
+ * Inject a string just before translated kernel functions
+ * @param {String} source
+ * @return {GPU}
+ */
+ injectNative(source) {
+ this.injectedNative = source;
+ return this;
+ }
+
+ /**
+ * @desc Destroys all memory associated with gpu.js & the webGl if we created it
+ * @return {Promise}
+ * @resolve {void}
+ * @reject {Error}
+ */
+ destroy() {
+ return new Promise((resolve, reject) => {
+ if (!this.kernels) {
+ resolve();
+ }
+ // perform on next run loop - for some reason we dont get lose context events
+ // if webGl is created and destroyed in the same run loop.
+ setTimeout(() => {
+ try {
+ for (let i = 0; i < this.kernels.length; i++) {
+ this.kernels[i].destroy(true); // remove canvas if exists
+ }
+ // all kernels are associated with one context, go ahead and take care of it here
+ let firstKernel = this.kernels[0];
+ if (firstKernel) {
+ // if it is shortcut
+ if (firstKernel.kernel) {
+ firstKernel = firstKernel.kernel;
+ }
+ if (firstKernel.constructor.destroyContext) {
+ firstKernel.constructor.destroyContext(this.context);
+ }
+ }
+ } catch (e) {
+ reject(e);
+ }
+ resolve();
+ }, 0);
+ });
+ }
+}
+
+
+function upgradeDeprecatedCreateKernelSettings(settings) {
+ if (!settings) {
+ return {};
+ }
+ const upgradedSettings = Object.assign({}, settings);
+
+ if (settings.hasOwnProperty('floatOutput')) {
+ utils.warnDeprecated('setting', 'floatOutput', 'precision');
+ upgradedSettings.precision = settings.floatOutput ? 'single' : 'unsigned';
+ }
+ if (settings.hasOwnProperty('outputToTexture')) {
+ utils.warnDeprecated('setting', 'outputToTexture', 'pipeline');
+ upgradedSettings.pipeline = Boolean(settings.outputToTexture);
+ }
+ if (settings.hasOwnProperty('outputImmutable')) {
+ utils.warnDeprecated('setting', 'outputImmutable', 'immutable');
+ upgradedSettings.immutable = Boolean(settings.outputImmutable);
+ }
+ if (settings.hasOwnProperty('floatTextures')) {
+ utils.warnDeprecated('setting', 'floatTextures', 'optimizeFloatMemory');
+ upgradedSettings.optimizeFloatMemory = Boolean(settings.floatTextures);
+ }
+ return upgradedSettings;
+}
+
+module.exports = {
+ GPU,
+ kernelOrder,
+ kernelTypes
+};
\ No newline at end of file
diff --git a/src/index-core.js b/src/index-core.js
deleted file mode 100644
index 853c4713..00000000
--- a/src/index-core.js
+++ /dev/null
@@ -1,12 +0,0 @@
-'use strict';
-
-const GPUCore = require("./core/gpu-core");
-if (typeof module !== 'undefined') {
- module.exports = GPUCore;
-}
-if (typeof window !== 'undefined') {
- window.GPUCore = GPUCore;
- if (window.GPU === null) {
- window.GPU = GPUCore;
- }
-}
\ No newline at end of file
diff --git a/src/index.d.ts b/src/index.d.ts
new file mode 100644
index 00000000..40d86bd0
--- /dev/null
+++ b/src/index.d.ts
@@ -0,0 +1,685 @@
+export class GPU {
+ static isGPUSupported: boolean;
+ static isCanvasSupported: boolean;
+ static isHeadlessGLSupported: boolean;
+ static isWebGLSupported: boolean;
+ static isWebGL2Supported: boolean;
+ static isKernelMapSupported: boolean;
+ static isOffscreenCanvasSupported: boolean;
+ static isGPUHTMLImageArraySupported: boolean;
+ static isSinglePrecisionSupported: boolean;
+ constructor(settings?: IGPUSettings);
+ functions: GPUFunction[];
+ nativeFunctions: IGPUNativeFunction[];
+ setFunctions(flag: any): this;
+ setNativeFunctions(flag: IGPUNativeFunction[]): this;
+ addFunction(kernel: GPUFunction, settings?: IGPUFunctionSettings): this;
+ addNativeFunction(name: string, source: string, settings?: IGPUFunctionSettings): this;
+ combineKernels(...kernels: KernelFunction[]): IKernelRunShortcut;
+ combineKernels(...kernels: KF[]):
+ ((...args: Parameters) =>
+ ReturnType[]
+ | ReturnType[][]
+ | ReturnType[][][]
+ | Texture
+ | void
+ )
+ & IKernelRunShortcutBase;
+ createKernel(kernel: KernelFunction, settings?: IGPUKernelSettings): IKernelRunShortcut;
+ createKernel(kernel: KernelType, settings?: IGPUKernelSettings):
+ ((...args: Parameters) =>
+ ReturnType[]
+ | ReturnType[][]
+ | ReturnType[][][]
+ | Texture
+ | void
+ )
+ & IKernelRunShortcutBase;
+ createKernelMap<
+ ArgTypes extends ThreadKernelVariable[],
+ ConstantsType = null,
+ >(
+ subKernels: ISubKernelObject,
+ rootKernel: ThreadFunction,
+ settings?: IGPUKernelSettings): (((this: IKernelFunctionThis, ...args: ArgTypes) => IMappedKernelResult) & IKernelMapRunShortcut);
+ destroy(): Promise;
+ Kernel: typeof Kernel;
+ mode: string;
+ canvas: any;
+ context: any;
+}
+
+export interface ISubKernelObject {
+ [targetLocation: string]:
+ ((...args: ThreadKernelVariable[]) => ThreadFunctionResult)
+ | ((...args: any[]) => ThreadFunctionResult);
+}
+
+export interface ISubKernelArray {
+ [index: number]:
+ ((...args: ThreadKernelVariable[]) => ThreadFunctionResult)
+ | ((...args: any[]) => ThreadFunctionResult);
+}
+
+export interface ISubKernelsResults {
+ [resultsLocation: string]: KernelOutput;
+}
+
+export interface IGPUFunction extends IFunctionSettings {
+ source: string;
+}
+
+export interface IGPUNativeFunction extends IGPUFunctionSettings {
+ name: string;
+ source: string;
+}
+
+export interface IMappedKernelResult {
+ result?: KernelVariable;
+ [targetLocation: string]: KernelVariable
+}
+
+export interface INativeFunction extends IGPUFunctionSettings {
+ name: string;
+ source: string;
+}
+
+export interface IInternalNativeFunction extends IArgumentTypes {
+ name: string;
+ source: string;
+}
+
+export interface INativeFunctionList {
+ [name: string]: INativeFunction
+}
+
+export type GPUMode = 'gpu' | 'cpu' | 'dev';
+export type GPUInternalMode = 'webgl' | 'webgl2' | 'headlessgl';
+
+export interface IGPUSettings {
+ mode?: GPUMode | GPUInternalMode;
+ canvas?: object;
+ context?: object;
+ functions?: KernelFunction[];
+ nativeFunctions?: IInternalNativeFunction[];
+ // format: 'Float32Array' | 'Float16Array' | 'Float' // WE WANT THIS!
+}
+
+export type GPUVariableType
+ = 'Array'
+ | 'Array(2)'
+ | 'Array(3)'
+ | 'Array(4)'
+ | 'Array1D(2)'
+ | 'Array2D(2)'
+ | 'Array3D(2)'
+ | 'Array1D(3)'
+ | 'Array2D(3)'
+ | 'Array3D(3)'
+ | 'Array1D(4)'
+ | 'Array2D(4)'
+ | 'Array3D(4)'
+ | 'Boolean'
+ | 'HTMLCanvas'
+ | 'HTMLImage'
+ | 'HTMLImageArray'
+ | 'Number'
+ | 'Float'
+ | 'Integer'
+ | GPUTextureType;
+
+export type GPUTextureType
+ = 'NumberTexture'
+ | 'ArrayTexture(4)';
+
+export interface IGPUArgumentTypes {
+ [argumentName: string]: GPUVariableType;
+}
+
+export interface IGPUFunctionSettings {
+ argumentTypes?: IGPUArgumentTypes | string[],
+ returnType?: GPUVariableType;
+}
+
+export class Kernel {
+ static isSupported: boolean;
+ static isContextMatch(context: any): boolean;
+ static disableValidation(): void;
+ static enableValidation(): void;
+ static nativeFunctionArguments(source: string): IArgumentTypes;
+ static nativeFunctionReturnType(source: string): string;
+ static destroyContext(context: any): void;
+ static features: IKernelFeatures;
+ static getFeatures(): IKernelFeatures;
+ static mode: GPUMode | GPUInternalMode;
+ source: string | IKernelJSON;
+ Kernel: Kernel;
+ output: number[];
+ debug: boolean;
+ graphical: boolean;
+ loopMaxIterations: number;
+ constants: IConstants;
+ canvas: any;
+ context: WebGLRenderingContext | any;
+ functions: IFunction[];
+ nativeFunctions: IInternalNativeFunction[];
+ subKernels: ISubKernel[];
+ validate: boolean;
+ immutable: boolean;
+ pipeline: boolean;
+ plugins: IPlugin[];
+ useLegacyEncoder: boolean;
+ tactic: Tactic;
+ built: boolean;
+ texSize: [number, number];
+ texture: Texture;
+ mappedTextures?: Texture[];
+ TextureConstructor: typeof Texture;
+ getPixels(flip?: boolean): Uint8ClampedArray[];
+ getVariablePrecisionString(textureSize?: number[], tactic?: Tactic, isInt?: boolean): string;
+ prependString(value: string): void;
+ hasPrependString(value: string): boolean;
+ constructor(kernel: KernelFunction|IKernelJSON|string, settings?: IDirectKernelSettings);
+ onRequestSwitchKernel?: Kernel;
+ onActivate(previousKernel: Kernel): void;
+ build(...args: KernelVariable[]): void;
+ run(...args: KernelVariable[]): KernelVariable;
+ toString(...args: KernelVariable[]): string;
+ toJSON(): IKernelJSON;
+ setOutput(flag: number[]): this;
+ setWarnVarUsage(flag: boolean): this;
+ setOptimizeFloatMemory(flag: boolean): this;
+ setArgumentTypes(flag: IKernelValueTypes): this;
+ setDebug(flag: boolean): this;
+ setGraphical(flag: boolean): this;
+ setLoopMaxIterations(flag: number): this;
+ setConstants(flag: IConstants): this;
+ setConstants(flag: T & IConstants): this;
+ setConstantTypes(flag: IKernelValueTypes): this;
+ setDynamicOutput(flag: boolean): this;
+ setDynamicArguments(flag: boolean): this;
+ setPipeline(flag: boolean): this;
+ setPrecision(flag: Precision): this;
+ setImmutable(flag: boolean): this;
+ setCanvas(flag: any): this;
+ setContext(flag: any): this;
+ addFunction(flag: GPUFunction, settings?: IFunctionSettings): this;
+ setFunctions(flag: any): this;
+ setNativeFunctions(flag: IGPUNativeFunction[]): this;
+ setStrictIntegers(flag: boolean): this;
+ setTactic(flag: Tactic): this;
+ setUseLegacyEncoder(flag: boolean): this;
+ addSubKernel(subKernel: ISubKernel): this;
+ destroy(removeCanvasReferences?: boolean): void;
+ validateSettings(args: IArguments): void;
+
+ setUniform1f(name: string, value: number): void;
+ setUniform2f(name: string, value1: number, value2: number): void;
+ setUniform3f(name: string, value1: number, value2: number, value3: number): void;
+ setUniform4f(name: string, value1: number, value2: number, value3: number, value4: number): void;
+
+ setUniform2fv(name: string, value: [number, number]): void;
+ setUniform3fv(name: string, value: [number, number, number]): void;
+ setUniform4fv(name: string, value: [number, number, number, number]): void;
+
+ setUniform1i(name: string, value: number): void;
+ setUniform2i(name: string, value1: number, value2: number): void;
+ setUniform3i(name: string, value1: number, value2: number, value3: number): void;
+ setUniform4i(name: string, value1: number, value2: number, value3: number, value4: number): void;
+
+ setUniform2iv(name: string, value: [number, number]): void;
+ setUniform3iv(name: string, value: [number, number, number]): void;
+ setUniform4iv(name: string, value: [number, number, number, number]): void;
+}
+
+
+export type GPUFunction
+ = ThreadFunction
+ | IFunction
+ | IGPUFunction
+ | string[];
+
+export type ThreadFunction =
+ ((this: IKernelFunctionThis, ...args: ArgTypes) => ThreadFunctionResult);
+
+export type Precision = 'single' | 'unsigned';
+
+export class CPUKernel extends Kernel {
+
+}
+export class GLKernel extends Kernel {
+
+}
+export class WebGLKernel extends GLKernel {
+
+}
+export class WebGL2Kernel extends WebGLKernel {
+
+}
+export class HeadlessGLKernel extends WebGLKernel {
+
+}
+
+export interface IArgumentTypes {
+ argumentTypes: GPUVariableType[],
+ argumentNames: string[],
+}
+
+export interface IConstants {
+ [constantName: string]: KernelVariable;
+}
+
+export interface IKernelValueTypes {
+ [constantType: string]: GPUVariableType;
+}
+
+export interface IWebGLKernelValueSettings extends IKernelValueSettings {
+ onRequestTexture: () => object;
+ onRequestIndex: () => number;
+ onRequestContextHandle: () => number;
+ texture: any;
+}
+
+export interface IKernelValueSettings {
+ name: string;
+ kernel: Kernel;
+ context: WebGLRenderingContext;
+ contextHandle?: number;
+ checkContext?: boolean;
+ onRequestContextHandle: () => number;
+ onUpdateValueMismatch: (constructor: object) => void;
+ origin: 'user' | 'constants';
+ strictIntegers?: boolean;
+ type: GPUVariableType;
+ tactic?: Tactic;
+ size: number[];
+ index?: number;
+}
+
+export type Tactic = 'speed' | 'balanced' | 'precision';
+
+export interface IConstantsThis {
+ [constantName: string]: ThreadKernelVariable;
+}
+
+export interface IKernelXYZ {
+ x: number;
+ y: number;
+ z: number;
+}
+
+export interface FunctionList {
+ [functionName: string]: Function
+}
+
+export interface IGPUKernelSettings extends IKernelSettings {
+ argumentTypes?: ITypesList;
+ functions?: Function[]|FunctionList;
+ tactic?: Tactic;
+ onRequestSwitchKernel?: Kernel;
+}
+
+export interface IKernelSettings {
+ pluginNames?: string[];
+ output?: number[] | IKernelXYZ;
+ precision?: Precision;
+ constants?: object;
+ context?: any;
+ canvas?: any;
+ pipeline?: boolean;
+ immutable?: boolean;
+ graphical?: boolean;
+ onRequestFallback?: () => Kernel;
+ optimizeFloatMemory?: boolean;
+ dynamicOutput?: boolean;
+ dynamicArguments?: boolean;
+ constantTypes?: ITypesList;
+ useLegacyEncoder?: boolean;
+ nativeFunctions?: IGPUNativeFunction[],
+ strictIntegers?: boolean;
+}
+
+export interface IDirectKernelSettings extends IKernelSettings {
+ argumentTypes?: string[];
+ functions?: string[]|IFunction;
+}
+
+export interface ITypesList {
+ [typeName: string]: GPUVariableType
+}
+
+export interface IKernelRunShortcutBase extends Kernel {
+ kernel: Kernel;
+ (...args: KernelVariable[]): T;
+ exec(): Promise;
+}
+
+export interface IKernelRunShortcut extends IKernelRunShortcutBase {
+
+}
+
+export interface IKernelMapRunShortcut extends IKernelRunShortcutBase<
+ { result: KernelOutput } & { [key in keyof SubKernelType]: KernelOutput }> {}
+
+export interface IKernelFeatures {
+ isFloatRead: boolean;
+ kernelMap: boolean;
+ isIntegerDivisionAccurate: boolean;
+ isSpeedTacticSupported: boolean;
+ isTextureFloat: boolean;
+ isDrawBuffers: boolean;
+ channelCount: number;
+ maxTextureSize: number;
+ lowIntPrecision: { rangeMax: number };
+ mediumIntPrecision: { rangeMax: number };
+ highIntPrecision: { rangeMax: number };
+ lowFloatPrecision: { rangeMax: number };
+ mediumFloatPrecision: { rangeMax: number };
+ highFloatPrecision: { rangeMax: number };
+}
+
+export interface IKernelFunctionThis {
+ output: IKernelXYZ;
+ thread: IKernelXYZ;
+ constants: ConstantsT;
+ color(r: number): void,
+ color(r: number, g: number): void,
+ color(r: number, g: number, b: number): void,
+ color(r: number, g: number, b: number, a: number): void,
+}
+
+export type KernelVariable =
+ boolean
+ | number
+ | Texture
+ | Input
+ | HTMLCanvasElement
+ | OffscreenCanvas
+ | HTMLVideoElement
+ | HTMLImageElement
+ | HTMLImageElement[]
+ | ImageBitmap
+ | ImageData
+ | Float32Array
+ | Uint8Array
+ | Uint16Array
+ | Uint32Array
+ | Uint8ClampedArray
+ | KernelOutput;
+
+export type ThreadFunctionResult
+ = number
+ | number[]
+ | number[][]
+ | [number, number]
+ | [number, number, number]
+ | [number, number, number, number]
+ | Pixel
+ | Boolean;
+
+export type ThreadKernelVariable
+ = boolean
+ | number
+ | number[]
+ | number[][]
+ | number[][][]
+
+ | Float32Array
+ | Float32Array[]
+ | Float32Array[][]
+
+ | Pixel
+ | Pixel[][]
+
+ | [number, number]
+ | [number, number][]
+ | [number, number][][]
+ | [number, number][][][]
+
+ | [number, number, number]
+ | [number, number, number][]
+ | [number, number, number][][]
+ | [number, number, number][][][]
+
+ | [number, number, number, number]
+ | [number, number, number, number][]
+ | [number, number, number, number][][]
+ | [number, number, number, number][][][]
+ ;
+
+export type Pixel = {
+ r: number;
+ g: number;
+ b: number;
+ a: number;
+};
+
+// export type KernelFunction = ((
+// this: IKernelFunctionThis,
+// ...args: ArgT
+// ) => KernelOutput);
+
+export interface KernelFunction {
+ (
+ this: IKernelFunctionThis,
+ ...args: ArgT
+ ): KernelOutput;
+}
+
+export type KernelOutput = void
+ | number
+ | number[]
+ | number[][]
+ | number[][][]
+
+ | Float32Array
+ | Float32Array[]
+ | Float32Array[][]
+
+ | [number, number][]
+ | [number, number, number][]
+ | [number, number, number, number][]
+
+ | [number, number][][]
+ | [number, number, number][][]
+ | [number, number, number, number][][]
+
+ | [number, number][][][]
+ | [number, number, number][][][]
+ | [number, number, number, number][][][]
+
+ | Texture;
+
+export interface IFunction {
+ source: string;
+ settings: IFunctionSettings;
+}
+
+export interface IFunctionSettings {
+ name?: string;
+ debug?: boolean;
+ argumentNames?: string[];
+ argumentTypes?: string[] | { [argumentName: string]: string };
+ argumentSizes?: number[];
+
+ constants?: IConstants;
+ constantTypes?: IKernelValueTypes;
+
+ output?: number[];
+ loopMaxIterations?: number;
+ returnType?: string;
+ isRootKernel?: boolean;
+ isSubKernel?: boolean;
+ onNestedFunction?(ast: any, source: string): void;
+ lookupReturnType?(functionName: string, ast: any, node: FunctionNode): void;
+ plugins?: any[];
+
+ useLegacyEncoder?: boolean;
+ ast?: any;
+}
+
+export interface ISubKernel {
+ name: string;
+ source: string;
+ property: string | number;
+ returnType: string;
+}
+
+
+export class FunctionBuilder {
+ static fromKernel(kernel: Kernel, FunctionNode: FunctionNode, extraNodeOptions?: any): FunctionBuilder;
+ constructor(settings: IFunctionBuilderSettings);
+ addFunctionNode(functionNode: FunctionNode): void;
+ traceFunctionCalls(functionName: string, retList?: string[]): string[];
+ getStringFromFunctionNames(functionName: string[]): string;
+ getPrototypesFromFunctionNames(functionName: string[]): string[];
+ getString(functionName: string): string;
+ getPrototypeString(functionName: string): string;
+}
+
+
+export interface IFunctionBuilderSettings {
+ kernel: Kernel;
+ rootNode: FunctionNode;
+ functionNodes?: FunctionNode[];
+ nativeFunctions?: INativeFunctionList;
+ subKernelNodes?: FunctionNode[];
+}
+
+// These are mostly internal
+export class FunctionNode implements IFunctionSettings {
+ constructor(source: string, settings?: IFunctionNodeSettings);
+}
+
+export interface IFunctionNodeSettings extends IFunctionSettings {
+ argumentTypes: string[]
+}
+
+export class WebGLFunctionNode extends FunctionNode {}
+export class WebGL2FunctionNode extends WebGLFunctionNode {}
+export class CPUFunctionNode extends FunctionNode {}
+
+export interface IGPUTextureSettings {
+ texture: WebGLTexture;
+ size: number[];
+ dimensions: number[];
+ output: number[];
+ context: WebGLRenderingContext;
+ kernel: Kernel;
+ gpu?: GPU;
+ type?: GPUTextureType;
+}
+
+export class Texture {
+ constructor(settings: IGPUTextureSettings)
+ toArray(): TextureArrayOutput;
+ clone(): Texture;
+ delete(): void;
+ clear(): void;
+ kernel: Kernel;
+}
+
+export type TextureArrayOutput
+ = number[]
+ | number[][]
+ | number[][][]
+
+ | Float32Array
+ | Float32Array[]
+ | Float32Array[][]
+
+ | [number, number][]
+ | [number, number][][]
+ | [number, number][][][]
+
+ | [number, number, number][]
+ | [number, number, number][][]
+ | [number, number, number][][][]
+
+ | [number, number, number, number][]
+ | [number, number, number, number][][]
+ | [number, number, number, number][][][]
+ ;
+
+export interface IPlugin {
+ source: string;
+ name: string;
+ functionMatch: string;
+ functionReplace: string;
+ functionReturnType: GPUVariableType;
+ onBeforeRun: (kernel: Kernel) => void;
+}
+
+export type OutputDimensions = [number] | [number, number] | [number, number, number] | Int32Array;
+export type TextureDimensions = [number, number];
+
+export class Input {
+ value: number[];
+ size: number[];
+ constructor(value: number[], size: OutputDimensions);
+}
+
+export type input = (value: number[], size: OutputDimensions) => Input;
+
+export function alias(name: string, source: T): T;
+
+export class KernelValue {
+ constructor(value: KernelVariable, settings: IKernelValueSettings);
+ getSource(): string;
+ setup(): void;
+ updateValue(value: KernelVariable): void;
+}
+
+export class WebGLKernelValue {
+ constructor(value: any, settings: IWebGLKernelValueSettings);
+}
+
+export interface IFunctionNodeMemberExpressionDetails {
+ xProperty: object;
+ yProperty: object;
+ zProperty: object;
+ property: string;
+ type: string;
+ origin: 'user' | 'constants';
+ signature: string;
+}
+
+export interface IKernelJSON {
+ settings: IJSONSettings;
+ functionNodes?: object;
+}
+
+export interface IJSONSettings {
+ output: number[];
+ argumentsTypes: GPUVariableType;
+ returnType: string;
+ argumentNames?: string[];
+ constants?: IConstants;
+ pipeline?: boolean;
+ pluginNames?: string[];
+ tactic?: Tactic;
+ threadDim?: number[];
+}
+
+export declare const utils: {
+ getMinifySafeName: