diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..4c2b5e36 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +charset = utf-8 +end_of_line = crlf +indent_size = 2 +indent_style = space +insert_final_newline = true +max_line_length = 80 +tab_width = 2 +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[{package.json,.travis.yml}] +indent_style = space +indent_size = 2 diff --git a/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md similarity index 97% rename from ISSUE_TEMPLATE.md rename to .github/ISSUE_TEMPLATE.md index 5fd7db4a..2aab9345 100644 --- a/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,20 +1,19 @@ - -![A GIF or MEME to give some spice of the internet](url) - -## *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 + +![A GIF or MEME to give some spice of the internet](url) + +## *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/.gitignore b/.gitignore index 91b984ce..226ea865 100644 --- a/.gitignore +++ b/.gitignore @@ -1,36 +1,36 @@ -# Logs -logs -*.log -npm-debug.log* - -# Runtime data -pids -*.pid -*.seed - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# node-waf configuration -.lock-wscript - -# Dependency directory -node_modules - -# Optional npm cache directory -.npm - -# Optional REPL history -.node_repl_history - -# intellij -.idea - -#yarn -yarn.lock - -# OSX .DS_Store -.DS_Store +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# node-waf configuration +.lock-wscript + +# Dependency directory +node_modules + +# Optional npm cache directory +.npm + +# Optional REPL history +.node_repl_history + +# intellij +.idea + +#yarn +yarn.lock + +# OSX .DS_Store +.DS_Store diff --git a/build-tests.js b/build-tests.js new file mode 100644 index 00000000..fc8d697c --- /dev/null +++ b/build-tests.js @@ -0,0 +1,48 @@ +/** + * Question: Why are we even using QUnit? + * + * We should be migrating to a more modern unit testing framework like Jest or Ava. + * I hear some people have even gotten WebGL-related testing done with Jest. + */ + +const fs = require('fs'); +const path = require('path'); +const util = require('util'); +const { readDirDeep } = require('read-dir-deep'); + +const readFile = util.promisify(fs.readFile) +const unlink = util.promisify(fs.unlink) +const writeFile = util.promisify(fs.writeFile) + +const CWD = process.cwd(); + +async function main () { + const folder = 'test'; + const output = path.resolve(CWD, folder, 'all.html'); + const template = path.resolve(CWD, folder, 'all-template.html'); + const rootPath = path.resolve(CWD, folder); + const warning = '\n'; + + await unlink(output).catch(e => {}); + + const files = await readDirDeep(rootPath, { + patterns: [ '**/*.js' ], + ignore: [ '*.js' ] + }); + + const str = warning + files + .map(file => file.replace(/^test\//, '')) + .map(file => ``) + .join('\n'); + + const file = await readFile(template, 'utf8'); + + const data = file.replace('{{test-files}}', str); + + await writeFile(output, data); +}; + +main().catch(err => { + console.error(err.message) + process.exit(1) +}); diff --git a/dist/gpu-browser-core.js b/dist/gpu-browser-core.js index 0db03108..aebab023 100644 --- a/dist/gpu-browser-core.js +++ b/dist/gpu-browser-core.js @@ -1,14118 +1,12168 @@ /** * gpu.js - * http://gpu.rocks/ + * https://gpu.rocks/ * * GPU Accelerated JavaScript * * @version 2.0.5 - * @date Fri Oct 11 2019 07:23:33 GMT-0400 (Eastern Daylight Time) + * @date Tue Oct 29 2019 10:46:59 GMT-0400 (Eastern Daylight Time) * * @license MIT * The MIT License * * Copyright (c) 2019 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 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 insertVariable(name, value) { - variables[name] = value; - } - function getEntity(value) { - const name = entityNames[value]; - if (name) { - return contextName + '.' + name; + 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 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}})();`); + return matrix; } - 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; - } + 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); } } - return null; } - - function getContextVariableName(value) { - const i = contextVariables.indexOf(value); - if (i !== -1) { - return `${contextName}Variable${i}`; + 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 null; + return cube; } -} - -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); + 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.exec = function() { + return new Promise((resolve, reject) => { + try { + resolve(kernel.apply(kernel, arguments)); + } catch(e) { + reject(e); } - return result; - }; + }); + }; + 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; + }; + kernel.setWarnVarUsage = () => { + return kernel; + }; + kernel.setOptimizeFloatMemory = () => { + return kernel; + }; + kernel.setArgumentTypes = () => { + return kernel; + }; + kernel.setDebug = () => { + return kernel; + }; + kernel.setLoopMaxIterations = () => { + return kernel; + }; + kernel.setPipeline = () => { + return kernel; + }; + kernel.setPrecision = () => { + return kernel; + }; + kernel.setImmutable = () => { + return kernel; + }; + kernel.setFunctions = () => { + return kernel; + }; + kernel.addSubKernel = () => { + return kernel; + }; + kernel.destroy = () => {}; + kernel.validateSettings = () => {}; + if (kernel.graphical && kernel.output) { + setupGraphical(kernel); } - extensionEntityNames[extension[property]] = property; - return extension[property]; + return kernel; } - - function getExtensionEntity(value) { - if (extensionEntityNames.hasOwnProperty(value)) { - return `${contextName}.${extensionEntityNames[value]}`; + 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 getEntity(value); + return result; } - - function methodCallToString(method, args) { - return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`; + 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 addVariable(value, source) { - const variableName = `${contextName}Variable${contextVariables.length}`; - contextVariables.push(value); - recording.push(`${indent}const ${variableName} = ${source};`); - return variableName; + 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; } -} + var gpuMock_js = { + gpuMock + }; + var gpuMock_js_1 = gpuMock_js.gpuMock; -function argumentsToString(args, options) { - const { variables, onUnrecognizedArgumentLookup } = options; - return (Array.from(args).map((arg) => { - const variableName = getVariableName(arg); - if (variableName) { - return variableName; + const ARGUMENT_NAMES = /([^\s,]+)/g; + const FUNCTION_NAME = /function ([^(]*)/; + const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; + function isFunction(funcObj) { + return typeof(funcObj) === 'function'; + }function getFunctionNameFromString(funcStr) { + return FUNCTION_NAME.exec(funcStr)[1].trim(); + }function functionToIFunction(source, settings) { + settings = 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 = getArgumentNamesFromString(sourceString) + .map(name => settings.argumentTypes[name]) || []; + } else { + argumentTypes = settings.argumentTypes || []; } - 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; - } + return { + source: sourceString, + argumentTypes, + returnType: settings.returnType || null, + }; + }function warnDeprecated(type, oldName, newName) { + const msg = newName + ? `It has been replaced with "${ newName }"` + : 'It has been removed'; + console.warn(`You are using a deprecated ${ type } "${ oldName }". ${msg}. Fixing, but please upgrade as it will soon be removed.`); + }function isFunctionString(fn) { + if (typeof fn === 'string') { + return (fn + .slice(0, 'function'.length) + .toLowerCase() === 'function'); + } + return false; + }function 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; + }function isArray(array) { + return !isNaN(array.length); + }function 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; + }function 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; } - if (onUnrecognizedArgumentLookup) { - return onUnrecognizedArgumentLookup(value); + return zResults; + }function 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 null; + return result.join('\n'); } -} -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 + "'"; + var common = /*#__PURE__*/Object.freeze({ + isFunction: isFunction, + getFunctionNameFromString: getFunctionNameFromString, + functionToIFunction: functionToIFunction, + warnDeprecated: warnDeprecated, + isFunctionString: isFunctionString, + getArgumentNamesFromString: getArgumentNamesFromString, + isArray: isArray, + erectMemoryOptimized2DFloat: erectMemoryOptimized2DFloat, + erectMemoryOptimized3DFloat: erectMemoryOptimized3DFloat, + getAstString: getAstString + }); + + class Input { + constructor(value, size) { + this.value = value; + if (Array.isArray(size)) { + this.size = size; } 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; + 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}`); } } - 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); + toArray() { + const [ w, h, d ] = this.size; + if (d) { + return erectMemoryOptimized3DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h, d); + } else if (h) { + return erectMemoryOptimized2DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h); + } else { + return this.value; + } } - matrix[y] = row; + }function input(value, size) { + return new Input(value, size); } - 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); + class Texture { + constructor(settings) { + const { + texture, + size, + dimensions, + output, + context, + type = 'NumberTexture', + } = settings; + if (!output) throw new Error('settings property "output" required.'); + if (!context) throw new Error('settings property "context" required.'); + this.texture = texture; + this.size = size; + this.dimensions = dimensions; + this.output = output; + this.context = context; + this.kernel = null; + this.type = type; } - } -} - -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; + toArray() { + throw new Error(`Not implemented on ${this.constructor.name}`); + } + delete() { + return this.context.deleteTexture(this.texture); } - cube[z] = matrix; } - return cube; -} -function apiDecorate(kernel) { - kernel.setOutput = (output) => { - kernel.output = setupOutput(output); - if (kernel.graphical) { - setupGraphical(kernel); + function 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'); + }const _systemEndianness = getSystemEndianness(); + function systemEndianness() { + return _systemEndianness; + }function getVariableType(value, strictIntegers) { + if (isArray(value)) { + if (value[0].nodeName === 'IMG') { + return 'HTMLImageArray'; + } + return 'Array'; } - }; - 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.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; + switch (value.constructor) { + case Boolean: + return 'Boolean'; + case Number: + return strictIntegers && Number.isInteger(value) ? 'Integer' : 'Float'; + case Texture: + return value.type; + case Input: + return 'Input'; } - - 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; - }; - - kernel.setWarnVarUsage = () => { - return kernel; - }; - kernel.setOptimizeFloatMemory = () => { - return kernel; - }; - kernel.setArgumentTypes = () => { - return kernel; - }; - kernel.setDebug = () => { - return kernel; - }; - kernel.setLoopMaxIterations = () => { - return kernel; - }; - kernel.setPipeline = () => { - return kernel; - }; - kernel.setPrecision = () => { - return kernel; - }; - kernel.setImmutable = () => { - return kernel; - }; - kernel.setFunctions = () => { - return kernel; - }; - kernel.addSubKernel = () => { - return kernel; - }; - kernel.destroy = () => {}; - kernel.validateSettings = () => {}; - if (kernel.graphical && kernel.output) { - setupGraphical(kernel); - } - 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 }; + switch (value.nodeName) { + case 'IMG': + return 'HTMLImage'; + case 'VIDEO': + return 'HTMLVideo'; } - } 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 value.hasOwnProperty('type') ? value.type : 'Unknown'; + }const utils$1 = { + systemEndianness, + getSystemEndianness, + isFunction, + isFunctionString, + getFunctionNameFromString, + getFunctionBodyFromString(funcStr) { + return funcStr.substring(funcStr.indexOf('{') + 1, funcStr.lastIndexOf('}')); + }, + getArgumentNamesFromString, + 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$1.clone(obj[key]); + delete obj.isActiveClone; + } + } + return temp; + }, + isArray, + getVariableType, + 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$1.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$1.roundTo((dimensions[0] || 1) * (dimensions[1] || 1) * (dimensions[2] || 1) * (dimensions[3] || 1), 4); + const texelCount = totalArea / bitRatio; + return utils$1.closestSquareDimensions(texelCount); + }, + getMemoryOptimizedPackedTextureSize(dimensions, bitRatio) { + const [w, h, d] = dimensions; + const totalArea = utils$1.roundTo((w || 1) * (h || 1) * (d || 1), 4); + const texelCount = totalArea / (4 / bitRatio); + return utils$1.closestSquareDimensions(texelCount); + }, + roundTo(n, d) { + return Math.floor((n + d - 1) / d) * d; + }, + getDimensions(x, pad) { + let ret; + if (isArray(x)) { + const dim = []; + let temp = x; + while (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}`); } - 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":111}],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(', '); + if (pad) { + ret = Array.from(ret); + while (ret.length < 3) { + ret.push(1); } - 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 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; } - } - - 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; + } + }, + 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; + } } } - 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'); + }, + flattenTo(array, target) { + if (isArray(array[0])) { + if (isArray(array[0][0])) { + if (isArray(array[0][0][0])) { + utils$1.flatten4dArrayTo(array, target); + } else { + utils$1.flatten3dArrayTo(array, target); + } + } else { + utils$1.flatten2dArrayTo(array, target); + } + } else { + target.set(array); } - retArr.push(`for (let ${iVariableName}=0;${iVariableName} 0) { - retArr.push(`if (!${testArr.join('')}) break;\n`); + }, + 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)); } - 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); + return result; + }, + getAstString, + 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'; } - this.popState('block-body'); - } else { - retArr.push('{\n'); - for (let i = 0; i < bNode.body.length; i++) { - this.astGeneric(bNode.body[i], retArr); + }, + warnDeprecated, + functionToIFunction, + 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); } - retArr.push('}\n'); - } - return retArr; - } - - astVariableDeclaration(varDecNode, retArr) { - if (varDecNode.kind === 'var' && this.warnVarUsage) { - this.varWarn(); - } - retArr.push(`${varDecNode.kind} `); - const { declarations } = varDecNode; - for (let i = 0; i < declarations.length; i++) { - if (i > 0) { - retArr.push(','); + 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); } - this.astGeneric(declarations[i], 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') { - this.astGeneric(ifNode.alternate, retArr); - } else { - retArr.push(' {\n'); - this.astGeneric(ifNode.alternate, retArr); - retArr.push('\n}\n'); + 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, + erectMemoryOptimized3DFloat, + 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 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'); + 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; } - 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'); + yResults[y] = xResults; } - } - 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; + 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; } - 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; + 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); } - 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; - 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; + yResults[y] = xResults; } - } - - const markupName = `${origin}_${name}`; - - switch (type) { - case 'Array(2)': - case 'Array(3)': - case 'Array(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(']'); + 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); } - } else if (typeof xProperty !== 'undefined') { - retArr.push('['); - this.astGeneric(xProperty, retArr); - retArr.push(']'); + yResults[y] = xResults; } - } - 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); + zResults[z] = yResults; } - - if (i > 0) { - retArr.push(', '); + 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); } - this.astGeneric(argument, retArr); - } - retArr.push(')'); - - return retArr; - } - - astArrayExpression(arrNode, retArr) { - const arrLen = arrNode.elements.length; - - retArr.push('new Float32Array(['); - for (let i = 0; i < arrLen; ++i) { - if (i > 0) { - retArr.push(', '); + 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; } - const subNode = arrNode.elements[i]; - this.astGeneric(subNode, retArr) - } - retArr.push('])'); - - 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)': - 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 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; } - return JSON.stringify(cpuKernel[propertyName]); - }, - findDependency: (object, name) => { - return null; + zResults[z] = yResults; } - }); - - 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 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); } - return JSON.stringify(cpuKernel[propertyName]); - }, - findDependency: () => { - return null; + yResults[y] = xResults; } - }); - - 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 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; } - return null; - }, - thisLookup: (propertyName) => { - switch (propertyName) { - case 'canvas': - return; - case 'context': - return 'context'; + 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 = []; + 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); + case 'FunctionDeclaration': + return `function ${ast.id.name}(${ast.params.map(flatten).join(', ')}) ${ flatten(ast.body) }`; + case 'BlockStatement': { + const result = []; + for (let i = 0; i < ast.body.length; i++) { + result.push(flatten(ast.body[i]), ';\n'); + } + return `{\n${result.join('')}}`; + } + case 'VariableDeclaration': + switch (ast.declarations[0].id.type) { + case 'ObjectPattern': { + const source = flatten(ast.declarations[0].init); + const properties = ast.declarations.map(declaration => declaration.id.properties.map(flatten))[0]; + if (/this/.test(source)) { + const result = []; + const lookups = properties.map(thisLookup); + for (let i = 0; i < lookups.length; i++) { + const lookup = lookups[i]; + if (lookup === null) continue; + const property = properties[i]; + result.push(`${ast.kind} ${ property } = ${ lookup };\n`); + } + return result.join(''); + } + return `${ast.kind} { ${properties} } = ${source}`; + } + case 'ArrayPattern': + return `${ast.kind} [ ${ ast.declarations.map(declaration => flatten(declaration.id)).join(', ') } ] = ${flatten(ast.declarations[0].init)}`; + } + if (doNotDefine && doNotDefine.indexOf(ast.declarations[0].id.name) !== -1) { + return ''; + } + return `${ast.kind} ${ast.declarations[0].id.name} = ${flatten(ast.declarations[0].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 '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 }`); } - }); - 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'; + 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; + } + flattenedFunctionDependencies.push(utils$1.flattenFunctionToString(functionDependency, settings) + ';\n'); } - throw new Error('unhandled thisLookup'); + return flattenedFunctionDependencies.join('') + result; } - }); - 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)': - 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":111}],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() { - return null; - } - - static combineKernels(combinedKernel) { - return combinedKernel; - } - - constructor(source, settings) { - super(source, settings); - this.mergeSettings(source.settings || settings); - - this._imageData = null; - this._colorData = null; - this._kernelString = null; - 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 []; - } + return result; + }, + }; - 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'); + 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 (!isFunctionString(source)) { + throw new Error('source not a function string'); + } + } + this.useLegacyEncoder = false; + this.fallbackRequested = false; + this.onRequestFallback = null; + this.argumentNames = typeof source === 'string' ? getArgumentNamesFromString(source) : null; + this.argumentTypes = null; + this.argumentSizes = null; + this.argumentBitRatios = null; + this.kernelArguments = null; + this.kernelConstants = 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 = 'balanced'; + this.plugins = null; + this.returnType = null; + this.leadingReturnStatement = null; + this.followingReturnStatement = null; + this.optimizeFloatMemory = null; + this.strictIntegers = false; + this.fixIntegerDivisionAccuracy = null; + this.warnVarUsage = true; + } + 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': + if (typeof settings.functions[0] === 'function') { + this.functions = settings.functions.map(source => functionToIFunction(source)); + continue; + } + break; + case 'graphical': + if (settings[p] && !settings.hasOwnProperty('precision')) { + this.precision = 'unsigned'; + } + this[p] = settings[p]; + continue; + } + this[p] = settings[p]; } - - 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; + 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 }`); + } + setupArguments(args) { + this.kernelArguments = []; + if (!this.argumentTypes) { + if (!this.argumentTypes) { + this.argumentTypes = []; + for (let i = 0; i < args.length; i++) { + const argType = getVariableType(args[i], this.strictIntegers); + const type = argType === 'Integer' ? 'Number' : argType; + this.argumentTypes.push(type); + this.kernelArguments.push({ + type + }); + } + } } else { - throw new Error('Auto output not supported for input type: ' + argType); + for (let i = 0; i < this.argumentTypes.length; i++) { + this.kernelArguments.push({ + type: this.argumentTypes[i] + }); + } } - } - - if (this.graphical) { - if (this.output.length !== 2) { - throw new Error('Output must have 2 dimensions on graphical mode'); + 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`); } } - - 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`); + 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 = 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]); + } } - this.followingReturnStatement = followingReturnStatement.join(''); } - const functionBuilder = FunctionBuilder.fromKernel(this, CPUFunctionNode); - this.translatedSources = functionBuilder.getPrototypes('kernel'); - if (!this.graphical && !this.returnType) { - this.returnType = functionBuilder.getKernelResultType(); + setOptimizeFloatMemory(flag) { + this.optimizeFloatMemory = flag; + return this; } - } - - build() { - 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'); + 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; } - 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); + return this; } - - const kernelString = this.getKernelString(); - this.kernelString = kernelString; - - if (this.debug) { - console.log('Function output:'); - console.log(kernelString); + setDebug(flag) { + this.debug = flag; + return this; } - - try { - this.run = new Function([], kernelString).bind(this)(); - } catch (e) { - console.error('An error occurred compiling the javascript: ', e); + setGraphical(flag) { + this.graphical = flag; + this.precision = 'unsigned'; + return this; } - } - - color(r, g, b, a) { - if (typeof a === 'undefined') { - a = 1; + setLoopMaxIterations(max) { + this.loopMaxIterations = max; + return this; } - - 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._processConstants() } - return (${ this.argumentNames.map(argumentName => 'user_' + argumentName).join(', ') }) => { - ${ 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 'HTMLImage': - 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`); - } + setConstants(constants) { + this.constants = constants; + return this; } - return result.join(''); - } - - _processArguments() { - const result = []; - for (let i = 0; i < this.argumentTypes.length; i++) { - const variableName = `user_${this.argumentNames[i]}`; - switch (this.argumentTypes[i]) { - case 'HTMLImage': - 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]; + setConstantTypes(constantTypes) { + this.constantTypes = constantTypes; + return this; + } + setFunctions(functions) { + if (typeof functions[0] === 'function') { + this.functions = functions.map(source => functionToIFunction(source)); } else { - _this.textureCache.push(${variableName}); - ${variableName} = ${variableName}.toArray(); - _this.arrayCache.push(${variableName}); - } - }`); - break; + this.functions = functions; } + return this; } - 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; - ctx.drawImage(media, 0, 0, width, height); - const 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; - } + setNativeFunctions(nativeFunctions) { + this.nativeFunctions = nativeFunctions; + return this; } - 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]); + setInjectedNative(injectedNative) { + this.injectedNative = injectedNative; + return this; } - return imagesArray; - } - - _resultKernelBody(kernelString) { - switch (this.output.length) { - case 1: - return this._resultKernel1DLoop(kernelString) + this._kernelOutput(); - case 2: - return this._resultKernel2DLoop(kernelString) + this._kernelOutput(); - case 3: - return this._resultKernel3DLoop(kernelString) + this._kernelOutput(); - default: - throw new Error('unsupported size kernel'); + setPipeline(flag) { + this.pipeline = flag; + return this; } - } - - _graphicalKernelBody(kernelThreadString) { - switch (this.output.length) { - case 2: - return this._graphicalKernel2DLoop(kernelThreadString) + this._graphicalOutput(); - default: - throw new Error('unsupported size kernel'); + setPrecision(flag) { + this.precision = flag; + return this; } - } - - _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 }`); + setOutputToTexture(flag) { + warnDeprecated('method', 'setOutputToTexture', 'setPipeline'); + this.pipeline = flag; + return this; } - } - - _resultKernel1DLoop(kernelString) { - const { - output - } = this; - 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 } - }`; - } - - _resultKernel2DLoop(kernelString) { - const { - output - } = this; - 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 } - } - }`; - } - - _graphicalKernel2DLoop(kernelString) { - const { - output - } = this; - const constructorString = this._getKernelResultTypeConstructorString(); - return ` const outputX = _this.output[0]; - const outputY = _this.output[1]; - ${ 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; - ${ 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 } - } - }`; - } - - _resultKernel3DLoop(kernelString) { - const { - output - } = this; - 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 } - } - } - }`; - } - - _kernelOutput() { - if (!this.subKernels) { - return '\n return result;'; + setImmutable(flag) { + this.immutable = flag; + return this; } - 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; + setCanvas(canvas) { + this.canvas = canvas; + return this; } - } - - 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); + setStrictIntegers(flag) { + this.strictIntegers = flag; + return this; } - } -} - -module.exports = { - CPUKernel -}; -},{"../../utils":111,"../function-builder":8,"../kernel":34,"./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, - warnVarUsage, - } = kernel; - - const argumentTypes = new Array(kernelArguments.length); - const constantTypes = {}; - - for (let i = 0; i < kernelArguments.length; i++) { - argumentTypes[i] = kernelArguments[i].type; + setDynamicOutput(flag) { + this.dynamicOutput = flag; + return this; } - - for (let i = 0; i < kernelConstants.length; i++) { - const kernelConstant = kernelConstants[i]; - constantTypes[kernelConstant.name] = kernelConstant.type; + setHardcodeConstants(flag) { + warnDeprecated('method', 'setHardcodeConstants'); + this.setDynamicOutput(flag); + this.setDynamicArguments(flag); + return this; } - - 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, returnType) => { - const argumentNames = []; - for (let i = 0; i < ast.params.length; i++) { - argumentNames.push(ast.params[i].name); - } - const nestedFunction = new FunctionNode(null, Object.assign({}, nodeOptions, { - returnType: null, - ast, - name: ast.id.name, - argumentNames, - lookupReturnType, - lookupFunctionArgumentTypes, - lookupFunctionArgumentName, - lookupFunctionArgumentBitRatio, - needsArgumentType, - assignArgumentType, - triggerImplyArgumentType, - triggerImplyArgumentBitRatio, - onFunctionCall, - warnVarUsage, - })); - 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); + setDynamicArguments(flag) { + this.dynamicArguments = flag; + return this; } - - 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, - })); + setUseLegacyEncoder(flag) { + this.useLegacyEncoder = flag; + return this; } - - 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, - })); - }); + setWarnVarUsage(flag) { + this.warnVarUsage = flag; + return this; } - - 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.argumentChain = []; - this.functionNodeDependencies = {}; - this.functionCalls = {}; - - if (this.rootNode) { - this.functionMap['kernel'] = this.rootNode; + getCanvas() { + warnDeprecated('method', 'getCanvas'); + return this.canvas; } - - if (this.functionNodes) { - for (let i = 0; i < this.functionNodes.length; i++) { - this.functionMap[this.functionNodes[i].name] = this.functionNodes[i]; - } + getWebGl() { + warnDeprecated('method', 'getWebGl'); + return this.context; } - - if (this.subKernelNodes) { - for (let i = 0; i < this.subKernelNodes.length; i++) { - this.functionMap[this.subKernelNodes[i].name] = this.subKernelNodes[i]; - } + setContext(context) { + this.context = context; + return this; } - - if (this.nativeFunctions) { - for (let i = 0; i < this.nativeFunctions.length; i++) { - const nativeFunction = this.nativeFunctions[i]; - this.nativeFunctionNames.push(nativeFunction.name); + setArgumentTypes(argumentTypes) { + if (Array.isArray(argumentTypes)) { + this.argumentTypes = argumentTypes; + } else { + this.argumentTypes = []; + for (const p in argumentTypes) { + const argumentIndex = this.argumentNames.indexOf(p); + if (argumentIndex === -1) throw new Error(`unable to find argument ${ p }`); + this.argumentTypes[argumentIndex] = argumentTypes[p]; + } } + return this; } - } - - addFunctionNode(functionNode) { - if (!functionNode.name) throw new Error('functionNode.name needs set'); - this.functionMap[functionNode.name] = functionNode; - if (functionNode.isRootKernel) { - this.rootNode = functionNode; + setTactic(tactic) { + this.tactic = tactic; + return this; } - } - - traceFunctionCalls(functionName, retList) { - functionName = functionName || 'kernel'; - retList = retList || []; - - if (this.nativeFunctionNames.indexOf(functionName) > -1) { - if (retList.indexOf(functionName) === -1) { - retList.push(functionName); + requestFallback(args) { + if (!this.onRequestFallback) { + throw new Error(`"onRequestFallback" not defined on ${ this.constructor.name }`); } - return retList; + this.fallbackRequested = true; + return this.onRequestFallback(args); } - - 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); + 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; } - - return retList; - } - - getPrototypeString(functionName) { - return this.getPrototypes(functionName).join('\n'); - } - - getPrototypes(functionName) { - if (this.rootNode) { - this.rootNode.toString(); + 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; + } } - if (functionName) { - return this.getPrototypesFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse()); + getPixels() { + throw new Error(`"getPixels" called on ${ this.constructor.name }`); } - 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()); + checkOutput() { + if (!this.output || !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`); + } } } - return ret.join('\n'); + toJSON() { + const settings = { + output: this.output, + threadDim: this.threadDim, + 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, + }; + return { + settings + }; + } } - 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; + 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, + warnVarUsage, + } = 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 triggerTrackArgumentSynonym = (functionName, argumentName, calleeFunctionName, argumentIndex) => { + functionBuilder.trackArgumentSynonym(functionName, argumentName, calleeFunctionName, argumentIndex); + }; + const lookupArgumentSynonym = (originFunctionName, functionName, argumentName) => { + return functionBuilder.lookupArgumentSynonym(originFunctionName, functionName, argumentName); + }; + const onFunctionCall = (functionName, calleeFunctionName, args) => { + functionBuilder.trackFunctionCall(functionName, calleeFunctionName, args); + }; + const onNestedFunction = (ast, returnType) => { + const argumentNames = []; + for (let i = 0; i < ast.params.length; i++) { + argumentNames.push(ast.params[i].name); + } + const nestedFunction = new FunctionNode(null, Object.assign({}, nodeOptions, { + returnType: null, + ast, + name: ast.id.name, + argumentNames, + lookupReturnType, + lookupFunctionArgumentTypes, + lookupFunctionArgumentName, + lookupFunctionArgumentBitRatio, + needsArgumentType, + assignArgumentType, + triggerImplyArgumentType, + triggerTrackArgumentSynonym, + lookupArgumentSynonym, + onFunctionCall, + warnVarUsage, + })); + nestedFunction.traceFunctionAST(ast); + functionBuilder.addFunctionNode(nestedFunction); + }; + const nodeOptions = Object.assign({ + isRootKernel: false, + onNestedFunction, + lookupReturnType, + lookupFunctionArgumentTypes, + lookupFunctionArgumentName, + lookupFunctionArgumentBitRatio, + needsArgumentType, + assignArgumentType, + triggerImplyArgumentType, + triggerTrackArgumentSynonym, + lookupArgumentSynonym, + 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, + triggerTrackArgumentSynonym, + lookupArgumentSynonym, + onFunctionCall, + })); } - const node = this.functionMap[functionName]; - if (node) { - ret.push(node.toString()); + 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; } - 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`); + 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.argumentChain = []; + 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); + } } - }); - } - - 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 }`); + addFunctionNode(functionNode) { + if (!functionNode.name) throw new Error('functionNode.name needs set'); + this.functionMap[functionNode.name] = functionNode; + if (functionNode.isRootKernel) { + this.rootNode = functionNode; + } } - 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!'); + traceFunctionCalls(functionName, retList) { + functionName = functionName || 'kernel'; + retList = retList || []; + if (this.nativeFunctionNames.indexOf(functionName) > -1) { + if (retList.indexOf(functionName) === -1) { + retList.push(functionName); + } + 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); } - this.lookupChain.push({ - name: requestingNode.name, - ast, - requestingNode - }); - const type = node.getType(node.getJsAST()); - this.lookupChain.pop(); - return node.returnType = type; } + return retList; } - - 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'); + getPrototypeString(functionName) { + return this.getPrototypes(functionName).join('\n'); } - if (this.rootNode.name === functionName) { - const i = this.rootNode.argumentNames.indexOf(argumentName); - if (i !== -1) { - return this.rootNode.argumentBitRatios[i]; + getPrototypes(functionName) { + if (this.rootNode) { + this.rootNode.toString(); } + if (functionName) { + return this.getPrototypesFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse()); + } + return this.getPrototypesFromFunctionNames(Object.keys(this.functionMap)); } - 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] = []; + 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'); } - 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; + 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; } - if (!called) { - throw new Error(`SubKernel ${ subKernelNode.name } never called by kernel`); + 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`); + } + }); } - 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); + 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; } - 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'); + getString(functionName) { + if (functionName) { + return this.getStringFromFunctionNames(this.traceFunctionCalls(functionName).reverse()); + } + return this.getStringFromFunctionNames(Object.keys(this.functionMap)); } - 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.declarations = 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; - this.warnVarUsage = true; - - if (settings) { - for (const p in settings) { - if (!settings.hasOwnProperty(p)) continue; - if (!this.hasOwnProperty(p)) continue; - this[p] = settings[p]; + 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; } - - 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'); + _getFunction(functionName) { + if (!this._isFunction(functionName)) ; + return this.functionMap[functionName]; } - - if (!this.ast && !utils.isFunctionString(this.source)) { - throw new Error('this.source not a function string'); + _isFunction(functionName) { + return Boolean(this.functionMap[functionName]); } - - if (!this.name) { - throw new Error('this.name could not be set'); + _getNativeFunction(functionName) { + for (let i = 0; i < this.nativeFunctions.length; i++) { + if (this.nativeFunctions[i].name === functionName) return this.nativeFunctions[i]; + } + return null; } - - if (this.argumentTypes.length > 0 && this.argumentTypes.length !== this.argumentNames.length) { - throw new Error(`argumentTypes count of ${ this.argumentTypes.length } exceeds ${ this.argumentNames.length }`); + _isNativeFunction(functionName) { + return Boolean(this._getNativeFunction(functionName)); } - - if (this.output.length < 1) { - throw new Error('this.output is not big enough'); + _lookupNativeFunctionReturnType(functionName) { + let nativeFunction = this._getNativeFunction(functionName); + if (nativeFunction) { + return nativeFunction.returnType; + } + throw new Error(`Native function ${ functionName } not found`); } - } - - 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 }`); + lookupFunctionArgumentTypes(functionName) { + if (this._isNativeFunction(functionName)) { + return this._getNativeFunction(functionName).argumentTypes; + } else if (this._isFunction(functionName)) { + return this._getFunction(functionName).argumentTypes; + } + return null; } - 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'; + lookupFunctionArgumentName(functionName, argumentIndex) { + return this._getFunction(functionName).argumentNames[argumentIndex]; } - - if (ast.type === 'MemberExpression') { - if (ast.object && ast.property) { - if (ast.object.hasOwnProperty('name') && ast.object.name[0] === '_') { - return this.astMemberExpressionUnroll(ast.property); - } - - return ( - this.astMemberExpressionUnroll(ast.object) + - '.' + - this.astMemberExpressionUnroll(ast.property) - ); + 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]; + } else { + throw new Error('argument bit ratio not found'); + } + } else { + const node = this._getFunction(functionName); + const argumentSynonym = node.argumentSynonym[node.synonymIndex]; + if (!argumentSynonym) { + throw new Error('argument synonym not found'); + } + return this.lookupFunctionArgumentBitRatio(argumentSynonym.functionName, argumentSynonym.argumentName); + } + } + 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; + } + } + trackArgumentSynonym(functionName, argumentName, calleeFunctionName, argumentIndex) { + if (!this._isFunction(calleeFunctionName)) return; + const node = this._getFunction(calleeFunctionName); + if (!node.argumentSynonym) { + node.argumentSynonym = {}; + } + const calleeArgumentName = node.argumentNames[argumentIndex]; + if (!node.argumentSynonym[calleeArgumentName]) { + node.argumentSynonym[calleeArgumentName] = {}; + } + node.synonymIndex++; + node.argumentSynonym[node.synonymIndex] = { + functionName, + argumentName, + calleeArgumentName, + calleeFunctionName, + }; } - - 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]); + lookupArgumentSynonym(originFunctionName, functionName, argumentName) { + if (originFunctionName === functionName) return argumentName; + if (!this._isFunction(functionName)) return null; + const node = this._getFunction(functionName); + const argumentSynonym = node.argumentSynonym[node.synonymUseIndex]; + if (!argumentSynonym) return null; + if (argumentSynonym.calleeArgumentName !== argumentName) return null; + node.synonymUseIndex++; + if (originFunctionName !== functionName) { + return this.lookupArgumentSynonym(originFunctionName, argumentSynonym.functionName, argumentSynonym.argumentName); } + return argumentSynonym.argumentName; } - - 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'); + 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); } - - 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'); + getKernelResultType() { + return this.rootNode.returnType || this.rootNode.getType(this.rootNode.ast); } - - 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.declarations = []; - this.functions = functions; - for (let i = 0; i < declarations.length; i++) { - const declaration = declarations[i]; - const { ast, context, name, origin, forceInteger, assignable } = declaration; - const { init } = ast; - const dependencies = this.getDependencies(init); - let valueType = null; - - if (forceInteger) { - 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; - } + 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; } } - this.declarations.push({ - valueType, - dependencies, - isSafe: this.isSafeDependencies(dependencies), - ast, - name, - context, - origin, - assignable, - }); - } - - for (let i = 0; i < functions.length; i++) { - this.onNestedFunction(functions[i]); + if (!called) { + throw new Error(`SubKernel ${ subKernelNode.name } never called by kernel`); + } + return subKernelNode.returnType || subKernelNode.getType(subKernelNode.getJsAST()); } - } - - getDeclaration(ast) { - for (let i = 0; i < this.identifiers.length; i++) { - const identifier = this.identifiers[i]; - if (ast === identifier.ast && identifier.context.hasOwnProperty(ast.name)) { - for (let j = 0; j < this.declarations.length; j++) { - const declaration = this.declarations[j]; - if (declaration.name === ast.name && declaration.context[ast.name] === identifier.context[ast.name]) { - return declaration; - } - } + 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; } - 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; - } + class FunctionTracer { + constructor(ast) { + this.runningContexts = []; + this.contexts = []; + this.functionCalls = []; + this.declarations = []; + this.identifiers = []; + this.functions = []; + this.returnStatements = []; + this.inLoopInit = false; + this.scan(ast); } - if (!type && this.strictTypingChecking) { - throw new Error(`Declaration of ${name} not found`); + get currentContext() { + return this.runningContexts.length > 0 ? this.runningContexts[this.runningContexts.length - 1] : null; } - return type; - } - - getLookupType(type) { - if (!typeLookupMap.hasOwnProperty(type)) { - throw new Error(`unknown typeLookupMap ${ type }`); + newContext(run) { + const newContext = Object.assign({}, this.currentContext); + this.contexts.push(newContext); + this.runningContexts.push(newContext); + run(); + this.runningContexts.pop(); } - return typeLookupMap[type]; - } - - getConstantType(constantName) { - if (this.constantTypes[constantName]) { - const type = this.constantTypes[constantName]; - if (type === 'Float') { - return 'Number'; - } else { - return type; + scan(ast) { + if (Array.isArray(ast)) { + for (let i = 0; i < ast.length; i++) { + this.scan(ast[i]); + } + return; } - } - 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': - return `Array(${ ast.elements.length })`; - case 'Literal': - const literalKey = `${ast.start},${ast.end}`; - 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'; - } + switch (ast.type) { + case 'Program': + this.scan(ast.body); + break; + case 'BlockStatement': + this.newContext(() => { + this.scan(ast.body); + }); + break; 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); - } - 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': + this.scan(ast.left); + this.scan(ast.right); + break; 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; + this.scan(ast.left); + this.scan(ast.right); + break; 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; - } + this.scan(ast.argument); + break; + case 'VariableDeclaration': + this.scan(ast.declarations); + break; 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); + const { currentContext } = this; + const declaration = { + ast: ast, + context: currentContext, + name: ast.id.name, + origin: 'declaration', + forceInteger: this.inLoopInit, + assignable: !this.inLoopInit && !currentContext.hasOwnProperty(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); } - - return declaration.valueType; + break; + case 'IfStatement': + this.scan(ast.test); + this.scan(ast.consequent); + if (ast.alternate) this.scan(ast.alternate); + break; + case 'ForStatement': + this.newContext(() => { + this.inLoopInit = true; + this.scan(ast.init); + this.inLoopInit = false; + this.scan(ast.test); + this.scan(ast.update); + this.newContext(() => { + this.scan(ast.body); + }); + }); + break; + case 'DoWhileStatement': + case 'WhileStatement': + this.newContext(() => { + this.scan(ast.body); + this.scan(ast.test); + }); + break; case 'Identifier': - if (ast.name === 'Infinity') { - return 'Number'; - } - if (this.isAstVariable(ast)) { - const signature = this.getVariableSignature(ast); - if (signature === 'value') { - const type = this.getVariableType(ast); - if (!type) { - throw this.astErrorOutput(`Unable to find identifier valueType`, ast); - } - return type; - } - } - const origin = this.findIdentifierOrigin(ast); - if (origin && origin.init) { - return this.getType(origin.init); - } - return null; + this.identifiers.push({ + context: this.currentContext, + ast, + }); + break; case 'ReturnStatement': - return this.getType(ast.argument); + this.returnStatements.push(ast); + this.scan(ast.argument); + break; 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.getVariableType(ast.object)); - case 'value[][]': - return this.getLookupType(this.getVariableType(ast.object.object)); - case 'value[][][]': - return this.getLookupType(this.getVariableType(ast.object.object.object)); - case 'value[][][][]': - return this.getLookupType(this.getVariableType(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()[]': - return this.getLookupType(this.getType(ast.object)); - case 'fn()[][]': - return this.getLookupType(this.getType(ast.object)); - case 'fn()[][][]': - return this.getLookupType(this.getType(ast.object)); - case 'value.value': - if (this.isAstMathVariable(ast)) { - return 'Number'; - } - switch (ast.property.name) { - case 'r': - return this.getLookupType(this.getVariableType(ast.object)); - case 'g': - return this.getLookupType(this.getVariableType(ast.object)); - case 'b': - return this.getLookupType(this.getVariableType(ast.object)); - case 'a': - return this.getLookupType(this.getVariableType(ast.object)); - } - case '[][]': - return 'Number'; - } - throw this.astErrorOutput('Unhandled getType MemberExpression', ast); - } - throw this.astErrorOutput('Unhandled getType MemberExpression', ast); + this.scan(ast.object); + this.scan(ast.property); + break; + case 'ExpressionStatement': + this.scan(ast.expression); + break; + case 'CallExpression': + this.functionCalls.push({ + context: this.currentContext, + ast, + }); + this.scan(ast.arguments); + break; + case 'ArrayExpression': + this.scan(ast.elements); + break; 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); + 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': + this.scan(ast.left); + this.scan(ast.right); + break; + case 'Literal': + case 'DebuggerStatement': + case 'EmptyStatement': + case 'BreakStatement': + case 'ContinueStatement': + break; default: - throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast); + throw new Error(`unhandled type "${ast.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]); + 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 || getFunctionNameFromString(source)) : null; + this.calledFunctions = []; + this.constants = {}; + this.constantTypes = {}; + this.constantBitRatios = {}; + this.isRootKernel = false; + this.isSubKernel = false; + this.debug = null; + this.declarations = 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' ? 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; + this.warnVarUsage = true; + if (settings) { + for (const p in settings) { + if (!settings.hasOwnProperty(p)) continue; + if (!this.hasOwnProperty(p)) continue; + this[p] = settings[p]; + } } - this.assignArgumentType(functionName, i, type); + this.literalTypes = {}; + this.validate(); + this._string = null; + this._internalVariableNames = {}; } - } - - 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', - 'asin', - 'atan', - 'atan2', - 'ceil', - 'cos', - 'exp', - 'floor', - 'log', - 'log2', - 'max', - 'min', - 'pow', - 'random', - 'round', - 'sign', - 'sin', - 'sqrt', - 'tan', - ]; - 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 = []; + validate() { + if (typeof this.source !== 'string' && !this.ast) { + throw new Error('this.source not a string'); + } + if (!this.ast && !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'; } - if (!ast) return null; - if (Array.isArray(ast)) { - for (let i = 0; i < ast.length; i++) { - this.getDependencies(ast[i], dependencies, isNotSafe); + pushState(state) { + this.states.push(state); + } + popState(state) { + if (this.state !== state) { + throw new Error(`Cannot popState ${ state } when in ${ this.state }`); } - return dependencies; + this.states.pop(); } - 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) + 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[0] === '_') { + 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; + } + const parser = inParser && inParser.hasOwnProperty('parse') ? inParser.parse : acorn.parse; + if (inParser === null) { + throw new Error('Missing JS to AST parser'); + } + const ast = Object.freeze(parser(`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.declarations = []; + this.functions = functions; + for (let i = 0; i < declarations.length; i++) { + const declaration = declarations[i]; + const { ast, context, name, origin, forceInteger, assignable } = declaration; + const { init } = ast; + const dependencies = this.getDependencies(init); + let valueType = null; + if (forceInteger) { + 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; + } + } + } + this.declarations.push({ + valueType, + dependencies, + isSafe: this.isSafeDependencies(dependencies), + ast, + name, + context, + origin, + assignable, }); - break; - case 'VariableDeclarator': - return this.getDependencies(ast.init, dependencies, isNotSafe); - case 'Identifier': + } + for (let i = 0; i < functions.length; i++) { + this.onNestedFunction(functions[i]); + } + } + getDeclaration(ast) { + for (let i = 0; i < this.identifiers.length; i++) { + const identifier = this.identifiers[i]; + if (ast === identifier.ast && identifier.context.hasOwnProperty(ast.name)) { + for (let j = 0; j < this.declarations.length; j++) { + const declaration = this.declarations[j]; + if (declaration.name === ast.name && declaration.context[ast.name] === identifier.context[ast.name]) { + return 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) { - 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': - 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; + return declaration.valueType; } - 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; + } else { + const argumentType = this.argumentTypes[argumentIndex]; + if (argumentType) { + type = argumentType; } - default: - throw this.astErrorOutput(`Unhandled type ${ ast.type } in getDependencies`, ast); + } + if (!type && this.strictTypingChecking) { + throw new Error(`Declaration of ${name} not found`); + } + return type; } - return dependencies; - } - - getVariableSignature(ast) { - 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('.value'); - } else if ( - ast.property.name === 'constants' || - ast.property.name === 'thread' || - ast.property.name === 'output' - ) { - signature.unshift('.' + ast.property.name); + 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 { - signature.unshift('.value'); - } - } else if (ast.name) { - signature.unshift('value'); - } else if (ast.callee && ast.callee.name) { - signature.unshift('fn()'); - } else if (ast.elements) { - signature.unshift('[]'); - } else { - signature.unshift('unknown'); + return type; + } } - ast = ast.object; + throw new Error(`Type for constant "${ constantName }" not declared`); } - - const signatureString = signature.join(''); - 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; + toString() { + if (this._string) return this._string; + return this._string = this.astGeneric(this.getJsAST(), []).join('').trim(); } - return null; - } - - build() { - return this.toString().length > 0; - } - - astGeneric(ast, retArr) { - if (ast === null) { - throw this.astErrorOutput('NULL ast', ast); - } else { + 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)) { - for (let i = 0; i < ast.length; i++) { - this.astGeneric(ast[i], retArr); - } - return retArr; + return this.getType(ast[ast.length - 1]); } - 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); + return this.getType(ast.body); case 'ArrayExpression': - return this.astArrayExpression(ast, retArr); - case 'DebuggerStatement': - return this.astDebuggerStatement(ast, retArr); + return `Array(${ ast.elements.length })`; + case 'Literal': + const literalKey = `${ast.start},${ast.end}`; + 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); + } + 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 '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') { + const type = this.getVariableType(ast); + if (!type) { + throw this.astErrorOutput(`Unable to find identifier valueType`, ast); + } + return type; + } + } + 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.getVariableType(ast.object)); + case 'value[][]': + return this.getLookupType(this.getVariableType(ast.object.object)); + case 'value[][][]': + return this.getLookupType(this.getVariableType(ast.object.object.object)); + case 'value[][][][]': + return this.getLookupType(this.getVariableType(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()[]': + return this.getLookupType(this.getType(ast.object)); + case 'fn()[][]': + return this.getLookupType(this.getType(ast.object)); + case 'fn()[][][]': + return this.getLookupType(this.getType(ast.object)); + case 'value.value': + if (this.isAstMathVariable(ast)) { + return 'Number'; + } + switch (ast.property.name) { + case 'r': + return this.getLookupType(this.getVariableType(ast.object)); + case 'g': + return this.getLookupType(this.getVariableType(ast.object)); + case 'b': + return this.getLookupType(this.getVariableType(ast.object)); + case 'a': + return this.getLookupType(this.getVariableType(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); + default: + throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast); + } + } + 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', + 'asin', + 'atan', + 'atan2', + 'ceil', + 'cos', + 'exp', + 'floor', + 'log', + 'log2', + 'max', + 'min', + 'pow', + 'random', + 'round', + 'sign', + 'sin', + 'sqrt', + 'tan', + ]; + 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': - return this.astConditionalExpression(ast, retArr); + 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': + 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; + } + default: + throw this.astErrorOutput(`Unhandled type ${ ast.type } in getDependencies`, ast); } - - throw this.astErrorOutput('Unknown ast type : ' + ast.type, ast); + return dependencies; } - } - astErrorOutput(error, ast) { - if (typeof this.source !== 'string') { - return new Error(error); + getVariableSignature(ast) { + 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('.value'); + } else if ( + ast.property.name === 'constants' || + ast.property.name === 'thread' || + ast.property.name === 'output' + ) { + signature.unshift('.' + ast.property.name); + } else { + signature.unshift('.value'); + } + } else if (ast.name) { + signature.unshift('value'); + } else if (ast.callee && ast.callee.name) { + signature.unshift('fn()'); + } else if (ast.elements) { + signature.unshift('[]'); + } else { + signature.unshift('unknown'); + } + ast = ast.object; + } + const signatureString = signature.join(''); + 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; } - - 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)) { + 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 = 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; } - return this.astFunction(ast, retArr); - } - astFunctionExpression(ast, retArr) { - if (this.isChildFunction(ast)) { + 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; } - return this.astFunction(ast, retArr); - } - isChildFunction(ast) { - for (let i = 0; i < this.functions.length; i++) { - if (this.functions[i] === ast) { - return true; + 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); } - return false; - } - astReturnStatement(ast, retArr) { - return retArr; - } - astLiteral(ast, retArr) { - this.literalTypes[`${ast.start},${ast.end}`] = '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; - } - astVariableDeclaration(varDecNode, retArr) { - const declarations = varDecNode.declarations; - if (!declarations || !declarations[0] || !declarations[0].init) { - throw this.astErrorOutput('Unexpected expression', varDecNode); + astFunctionExpression(ast, retArr) { + if (this.isChildFunction(ast)) { + return retArr; + } + return this.astFunction(ast, retArr); } - const result = []; - const firstDeclaration = declarations[0]; - const init = firstDeclaration.init; - let type = this.isState('in-for-loop-init') ? 'Integer' : this.getType(init); - if (type === 'LiteralInteger') { - type = 'Number'; - } - const markupType = typeMap[type]; - if (!markupType) { - throw this.astErrorOutput(`Markup type ${ markupType } not handled`, varDecNode); - } - let dependencies = this.getDependencies(firstDeclaration.init); - throw new Error('remove me'); - this.declarations[firstDeclaration.id.name] = Object.freeze({ - type, - dependencies, - isSafe: dependencies.every(dependency => dependency.isSafe) - }); - const initResult = [`${type} user_${firstDeclaration.id.name}=`]; - this.astGeneric(init, initResult); - result.push(initResult.join('')); - - for (let i = 1; i < declarations.length; i++) { - const declaration = declarations[i]; - dependencies = this.getDependencies(declaration); - throw new Error('Remove me'); - this.declarations[declaration.id.name] = Object.freeze({ + 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[`${ast.start},${ast.end}`] = '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; + } + astVariableDeclaration(varDecNode, retArr) { + const declarations = varDecNode.declarations; + if (!declarations || !declarations[0] || !declarations[0].init) { + throw this.astErrorOutput('Unexpected expression', varDecNode); + } + const result = []; + const firstDeclaration = declarations[0]; + const init = firstDeclaration.init; + let type = this.isState('in-for-loop-init') ? 'Integer' : this.getType(init); + if (type === 'LiteralInteger') { + type = 'Number'; + } + const markupType = typeMap[type]; + if (!markupType) { + throw this.astErrorOutput(`Markup type ${ markupType } not handled`, varDecNode); + } + let dependencies = this.getDependencies(firstDeclaration.init); + throw new Error('remove me'); + this.declarations[firstDeclaration.id.name] = Object.freeze({ type, dependencies, - isSafe: false + isSafe: dependencies.every(dependency => dependency.isSafe) }); - this.astGeneric(declaration, result); + const initResult = [`${type} user_${firstDeclaration.id.name}=`]; + this.astGeneric(init, initResult); + result.push(initResult.join('')); + for (let i = 1; i < declarations.length; i++) { + const declaration = declarations[i]; + dependencies = this.getDependencies(declaration); + throw new Error('Remove me'); + this.declarations[declaration.id.name] = Object.freeze({ + type, + dependencies, + isSafe: false + }); + this.astGeneric(declaration, result); + } + retArr.push(retArr, result.join(',')); + retArr.push(';'); + return retArr; } - - retArr.push(retArr, result.join(',')); - retArr.push(';'); - return retArr; - } - astVariableDeclarator(iVarDecNode, retArr) { - this.astGeneric(iVarDecNode.id, retArr); - if (iVarDecNode.init !== null) { - retArr.push('='); - this.astGeneric(iVarDecNode.init, retArr); + astVariableDeclarator(iVarDecNode, retArr) { + this.astGeneric(iVarDecNode.id, retArr); + if (iVarDecNode.init !== null) { + retArr.push('='); + this.astGeneric(iVarDecNode.init, retArr); + } + return retArr; } - return retArr; - } - astThisExpression(ast, retArr) { - return retArr; - } - astSequenceExpression(sNode, retArr) { - for (let i = 0; i < sNode.expressions.length; i++) { - if (i > 0) { - retArr.push(','); + astThisExpression(ast, retArr) { + return retArr; + } + astSequenceExpression(sNode, retArr) { + for (let i = 0; i < sNode.expressions.length; i++) { + if (i > 0) { + retArr.push(','); + } + this.astGeneric(sNode.expressions, retArr); } - this.astGeneric(sNode.expressions, retArr); + return retArr; } - return retArr; - } - astUnaryExpression(uNode, retArr) { - const unaryResult = this.checkAndUpconvertBitwiseUnary(uNode, retArr); - if (unaryResult) { + 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; } - - if (uNode.prefix) { - retArr.push(uNode.operator); - this.astGeneric(uNode.argument, retArr); - } else { - this.astGeneric(uNode.argument, retArr); - retArr.push(uNode.operator); + 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; } - - 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); + astLogicalExpression(logNode, retArr) { + retArr.push('('); + this.astGeneric(logNode.left, retArr); + retArr.push(logNode.operator); + this.astGeneric(logNode.right, retArr); + retArr.push(')'); + return retArr; } - - 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; + 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 { - name, - origin: 'Math', - type: 'Number', signature: variableSignature, + type: 'Integer', + name: ast.property.name }; - } - 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') { + case 'value[]': + if (typeof ast.object.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); - } + name = ast.object.name; return { name, - type, - origin: 'constants', + origin: 'user', signature: variableSignature, + type: this.getVariableType(ast.object), + xProperty: ast.property }; - case 'this.constants.value[]': - if (typeof ast.object.property.name !== 'string') { + case 'value[][]': + if (typeof ast.object.object.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); - } + name = ast.object.object.name; return { name, - type, - origin: 'constants', + origin: 'user', signature: variableSignature, + type: this.getVariableType(ast.object.object), + yProperty: ast.object.property, xProperty: ast.property, }; - case 'this.constants.value[][]': { - if (typeof ast.object.object.property.name !== 'string') { + case 'value[][][]': + if (typeof ast.object.object.object.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); - } + name = ast.object.object.object.name; return { name, - type, - origin: 'constants', - signature: variableSignature, - yProperty: ast.object.property, - xProperty: ast.property, + origin: 'user', + signature: variableSignature, + type: this.getVariableType(ast.object.object.object), + zProperty: ast.object.object.property, + yProperty: ast.object.property, + xProperty: ast.property, }; - } - case 'this.constants.value[][][]': { - if (typeof ast.object.object.object.property.name !== 'string') { + case 'value[][][][]': + if (typeof ast.object.object.object.object.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); - } + name = ast.object.object.object.object.name; return { name, - type, - origin: 'constants', - signature: variableSignature, - zProperty: ast.object.object.property, - yProperty: ast.object.property, - xProperty: ast.property, - }; - } - case 'fn()[]': - case '[][]': - return { - signature: variableSignature, - property: ast.property, + origin: 'user', + signature: variableSignature, + type: this.getVariableType(ast.object.object.object.object), + zProperty: ast.object.object.property, + yProperty: ast.object.property, + xProperty: 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; + 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 '[][]': + return { + signature: variableSignature, + property: ast.property, + }; + default: + throw this.astErrorOutput('Unexpected expression', ast); } - 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]); + } + 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; } - 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); + 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; } - 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]; - } - - varWarn() { - console.warn('var declarations are deprecated, weird things happen when falling back to CPU because var scope differs in javascript than in most languages. Use const or let'); - } -} - -const typeLookupMap = { - 'Number': 'Number', - 'Float': 'Float', - 'Integer': 'Integer', - 'Array': 'Number', - 'Array(2)': 'Number', - 'Array(3)': 'Number', - 'Array(4)': 'Number', - 'Array2D': 'Number', - 'Array3D': 'Number', - 'Input': 'Number', - 'HTMLImage': '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":111,"./function-tracer":10,"acorn":1}],10:[function(require,module,exports){ -class FunctionTracer { - constructor(ast) { - this.runningContexts = []; - this.contexts = []; - this.functionCalls = []; - this.declarations = []; - this.identifiers = []; - this.functions = []; - this.returnStatements = []; - this.inLoopInit = false; - this.scan(ast); - } - - get currentContext() { - return this.runningContexts.length > 0 ? this.runningContexts[this.runningContexts.length - 1] : null; - } - - newContext(run) { - const newContext = Object.assign({}, this.currentContext); - this.contexts.push(newContext); - this.runningContexts.push(newContext); - run(); - this.runningContexts.pop(); - } - - 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.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': - case 'UnaryExpression': - this.scan(ast.argument); - break; - case 'VariableDeclaration': - this.scan(ast.declarations); - break; - case 'VariableDeclarator': - const { currentContext } = this; - const declaration = { - ast: ast, - context: currentContext, - name: ast.id.name, - origin: 'declaration', - forceInteger: this.inLoopInit, - assignable: !this.inLoopInit && !currentContext.hasOwnProperty(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': - this.newContext(() => { - this.inLoopInit = true; - this.scan(ast.init); - this.inLoopInit = false; - this.scan(ast.test); - this.scan(ast.update); - this.newContext(() => { - this.scan(ast.body); - }); - }); - break; - case 'DoWhileStatement': - case 'WhileStatement': - this.newContext(() => { - this.scan(ast.body); - this.scan(ast.test); - }); - break; - case 'Identifier': - this.identifiers.push({ - context: this.currentContext, - ast, - }); - break; - case 'ReturnStatement': - this.returnStatements.push(ast); - this.scan(ast.argument); - break; - case 'MemberExpression': - this.scan(ast.object); - this.scan(ast.property); - break; - case 'ExpressionStatement': - this.scan(ast.expression); - 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, -}; -},{}],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.*/'); -} + 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]; + } + varWarn() { + console.warn('var declarations are deprecated, weird things happen when falling back to CPU because var scope differs in javascript than in most languages. Use const or let'); + } + } + const typeLookupMap = { + 'Number': 'Number', + 'Float': 'Float', + 'Integer': 'Integer', + 'Array': 'Number', + 'Array(2)': 'Number', + 'Array(3)': 'Number', + 'Array(4)': 'Number', + 'Array2D': 'Number', + 'Array3D': 'Number', + 'Input': 'Number', + 'HTMLImage': '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)', + }; -function glKernelString(Kernel, args, originKernel, setupContextString, destroyContextString) { - 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;'); + 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); } - return; + retArr.push(') {\n'); } - if (targetName) { - postResult.push(` return ${getRenderString(targetName, kernel)};`); - } else { - postResult.push(` return null;`); + for (let i = 0; i < ast.body.body.length; ++i) { + this.astGeneric(ast.body.body[i], retArr); + retArr.push('\n'); } - }, - onUnrecognizedArgumentLookup: (argument) => { - const argumentName = findKernelValue(argument, kernel.kernelArguments, [], context, uploadedValues); - if (argumentName) { - return argumentName; + if (!this.isRootKernel) { + retArr.push('}\n'); } - const constantName = findKernelValue(argument, kernel.kernelConstants, constants ? Object.keys(constants).map(key => constants[key]) : [], context, uploadedValues); - if (constantName) { - return constantName; + return retArr; + } + astReturnStatement(ast, retArr) { + const type = this.returnType || this.getType(ast.argument); + if (!this.returnType) { + this.returnType = type; } - return null; + 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; } - }); - 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, - } = originKernel; - const kernel = new Kernel(source, { - canvas, - context, - checkContext: false, - output, - pipeline, - graphical, - loopMaxIterations, - constants, - optimizeFloatMemory, - precision, - fixIntegerDivisionAccuracy, - functions, - nativeFunctions, - subKernels, - immutable, - argumentTypes, - constantTypes, - }); - 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 '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}`); + astLiteral(ast, retArr) { + if (isNaN(ast.value)) { + throw this.astErrorOutput( + 'Non-numeric literal not supported : ' + ast.value, + ast + ); + } + retArr.push(ast.value); + return retArr; } - }); - 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 results = kernel.renderKernels(); - const textureName = context.getContextVariableName(kernel.outputTexture); - result.push(` return { - result: { - texture: ${ textureName }, - type: '${ results.result.type }', - toArray: ${ getToArrayString(results.result, textureName) } - },`); - const { subKernels, subKernelOutputTextures } = kernel; - for (let i = 0; i < subKernels.length; i++) { - const texture = subKernelOutputTextures[i]; - const subKernel = subKernels[i]; - const subKernelResult = results[subKernel.property]; - const subKernelTextureName = context.getContextVariableName(texture); - result.push(` - ${subKernel.property}: { - texture: ${ subKernelTextureName }, - type: '${ subKernelResult.type }', - toArray: ${ getToArrayString(subKernelResult, subKernelTextureName) } - },`); + astBinaryExpression(ast, retArr) { + retArr.push('('); + this.astGeneric(ast.left, retArr); + retArr.push(ast.operator); + this.astGeneric(ast.right, retArr); + retArr.push(')'); + return retArr; } - result.push(` };`); - } - 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; + astIdentifierExpression(idtNode, retArr) { + if (idtNode.type !== 'Identifier') { + throw this.astErrorOutput( + 'IdentifierExpression - not an Identifier', + idtNode + ); } - if (kernel.hasOwnProperty(property)) { - return JSON.stringify(kernel[property]); + 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); + } } - throw new Error(`unhandled thisLookup ${ property }`); + return retArr; } - }); -} - -function getToArrayString(kernelResult, textureName) { - 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') { - return `${useFunctionKeyword ? 'function ' : ''}${kernelResult[name].toString()}`; + 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 { - throw new Error('unhandled fromObject'); + isSafe = false; } - }, - thisLookup: (property) => { - if (property === 'texture') { - return textureName; + 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 (kernelResult.hasOwnProperty(property)) { - return JSON.stringify(kernelResult[property]); + 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'); } - throw new Error(`unhandled thisLookup ${ property }`); + return retArr; } - }); - return `() => { - ${flattenedFunctions} - return toArray(); - }`; -} - -function findKernelValue(argument, kernelValues, values, context, uploadedValues) { - if (argument === 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') 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; + 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; } - return null; - } - - 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":111,"gl-wiretap":2}],12:[function(require,module,exports){ -const { Kernel } = require('../kernel'); -const { Texture } = require('../../texture'); -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 get testCanvas() { - throw new Error(`"testCanvas" not defined on ${ this.name }`); - } - - static get testContext() { - throw new Error(`"testContext" not defined on ${ this.name }`); - } - - static get features() { - throw new Error(`"features" not defined on ${ this.name }`); - } - - static setupFeatureChecks() { - throw new Error(`"setupFeatureChecks" not defined on ${ this.name }`); - } - - 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; + astDoWhileStatement(doWhileNode, retArr) { + if (doWhileNode.type !== 'DoWhileStatement') { + throw this.astErrorOutput( + 'Invalid while statement', + doWhileNode + ); } - - else if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '/') { - states.push('COMMENT'); - i += 2; - continue; - } else if (state === 'COMMENT' && char === '\n') { - states.pop(); - i++; - continue; + 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 new this.astErrorOutput(`Variable ${assNode.left.name} is not assignable here`, assNode); } - - else if (state === null && char === '(') { - states.push('FUNCTION_ARGUMENTS'); - i++; - continue; - } else if (state === 'FUNCTION_ARGUMENTS') { - if (char === ')') { - states.pop(); - break; + 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); } - 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; + 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) { + if (varDecNode.kind === 'var' && this.warnVarUsage) { + this.varWarn(); + } + retArr.push(`${varDecNode.kind} `); + const { declarations } = varDecNode; + for (let i = 0; i < declarations.length; i++) { + if (i > 0) { + retArr.push(','); + } + this.astGeneric(declarations[i], 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') { + 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'); + } } - - else if (state === 'DECLARE_VARIABLE') { - if (argumentName === '') { - if (char === ' ') { - i++; - continue; + 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); } - if (!isStartingVariableName.test(char)) { - throw new Error('variable name is not expected string'); + 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; + 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; } - argumentName += char; - if (!isVariableChar.test(nextChar)) { - states.pop(); - argumentNames.push(argumentName); - argumentTypes.push(typeMap[argumentType]); + } + const markupName = `${origin}_${name}`; + switch (type) { + case 'Array(2)': + case 'Array(3)': + case 'Array(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); } - - i++; + retArr.push(')'); + return retArr; } - if (states.length > 0) { - throw new Error('GLSL function was not parsable'); + astArrayExpression(arrNode, retArr) { + 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); + } + retArr.push('])'); + return retArr; + } + astDebuggerStatement(arrNode, retArr) { + retArr.push('debugger;'); + return retArr; } - 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); + 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)': + results.push(`${name}:new ${constant.constructor.name}(${JSON.stringify(Array.from(constant))})`); + break; + } } - - 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]); + 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$1.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$1.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$1.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$1.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)': + 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; +}`; } - 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.renderStrategy = null; - this.compiledFragmentShader = null; - this.compiledVertexShader = 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}]`); + class CPUKernel extends Kernel { + static getFeatures() { + return this.features; } - } - - 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; + 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; } - 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; + static nativeFunctionReturnType() { + return null; + } + static combineKernels(combinedKernel) { + return combinedKernel; + } + constructor(source, settings) { + super(source, settings); + this.mergeSettings(source.settings || settings); + this._imageData = null; + this._colorData = null; + this._kernelString = null; + 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'); } - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureUnsigned3D; - this.renderStrategy = renderStrategy.PackedPixelTo3DFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureUnsigned2D; - this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; - return null; - } else { - this.TextureConstructor = GLTextureUnsigned; - this.renderStrategy = renderStrategy.PackedPixelToFloat; - return null; - } - break; - 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.renderStrategy = renderStrategy.PackedPixelTo3DFloat; - this.formatValues = utils.erect3DPackedFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureUnsigned2D; - this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; - this.formatValues = utils.erect2DPackedFloat; - return null; - } else { - this.TextureConstructor = GLTextureUnsigned; - this.renderStrategy = renderStrategy.PackedPixelToFloat; - this.formatValues = utils.erectPackedFloat; - return null; - } - - break; - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - return this.requestFallback(args); + const argType = utils$1.getVariableType(args[0], this.strictIntegers); + if (argType === 'Array') { + this.output = utils$1.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); } } - } else if (this.precision === 'single') { - this.renderRawOutput = this.readFloatPixelsToFloat32Array; - this.transferValues = this.readFloatPixelsToFloat32Array; - if (this.pipeline) { - this.renderStrategy = renderStrategy.FloatTexture; - this.renderOutput = this.renderTexture; - if (this.subKernels !== null) { - this.renderKernels = this.renderKernelsToTextures; + if (this.graphical) { + if (this.output.length !== 2) { + throw new Error('Output must have 2 dimensions on graphical mode'); } - 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; - } - } - break; - 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; - } - break; - 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; - } - break; - 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.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(''); } - this.renderOutput = this.renderValues; - if (this.subKernels !== null) { - this.renderKernels = this.renderKernelsToArrays; + const functionBuilder = FunctionBuilder.fromKernel(this, CPUFunctionNode); + this.translatedSources = functionBuilder.getPrototypes('kernel'); + if (!this.graphical && !this.returnType) { + this.returnType = functionBuilder.getKernelResultType(); } - if (this.optimizeFloatMemory) { - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureMemoryOptimized3D; - this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized3DFloat; - this.formatValues = utils.erectMemoryOptimized3DFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureMemoryOptimized2D; - this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized2DFloat; - this.formatValues = utils.erectMemoryOptimized2DFloat; - return null; - } else { - this.TextureConstructor = GLTextureMemoryOptimized; - this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimizedFloat; - this.formatValues = utils.erectMemoryOptimizedFloat; - return null; - } + } + build() { + 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); + } + } + 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._processConstants() } + return (${ this.argumentNames.map(argumentName => 'user_' + argumentName).join(', ') }) => { + ${ 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 'HTMLImage': + case 'HTMLVideo': + result.push(` const constants_${p} = this._mediaTo2DArray(this.constants.${p});\n`); break; - case 'Array(2)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray2Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; - this.formatValues = utils.erect3DArray2; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray2Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; - this.formatValues = utils.erect2DArray2; - return null; - } else { - this.TextureConstructor = GLTextureArray2Float; - this.renderStrategy = renderStrategy.FloatPixelToArray2; - this.formatValues = utils.erectArray2; - return null; - } + case 'HTMLImageArray': + result.push(` const constants_${p} = this._imageTo3DArray(this.constants.${p});\n`); break; - case 'Array(3)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray3Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; - this.formatValues = utils.erect3DArray3; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray3Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; - this.formatValues = utils.erect2DArray3; - return null; - } else { - this.TextureConstructor = GLTextureArray3Float; - this.renderStrategy = renderStrategy.FloatPixelToArray3; - this.formatValues = utils.erectArray3; - return null; - } + case 'Input': + result.push(` const constants_${p} = this.constants.${p}.value;\n`); break; - case 'Array(4)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray4Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; - this.formatValues = utils.erect3DArray4; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray4Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; - this.formatValues = utils.erect2DArray4; - return null; - } else { - this.TextureConstructor = GLTextureArray4Float; - this.renderStrategy = renderStrategy.FloatPixelToArray4; - this.formatValues = utils.erectArray4; - return null; - } + default: + result.push(` const constants_${p} = this.constants.${p};\n`); } - } else { - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureFloat3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DFloat; - this.formatValues = utils.erect3DFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureFloat2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DFloat; - this.formatValues = utils.erect2DFloat; - return null; - } else { - this.TextureConstructor = GLTextureFloat; - this.renderStrategy = renderStrategy.FloatPixelToFloat; - this.formatValues = utils.erectFloat; - return null; - } + } + return result.join(''); + } + _processArguments() { + const result = []; + for (let i = 0; i < this.argumentTypes.length; i++) { + const variableName = `user_${this.argumentNames[i]}`; + switch (this.argumentTypes[i]) { + case 'HTMLImage': + case 'HTMLVideo': + result.push(` ${variableName} = this._mediaTo2DArray(${variableName});\n`); break; - case 'Array(2)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray2Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; - this.formatValues = utils.erect3DArray2; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray2Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; - this.formatValues = utils.erect2DArray2; - return null; - } else { - this.TextureConstructor = GLTextureArray2Float; - this.renderStrategy = renderStrategy.FloatPixelToArray2; - this.formatValues = utils.erectArray2; - return null; - } + case 'HTMLImageArray': + result.push(` ${variableName} = this._imageTo3DArray(${variableName});\n`); break; - case 'Array(3)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray3Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; - this.formatValues = utils.erect3DArray3; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray3Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; - this.formatValues = utils.erect2DArray3; - return null; - } else { - this.TextureConstructor = GLTextureArray3Float; - this.renderStrategy = renderStrategy.FloatPixelToArray3; - this.formatValues = utils.erectArray3; - return null; - } + 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; - case 'Array(4)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray4Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; - this.formatValues = utils.erect3DArray4; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray4Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; - this.formatValues = utils.erect2DArray4; - return null; - } else { - this.TextureConstructor = GLTextureArray4Float; - this.renderStrategy = renderStrategy.FloatPixelToArray4; - this.formatValues = utils.erectArray4; - return null; - } } } - } else { - throw new Error(`unhandled precision of "${this.precision}"`); + 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; + ctx.drawImage(media, 0, 0, width, height); + const 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$1.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; + } + _resultKernelBody(kernelString) { + switch (this.output.length) { + case 1: + return this._resultKernel1DLoop(kernelString) + this._kernelOutput(); + case 2: + return this._resultKernel2DLoop(kernelString) + this._kernelOutput(); + case 3: + return this._resultKernel3DLoop(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 }`); + } + } + _resultKernel1DLoop(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 } + }`; + } + _resultKernel2DLoop(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 } + } + }`; + } + _graphicalKernel2DLoop(kernelString) { + const constructorString = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const outputY = _this.output[1]; + ${ 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; + ${ 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 } + } + }`; + } + _resultKernel3DLoop(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 } + } + } + }`; + } + _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); + } } - - 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 }`); + class GLTextureFloat extends Texture { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(1)'; + } + renderRawOutput() { + const { context: gl } = this; + const framebuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_2D, + this.texture, + 0 + ); + const result = new Float32Array(this.size[0] * this.size[1] * 4); + gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.FLOAT, result); + return result; + } + renderValues() { + return this.renderRawOutput(); + } + toArray() { + return utils$1.erectFloat(this.renderValues(), this.output[0]); } } - 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`); + class GLTextureArray2Float extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(2)'; + } + toArray() { + return utils$1.erectArray2(this.renderValues(), this.output[0], this.output[1]); + } } - 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(); + class GLTextureArray2Float2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(2)'; + } + toArray() { + return utils$1.erect2DArray2(this.renderValues(), this.output[0], this.output[1]); } } - getMainResultNumberTexture() { - return utils.linesToString(this.getMainResultKernelNumberTexture()) + - utils.linesToString(this.getMainResultSubKernelNumberTexture()); + class GLTextureArray2Float3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(2)'; + } + toArray() { + return utils$1.erect3DArray2(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } } - getMainResultArray2Texture() { - return utils.linesToString(this.getMainResultKernelArray2Texture()) + - utils.linesToString(this.getMainResultSubKernelArray2Texture()); + class GLTextureArray3Float extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(3)'; + } + toArray() { + return utils$1.erectArray3(this.renderValues(), this.output[0]); + } } - getMainResultArray3Texture() { - return utils.linesToString(this.getMainResultKernelArray3Texture()) + - utils.linesToString(this.getMainResultSubKernelArray3Texture()); + class GLTextureArray3Float2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(3)'; + } + toArray() { + return utils$1.erect2DArray3(this.renderValues(), this.output[0], this.output[1]); + } } - getMainResultArray4Texture() { - return utils.linesToString(this.getMainResultKernelArray4Texture()) + - utils.linesToString(this.getMainResultSubKernelArray4Texture()); + class GLTextureArray3Float3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(3)'; + } + toArray() { + return utils$1.erect3DArray3(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } } - getFloatTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp float;\n'; - case 'performance': - return 'precision highp float;\n'; - case 'balanced': - default: - return 'precision mediump float;\n'; + class GLTextureArray4Float extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return utils$1.erectArray4(this.renderValues(), this.output[0]); } } - getIntTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp int;\n'; - case 'performance': - return 'precision highp int;\n'; - case 'balanced': - default: - return 'precision mediump int;\n'; + class GLTextureArray4Float2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return utils$1.erect2DArray4(this.renderValues(), this.output[0], this.output[1]); } } - getSampler2DTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp sampler2D;\n'; - case 'performance': - return 'precision highp sampler2D;\n'; - case 'balanced': - default: - return 'precision mediump sampler2D;\n'; + class GLTextureArray4Float3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return utils$1.erect3DArray4(this.renderValues(), this.output[0], this.output[1], this.output[2]); } } - getSampler2DArrayTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp sampler2DArray;\n'; - case 'performance': - return 'precision highp sampler2DArray;\n'; - case 'balanced': - default: - return 'precision mediump sampler2DArray;\n'; + class GLTextureFloat2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(1)'; + } + toArray() { + return utils$1.erect2DFloat(this.renderValues(), this.output[0], this.output[1]); } } - renderTexture() { - return new this.TextureConstructor({ - texture: this.outputTexture, - size: this.texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }); - } - 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; + class GLTextureFloat3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(1)'; + } + toArray() { + return utils$1.erect3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } } - readPackedPixelsToFloat32Array() { - return new Float32Array(this.readPackedPixelsToUint8Array().buffer); + class GLTextureMemoryOptimized extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'MemoryOptimizedNumberTexture'; + } + toArray() { + return utils$1.erectMemoryOptimizedFloat(this.renderValues(), this.output[0]); + } } - 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; + class GLTextureMemoryOptimized2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'MemoryOptimizedNumberTexture'; + } + toArray() { + return utils$1.erectMemoryOptimized2DFloat(this.renderValues(), this.output[0], this.output[1]); + } } - readMemoryOptimizedFloatPixelsToFloat32Array() { - 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; + class GLTextureMemoryOptimized3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'MemoryOptimizedNumberTexture'; + } + toArray() { + return utils$1.erectMemoryOptimized3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } } - 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); + class GLTextureUnsigned extends Texture { + constructor(settings) { + super(settings); + this.type = 'NumberTexture'; + } + renderRawOutput() { + const { context: gl } = this; + const framebuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, 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() { + return new Float32Array(this.renderRawOutput().buffer); + } + toArray() { + return utils$1.erectPackedFloat(this.renderValues(), this.output[0]); + } } - renderKernelsToArrays() { - const result = { - result: this.renderOutput(), - }; - for (let i = 0; i < this.subKernels.length; i++) { - result[this.subKernels[i].property] = new this.TextureConstructor({ - texture: this.subKernelOutputTextures[i], - size: this.texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }).toArray(); + class GLTextureUnsigned2D extends GLTextureUnsigned { + constructor(settings) { + super(settings); + this.type = 'NumberTexture'; + } + toArray() { + return utils$1.erect2DPackedFloat(this.renderValues(), this.output[0], this.output[1]); } - return result; } - renderKernelsToTextures() { - const result = { - result: this.renderOutput(), - }; - for (let i = 0; i < this.subKernels.length; i++) { - result[this.subKernels[i].property] = new this.TextureConstructor({ - texture: this.subKernelOutputTextures[i], - size: this.texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }); + class GLTextureUnsigned3D extends GLTextureUnsigned { + constructor(settings) { + super(settings); + this.type = 'NumberTexture'; + } + toArray() { + return utils$1.erect3DPackedFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); } - return result; } - setOutput(output) { - super.setOutput(output); - if (this.program) { - this.threadDim = [this.output[0], this.output[1] || 1, this.output[2] || 1]; - this.texSize = utils.getKernelTextureSize({ - optimizeFloatMemory: this.optimizeFloatMemory, - precision: this.precision, - }, this.output); - const { context: gl } = this; - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - this.updateMaxTexSize(); - this.framebuffer.width = this.texSize[0]; - this.framebuffer.height = this.texSize[1]; - this.context.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); - this.canvas.width = this.maxTexSize[0]; - this.canvas.height = this.maxTexSize[1]; - this._setupOutputTexture(); - if (this.subKernels && this.subKernels.length > 0) { - this._setupSubOutputTextures(); - } + class GLTextureGraphical extends GLTextureUnsigned { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return this.renderValues(); } - return this; - } - renderValues() { - return this.formatValues( - this.transferValues(), - this.output[0], - this.output[1], - this.output[2] - ); } -} - -const renderStrategy = Object.freeze({ - PackedPixelToUint8Array: Symbol('PackedPixelToUint8Array'), - PackedPixelToFloat: Symbol('PackedPixelToFloat'), - PackedPixelTo2DFloat: Symbol('PackedPixelTo2DFloat'), - PackedPixelTo3DFloat: Symbol('PackedPixelTo3DFloat'), - PackedTexture: Symbol('PackedTexture'), - FloatPixelToFloat32Array: Symbol('FloatPixelToFloat32Array'), - FloatPixelToFloat: Symbol('FloatPixelToFloat'), - FloatPixelTo2DFloat: Symbol('FloatPixelTo2DFloat'), - FloatPixelTo3DFloat: Symbol('FloatPixelTo3DFloat'), - FloatPixelToArray2: Symbol('FloatPixelToArray2'), - FloatPixelTo2DArray2: Symbol('FloatPixelTo2DArray2'), - FloatPixelTo3DArray2: Symbol('FloatPixelTo3DArray2'), - FloatPixelToArray3: Symbol('FloatPixelToArray3'), - FloatPixelTo2DArray3: Symbol('FloatPixelTo2DArray3'), - FloatPixelTo3DArray3: Symbol('FloatPixelTo3DArray3'), - FloatPixelToArray4: Symbol('FloatPixelToArray4'), - FloatPixelTo2DArray4: Symbol('FloatPixelTo2DArray4'), - FloatPixelTo3DArray4: Symbol('FloatPixelTo3DArray4'), - FloatTexture: Symbol('FloatTexture'), - MemoryOptimizedFloatPixelToMemoryOptimizedFloat: Symbol('MemoryOptimizedFloatPixelToFloat'), - MemoryOptimizedFloatPixelToMemoryOptimized2DFloat: Symbol('MemoryOptimizedFloatPixelTo2DFloat'), - MemoryOptimizedFloatPixelToMemoryOptimized3DFloat: Symbol('MemoryOptimizedFloatPixelTo3DFloat'), -}); - -const typeMap = { - int: 'Integer', - float: 'Number', - vec2: 'Array(2)', - vec3: 'Array(3)', - vec4: 'Array(4)', -}; -module.exports = { - GLKernel, - renderStrategy -}; -},{"../../texture":110,"../../utils":111,"../kernel":34,"./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":28,"./texture/memory-optimized-2d":26,"./texture/memory-optimized-3d":27,"./texture/unsigned":31,"./texture/unsigned-2d":29,"./texture/unsigned-3d":30}],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":111,"./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":111,"./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":111,"./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":111,"./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":111,"./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":111,"./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":111,"./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":111,"./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":111,"./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":111,"./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":111,"./float":24}],24:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { Texture } = require('../../../texture'); - -class GLTextureFloat extends Texture { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(1)'; - } - renderRawOutput() { - const { context: gl } = this; - const framebuffer = gl.createFramebuffer(); - gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); - gl.framebufferTexture2D( - gl.FRAMEBUFFER, - gl.COLOR_ATTACHMENT0, - gl.TEXTURE_2D, - this.texture, - 0 - ); - const result = new Float32Array(this.size[0] * this.size[1] * 4); - gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.FLOAT, result); - return result; - } - renderValues() { - return this.renderRawOutput(); - } - toArray() { - return utils.erectFloat(this.renderValues(), this.output[0]); - } -} - -module.exports = { - GLTextureFloat -}; -},{"../../../texture":110,"../../../utils":111}],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":31}],26:[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":111,"./float":24}],27:[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":111,"./float":24}],28:[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":111,"./float":24}],29:[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":111,"./unsigned":31}],30:[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":111,"./unsigned":31}],31:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { Texture } = require('../../../texture'); - -class GLTextureUnsigned extends Texture { - constructor(settings) { - super(settings); - this.type = 'NumberTexture'; - } - renderRawOutput() { - const { context: gl } = this; - const framebuffer = gl.createFramebuffer(); - gl.bindFramebuffer(gl.FRAMEBUFFER, 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() { - return new Float32Array(this.renderRawOutput().buffer); - } - toArray() { - return utils.erectPackedFloat(this.renderValues(), this.output[0]); - } -} - -module.exports = { - GLTextureUnsigned -}; -},{"../../../texture":110,"../../../utils":111}],32:[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'), - }; - features = this.getFeatures(); - } catch (e) { - console.warn(e); - } - } - - static isContextMatch(context) { - try { - return context.getParameter(context.RENDERER) === 'ANGLE'; - } catch (e) { - return false; - } - } - - static getFeatures() { - const isDrawBuffers = this.getIsDrawBuffers(); - return Object.freeze({ - isFloatRead: this.getIsFloatRead(), - isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), - isTextureFloat: this.getIsTextureFloat(), - isDrawBuffers, - kernelMap: isDrawBuffers, - channelCount: this.getChannelCount(), - maxTextureSize: this.getMaxTextureSize(), - }); - } - - 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() { - const context = getContext(2, 2, { - preserveDrawingBuffer: true - }); - return context; - } - - 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]); - } - } -} - -module.exports = { - HeadlessGLKernel -}; -},{"../gl/kernel-string":11,"../web-gl/kernel":67,"gl":1}],33:[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 (!tactic) { - throw new Error('tactic 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.id = `${this.origin}_${name}`; - 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; - } - - 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 -}; -},{}],34:[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'); - } + class GLKernel extends Kernel { + static get mode() { + return 'gpu'; } - 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 = 'balanced'; - - this.plugins = null; - - this.returnType = null; - this.leadingReturnStatement = null; - this.followingReturnStatement = null; - this.optimizeFloatMemory = null; - this.strictIntegers = false; - this.fixIntegerDivisionAccuracy = null; - this.warnVarUsage = true; - } - - 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; + 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 get testCanvas() { + throw new Error(`"testCanvas" not defined on ${ this.name }`); + } + static get testContext() { + throw new Error(`"testContext" not defined on ${ this.name }`); + } + static get features() { + throw new Error(`"features" not defined on ${ this.name }`); + } + static setupFeatureChecks() { + throw new Error(`"setupFeatureChecks" not defined on ${ this.name }`); + } + setFixIntegerDivisionAccuracy(fix) { + this.fixIntegerDivisionAccuracy = fix; + return this; + } + setPrecision(flag) { + this.precision = flag; + return this; + } + setFloatTextures(flag) { + utils$1.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; } - break; - case 'functions': - if (typeof settings.functions[0] === 'function') { - this.functions = settings.functions.map(source => utils.functionToIFunction(source)); + 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; } - break; - case 'graphical': - if (settings[p] && !settings.hasOwnProperty('precision')) { - this.precision = 'unsigned'; + } + else if (state === 'DECLARE_VARIABLE') { + if (argumentName === '') { + if (char === ' ') { + i++; + continue; + } + if (!isStartingVariableName.test(char)) { + throw new Error('variable name is not expected string'); + } } - this[p] = settings[p]; - continue; + argumentName += char; + if (!isVariableChar.test(nextChar)) { + states.pop(); + argumentNames.push(argumentName); + argumentTypes.push(typeMap$1[argumentType]); + } + } + i++; + } + if (states.length > 0) { + throw new Error('GLSL function was not parsable'); } - this[p] = settings[p]; + return { + argumentNames, + argumentTypes, + }; } - - 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 }`); - } - - 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 - }); - } + static nativeFunctionReturnType(source) { + return typeMap$1[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); } - } else { - for (let i = 0; i < this.argumentTypes.length; i++) { - this.kernelArguments.push({ - type: this.argumentTypes[i] + 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$1.splitArray(result, lastKernel.output[0]); + } else if (lastKernel.output.length === 3) { + const cube = utils$1.splitArray(result, lastKernel.output[0] * lastKernel.output[1]); + return cube.map(function(x) { + return utils$1.splitArray(x, lastKernel.output[0]); }); } } - - 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 - }); + 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.renderStrategy = null; + this.compiledFragmentShader = null; + this.compiledVertexShader = 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; + this.renderStrategy = renderStrategy.PackedPixelTo3DFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureUnsigned2D; + this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; + return null; + } else { + this.TextureConstructor = GLTextureUnsigned; + this.renderStrategy = renderStrategy.PackedPixelToFloat; + return null; + } + break; + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + return this.requestFallback(args); + } } else { - this.kernelConstants.push({ - name, - type: this.constantTypes[name] - }); + 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.renderStrategy = renderStrategy.PackedPixelTo3DFloat; + this.formatValues = utils$1.erect3DPackedFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureUnsigned2D; + this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; + this.formatValues = utils$1.erect2DPackedFloat; + return null; + } else { + this.TextureConstructor = GLTextureUnsigned; + this.renderStrategy = renderStrategy.PackedPixelToFloat; + this.formatValues = utils$1.erectPackedFloat; + return null; + } + break; + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + return this.requestFallback(args); + } } - this.constantBitRatios[name] = this.getBitRatio(this.constants[name]); - } - } - } - - setOptimizeFloatMemory(flag) { - this.optimizeFloatMemory = flag; - return this; - } - - setOutput(output) { - if (output.hasOwnProperty('x')) { - if (output.hasOwnProperty('y')) { - if (output.hasOwnProperty('z')) { - this.output = [output.x, output.y, output.z]; + } else if (this.precision === 'single') { + this.renderRawOutput = this.readFloatPixelsToFloat32Array; + this.transferValues = this.readFloatPixelsToFloat32Array; + if (this.pipeline) { + this.renderStrategy = renderStrategy.FloatTexture; + 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; + } + } + break; + 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; + } + break; + 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; + } + break; + 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.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized3DFloat; + this.formatValues = utils$1.erectMemoryOptimized3DFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureMemoryOptimized2D; + this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized2DFloat; + this.formatValues = utils$1.erectMemoryOptimized2DFloat; + return null; + } else { + this.TextureConstructor = GLTextureMemoryOptimized; + this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimizedFloat; + this.formatValues = utils$1.erectMemoryOptimizedFloat; + return null; + } + break; + case 'Array(2)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray2Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; + this.formatValues = utils$1.erect3DArray2; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray2Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; + this.formatValues = utils$1.erect2DArray2; + return null; + } else { + this.TextureConstructor = GLTextureArray2Float; + this.renderStrategy = renderStrategy.FloatPixelToArray2; + this.formatValues = utils$1.erectArray2; + return null; + } + break; + case 'Array(3)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray3Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; + this.formatValues = utils$1.erect3DArray3; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray3Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; + this.formatValues = utils$1.erect2DArray3; + return null; + } else { + this.TextureConstructor = GLTextureArray3Float; + this.renderStrategy = renderStrategy.FloatPixelToArray3; + this.formatValues = utils$1.erectArray3; + return null; + } + break; + case 'Array(4)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray4Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; + this.formatValues = utils$1.erect3DArray4; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray4Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; + this.formatValues = utils$1.erect2DArray4; + return null; + } else { + this.TextureConstructor = GLTextureArray4Float; + this.renderStrategy = renderStrategy.FloatPixelToArray4; + this.formatValues = utils$1.erectArray4; + return null; + } + } } else { - this.output = [output.x, output.y]; + switch (this.returnType) { + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureFloat3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DFloat; + this.formatValues = utils$1.erect3DFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureFloat2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DFloat; + this.formatValues = utils$1.erect2DFloat; + return null; + } else { + this.TextureConstructor = GLTextureFloat; + this.renderStrategy = renderStrategy.FloatPixelToFloat; + this.formatValues = utils$1.erectFloat; + return null; + } + break; + case 'Array(2)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray2Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; + this.formatValues = utils$1.erect3DArray2; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray2Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; + this.formatValues = utils$1.erect2DArray2; + return null; + } else { + this.TextureConstructor = GLTextureArray2Float; + this.renderStrategy = renderStrategy.FloatPixelToArray2; + this.formatValues = utils$1.erectArray2; + return null; + } + break; + case 'Array(3)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray3Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; + this.formatValues = utils$1.erect3DArray3; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray3Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; + this.formatValues = utils$1.erect2DArray3; + return null; + } else { + this.TextureConstructor = GLTextureArray3Float; + this.renderStrategy = renderStrategy.FloatPixelToArray3; + this.formatValues = utils$1.erectArray3; + return null; + } + break; + case 'Array(4)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray4Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; + this.formatValues = utils$1.erect3DArray4; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray4Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; + this.formatValues = utils$1.erect2DArray4; + return null; + } else { + this.TextureConstructor = GLTextureArray4Float; + this.renderStrategy = renderStrategy.FloatPixelToArray4; + this.formatValues = utils$1.erectArray4; + return null; + } + } } } else { - this.output = [output.x]; + throw new Error(`unhandled precision of "${this.precision}"`); } - } else { - this.output = output; + throw new Error(`unhandled return type "${this.returnType}"`); } - 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) { - if (typeof functions[0] === 'function') { - this.functions = functions.map(source => utils.functionToIFunction(source)); - } else { - this.functions = functions; + getKernelString() { + throw new Error(`abstract method call`); } - return this; - } - - setNativeFunctions(nativeFunctions) { - this.nativeFunctions = nativeFunctions; - return this; - } - - setInjectedNative(injectedNative) { - this.injectedNative = injectedNative; - return this; - } - - setPipeline(flag) { - this.pipeline = flag; - return this; - } - - setPrecision(flag) { - this.precision = 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) { - this.warnVarUsage = flag; - 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) { - const argumentIndex = this.argumentNames.indexOf(p); - if (argumentIndex === -1) throw new Error(`unable to find argument ${ p }`); - this.argumentTypes[argumentIndex] = argumentTypes[p]; + 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 }`); } } - return this; - } - - setTactic(tactic) { - this.tactic = tactic; - return this; - } - - requestFallback(args) { - if (!this.onRequestFallback) { - throw new Error(`"onRequestFallback" not defined on ${ this.constructor.name }`); + getMainResultKernelNumberTexture() { + throw new Error(`abstract method call`); } - 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); + getMainResultSubKernelNumberTexture() { + throw new Error(`abstract method call`); } - 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() { - 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`); - } + getMainResultKernelArray2Texture() { + throw new Error(`abstract method call`); } - } - - toJSON() { - const settings = { - output: this.output, - threadDim: this.threadDim, - 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, - }; - return { - settings - }; - } -} - -module.exports = { - Kernel -}; -},{"../input":107,"../utils":111}],35:[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; - -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; + getMainResultSubKernelArray2Texture() { + throw new Error(`abstract method call`); } - } - 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; + getMainResultKernelArray3Texture() { + throw new Error(`abstract method call`); } - } - 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; + getMainResultSubKernelArray3Texture() { + throw new Error(`abstract method call`); } - } - 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; + getMainResultKernelArray4Texture() { + throw new Error(`abstract method call`); } - 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; + getMainResultSubKernelArray4Texture() { + throw new Error(`abstract method call`); } - maxBytes *= 2; - } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; + getMainResultGraphical() { + throw new Error(`abstract method call`); } - 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); + getMainResultMemoryOptimizedFloats() { + throw new Error(`abstract method call`); } - } -} - -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); -} - -__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 -}; -},{}],36:[function(require,module,exports){ -const { utils } = require('../../utils'); -const { FunctionNode } = require('../function-node'); -const jsMathPrefix = 'Math.'; -const localPrefix = 'this.'; - -class WebGLFunctionNode extends FunctionNode { - constructor(source, settings) { - super(source, settings); - if (settings && settings.hasOwnProperty('fixIntegerDivisionAccuracy')) { - this.fixIntegerDivisionAccuracy = settings.fixIntegerDivisionAccuracy; + getMainResultPackedPixels() { + throw new Error(`abstract method call`); } - } - - astFunction(ast, retArr) { - if (this.isRootKernel) { - retArr.push('void'); - } else { - let lastReturn = null; - if (!this.returnType) { - const lastReturn = this.findLastReturn(); - if (lastReturn) { - this.returnType = this.getType(ast.body); - if (this.returnType === 'LiteralInteger') { - this.returnType = 'Number'; - } + getMainResultString() { + if (this.graphical) { + return this.getMainResultGraphical(); + } else if (this.precision === 'single') { + if (this.optimizeFloatMemory) { + return this.getMainResultMemoryOptimizedFloats(); } - } - - const { returnType } = this; - if (!returnType) { - retArr.push('void'); + return this.getMainResultTexture(); } else { - const type = typeMap[returnType]; - if (!type) { - throw new Error(`unknown type ${returnType}`); - } - retArr.push(type); + return this.getMainResultPackedPixels(); } } - 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); - } - - if (type === 'sampler2D' || type === 'sampler2DArray') { - retArr.push(`${type} user_${argumentName},ivec2 user_${argumentName}Size,ivec3 user_${argumentName}Dim`); - } else { - retArr.push(`${type} user_${argumentName}`); - } + getMainResultNumberTexture() { + return utils$1.linesToString(this.getMainResultKernelNumberTexture()) + + utils$1.linesToString(this.getMainResultSubKernelNumberTexture()); + } + getMainResultArray2Texture() { + return utils$1.linesToString(this.getMainResultKernelArray2Texture()) + + utils$1.linesToString(this.getMainResultSubKernelArray2Texture()); + } + getMainResultArray3Texture() { + return utils$1.linesToString(this.getMainResultKernelArray3Texture()) + + utils$1.linesToString(this.getMainResultSubKernelArray3Texture()); + } + getMainResultArray4Texture() { + return utils$1.linesToString(this.getMainResultKernelArray4Texture()) + + utils$1.linesToString(this.getMainResultSubKernelArray4Texture()); + } + getFloatTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp float;\n'; + case 'performance': + return 'precision highp float;\n'; + case 'balanced': + default: + return 'precision mediump float;\n'; } } - - retArr.push(') {\n'); - - for (let i = 0; i < ast.body.body.length; ++i) { - this.astGeneric(ast.body.body[i], retArr); - retArr.push('\n'); + getIntTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp int;\n'; + case 'performance': + return 'precision highp int;\n'; + case 'balanced': + default: + return 'precision mediump int;\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; + getSampler2DTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp sampler2D;\n'; + case 'performance': + return 'precision highp sampler2D;\n'; + case 'balanced': + default: + return 'precision mediump sampler2D;\n'; } } - - 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 'Input': - this.astGeneric(ast.argument, result); - break; - default: - throw this.astErrorOutput(`unhandled return type ${this.returnType}`, ast); + getSampler2DArrayTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp sampler2DArray;\n'; + case 'performance': + return 'precision highp sampler2DArray;\n'; + case 'balanced': + default: + return 'precision mediump sampler2DArray;\n'; + } } - - 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('') };`); + renderTexture() { + return new this.TextureConstructor({ + texture: this.outputTexture, + size: this.texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }); } - return retArr; - } - - astLiteral(ast, retArr) { - if (isNaN(ast.value)) { - throw this.astErrorOutput( - 'Non-numeric literal not supported : ' + ast.value, - ast - ); + 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; } - - const key = `${ast.start},${ast.end}`; - if (Number.isInteger(ast.value)) { - if (this.isState('in-for-loop-init') || 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`); + 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; + } + readMemoryOptimizedFloatPixelsToFloat32Array() { + 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$1.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] = new this.TextureConstructor({ + texture: this.subKernelOutputTextures[i], + size: this.texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }).toArray(); } - } 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 result; + } + renderKernelsToTextures() { + const result = { + result: this.renderOutput(), + }; + for (let i = 0; i < this.subKernels.length; i++) { + result[this.subKernels[i].property] = new this.TextureConstructor({ + texture: this.subKernelOutputTextures[i], + size: this.texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }); + } + return result; + } + setOutput(output) { + super.setOutput(output); + if (this.program) { + this.threadDim = [this.output[0], this.output[1] || 1, this.output[2] || 1]; + this.texSize = utils$1.getKernelTextureSize({ + optimizeFloatMemory: this.optimizeFloatMemory, + precision: this.precision, + }, this.output); + const { context: gl } = this; + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + this.updateMaxTexSize(); + this.framebuffer.width = this.texSize[0]; + this.framebuffer.height = this.texSize[1]; + this.context.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); + this.canvas.width = this.maxTexSize[0]; + this.canvas.height = this.maxTexSize[1]; + this._setupOutputTexture(); + if (this.subKernels && this.subKernels.length > 0) { + this._setupSubOutputTextures(); + } + } + return this; + } + renderValues() { + return this.formatValues( + this.transferValues(), + this.output[0], + this.output[1], + this.output[2] + ); } - return retArr; } + const renderStrategy = Object.freeze({ + PackedPixelToUint8Array: Symbol('PackedPixelToUint8Array'), + PackedPixelToFloat: Symbol('PackedPixelToFloat'), + PackedPixelTo2DFloat: Symbol('PackedPixelTo2DFloat'), + PackedPixelTo3DFloat: Symbol('PackedPixelTo3DFloat'), + PackedTexture: Symbol('PackedTexture'), + FloatPixelToFloat32Array: Symbol('FloatPixelToFloat32Array'), + FloatPixelToFloat: Symbol('FloatPixelToFloat'), + FloatPixelTo2DFloat: Symbol('FloatPixelTo2DFloat'), + FloatPixelTo3DFloat: Symbol('FloatPixelTo3DFloat'), + FloatPixelToArray2: Symbol('FloatPixelToArray2'), + FloatPixelTo2DArray2: Symbol('FloatPixelTo2DArray2'), + FloatPixelTo3DArray2: Symbol('FloatPixelTo3DArray2'), + FloatPixelToArray3: Symbol('FloatPixelToArray3'), + FloatPixelTo2DArray3: Symbol('FloatPixelTo2DArray3'), + FloatPixelTo3DArray3: Symbol('FloatPixelTo3DArray3'), + FloatPixelToArray4: Symbol('FloatPixelToArray4'), + FloatPixelTo2DArray4: Symbol('FloatPixelTo2DArray4'), + FloatPixelTo3DArray4: Symbol('FloatPixelTo3DArray4'), + FloatTexture: Symbol('FloatTexture'), + MemoryOptimizedFloatPixelToMemoryOptimizedFloat: Symbol('MemoryOptimizedFloatPixelToFloat'), + MemoryOptimizedFloatPixelToMemoryOptimized2DFloat: Symbol('MemoryOptimizedFloatPixelTo2DFloat'), + MemoryOptimizedFloatPixelToMemoryOptimized3DFloat: Symbol('MemoryOptimizedFloatPixelTo3DFloat'), + }); + const typeMap$1 = { + int: 'Integer', + float: 'Number', + vec2: 'Array(2)', + vec3: 'Array(3)', + vec4: 'Array(4)', + }; - astBinaryExpression(ast, retArr) { - if (this.checkAndUpconvertOperator(ast, retArr)) { - return retArr; + class WebGLFunctionNode extends FunctionNode { + constructor(source, settings) { + super(source, settings); + if (settings && settings.hasOwnProperty('fixIntegerDivisionAccuracy')) { + this.fixIntegerDivisionAccuracy = settings.fixIntegerDivisionAccuracy; + } } - - if (this.fixIntegerDivisionAccuracy && ast.operator === '/') { - retArr.push('div_with_int_check('); - 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); + 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$2[returnType]; + if (!type) { + throw new Error(`unknown type ${returnType}`); + } + retArr.push(type); + } } - 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(' '); + 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$2[argumentType]; + if (!type) { + throw this.astErrorOutput('Unexpected expression', ast); + } + retArr.push(type); + retArr.push(' '); + retArr.push('user_'); + retArr.push(argumentName); + } } - this.popState('building-float'); - retArr.push(')'); + 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; } - - 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': + 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 '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 = `${ast.start},${ast.end}`; + if (Number.isInteger(ast.value)) { + if (this.isState('in-for-loop-init') || 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('div_with_int_check('); this.pushState('building-float'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.astGeneric(ast.right, retArr); + 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'); - break; - case 'LiteralInteger & LiteralInteger': - if (this.isState('casting-to-integer') || this.isState('building-integer')) { + 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'); - } else { + break; + case 'Number & Float': + case 'Float & Number': + case 'Float & Float': + case 'Number & Number': this.pushState('building-float'); - this.castLiteralToFloat(ast.left, retArr); + this.astGeneric(ast.left, retArr); retArr.push(operatorMap[ast.operator] || ast.operator); - this.castLiteralToFloat(ast.right, retArr); + this.astGeneric(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); + 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; } - } - 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('')); + 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 { - throw this.astErrorOutput(`Unhandled binary expression with literal`, ast); + retArr.push('int('); + this.astGeneric(ast.right, retArr); + retArr.push(')'); } - } 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': - if (this.isState('in-for-loop-test')) { + this.popState('casting-to-integer'); + this.popState('building-integer'); + break; + case 'Integer & LiteralInteger': this.pushState('building-integer'); - retArr.push('int('); this.astGeneric(ast.left, retArr); - retArr.push(')'); retArr.push(operatorMap[ast.operator] || ast.operator); this.castLiteralToInteger(ast.right, retArr); this.popState('building-integer'); - } else { + break; + case 'Number & Integer': this.pushState('building-float'); this.astGeneric(ast.left, retArr); retArr.push(operatorMap[ast.operator] || ast.operator); - this.castLiteralToFloat(ast.right, retArr); + this.castValueToFloat(ast.right, retArr); this.popState('building-float'); - } - break; - case 'LiteralInteger & Float': - case 'LiteralInteger & Number': - if (this.isState('in-for-loop-test') || this.isState('in-for-loop-init') || this.isState('casting-to-integer')) { + break; + case 'Float & LiteralInteger': + case 'Number & LiteralInteger': + if (this.isState('in-for-loop-test')) { + this.pushState('building-integer'); + retArr.push('int('); + this.astGeneric(ast.left, retArr); + retArr.push(')'); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToInteger(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.castLiteralToFloat(ast.right, retArr); + this.popState('building-float'); + } + break; + case 'LiteralInteger & Float': + case 'LiteralInteger & Number': + if (this.isState('in-for-loop-test') || this.isState('in-for-loop-init') || 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.castValueToInteger(ast.right, retArr); + this.astGeneric(ast.right, retArr); this.popState('building-integer'); - } else { - this.pushState('building-float'); + break; + case 'Boolean & Boolean': + this.pushState('building-boolean'); 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-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; - 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); + break; + default: + throw this.astErrorOutput(`Unhandled binary expression between ${key}`, ast); + } + retArr.push(')'); + return retArr; } - retArr.push(')'); - - return retArr; - } - - checkAndUpconvertOperator(ast, retArr) { - const bitwiseResult = this.checkAndUpconvertBitwiseOperators(ast, retArr); - if (bitwiseResult) { - return bitwiseResult; - } - const upconvertableOperators = { - '%': 'mod', - '**': '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); + checkAndUpconvertOperator(ast, retArr) { + const bitwiseResult = this.checkAndUpconvertBitwiseOperators(ast, retArr); + if (bitwiseResult) { + return bitwiseResult; + } + const upconvertableOperators = { + '%': 'mod', + '**': '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; } - 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); + 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; } - 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); + 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; } - 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); + castLiteralToInteger(ast, retArr) { + this.pushState('casting-to-integer'); + this.astGeneric(ast, retArr); + this.popState('casting-to-integer'); + return retArr; } - - const type = this.getType(idtNode); - - if (idtNode.name === 'Infinity') { - retArr.push('3.402823466e+38'); - } else if (type === 'Boolean') { - if (this.argumentNames.indexOf(idtNode.name) > -1) { - retArr.push(`bool(user_${idtNode.name})`); + 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); + if (idtNode.name === 'Infinity') { + retArr.push('3.402823466e+38'); + } else if (type === 'Boolean') { + if (this.argumentNames.indexOf(idtNode.name) > -1) { + retArr.push(`bool(user_${idtNode.name})`); + } else { + retArr.push(`user_${idtNode.name}`); + } } else { retArr.push(`user_${idtNode.name}`); } - } else { - retArr.push(`user_${idtNode.name}`); + return retArr; } - - 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); - const { declarations } = forNode.init; - for (let i = 0; i < declarations.length; i++) { - if (declarations[i].init && declarations[i].init.type !== 'Literal') { - isSafe = false; + 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); + const { declarations } = forNode.init; + for (let i = 0; i < declarations.length; i++) { + if (declarations[i].init && declarations[i].init.type !== 'Literal') { + isSafe = false; + } + } + if (isSafe) { + 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.pushState('in-for-loop-test'); + this.astGeneric(forNode.test, testArr); + this.popState('in-for-loop-test'); + } 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) { - for (let i = 0; i < initArr.length; i++) { - if (initArr[i].includes && initArr[i].includes(',')) { - isSafe = false; - } + 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 (int ${iVariableName}=0;${iVariableName} 0) { + retArr.push(`if (!${testArr.join('')}) break;\n`); } + retArr.push(bodyArr.join('')); + retArr.push(`\n${updateArr.join('')};`); + retArr.push('}\n'); } - this.popState('in-for-loop-init'); - } else { - isSafe = false; - } - - if (forNode.test) { - this.pushState('in-for-loop-test'); - this.astGeneric(forNode.test, testArr); - this.popState('in-for-loop-test'); - } 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); + return retArr; } - - 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'); + 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) { - retArr.push(`if (!${testArr.join('')}) break;\n`); - } - retArr.push(bodyArr.join('')); - retArr.push(`\n${updateArr.join('')};`); + retArr.push('if (!'); + this.astGeneric(whileNode.test, retArr); + retArr.push(') break;\n'); + this.astGeneric(whileNode.body, retArr); retArr.push('}\n'); + return retArr; } - 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} i + 1) { - movingDefaultToEnd = true; - this.astGeneric(cases[i].consequent, defaultResult); - continue; + if (ifNode.alternate) { + retArr.push('else '); + if (ifNode.alternate.type === 'BlockStatement') { + this.astGeneric(ifNode.alternate, retArr); } else { - retArr.push(' else {\n'); + retArr.push(' {\n'); + this.astGeneric(ifNode.alternate, retArr); + retArr.push('\n}\n'); } - } else { - if (i === 0 || !pastFirstIf) { - pastFirstIf = true; - retArr.push(`if (${varName} == `); + } + 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${ast.start}_${ast.end}`; + 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 (fallingThrough) { - retArr.push(`${varName} == `); - fallingThrough = false; + if (i === 0 || !pastFirstIf) { + pastFirstIf = true; + retArr.push(`if (${varName} == `); } else { - retArr.push(` else if (${varName} == `); + 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; + 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'); } - } 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; + if (!cases[i].consequent || cases[i].consequent.length === 0) { + fallingThrough = true; + retArr.push(' || '); + continue; } - } else { - throw new Error('unhanlded'); - } - if (!cases[i].consequent || cases[i].consequent.length === 0) { - fallingThrough = true; - retArr.push(' || '); - continue; + retArr.push(`) {\n`); } - retArr.push(`) {\n`); + this.astGeneric(cases[i].consequent, retArr); + 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; } - if (movingDefaultToEnd) { - retArr.push(' else {'); - retArr.push(defaultResult.join('')); - retArr.push('}'); + astThisExpression(tNode, retArr) { + retArr.push('this'); + return retArr; } - 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); + 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); } - } 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); + 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; - } - switch (property) { - case 'r': - retArr.push(`user_${ name }.r`); - return retArr; - case 'g': - retArr.push(`user_${ name }.g`); - return retArr; - case 'b': - retArr.push(`user_${ name }.b`); - return retArr; - case 'a': - retArr.push(`user_${ name }.a`); + 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; - } - break; - case 'this.constants.value': - if (typeof xProperty === 'undefined') { - switch (type) { - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - retArr.push(`constants_${ name }`); + } + switch (property) { + case 'r': + retArr.push(`user_${ name }.r`); + return retArr; + case 'g': + retArr.push(`user_${ name }.g`); + return retArr; + case 'b': + retArr.push(`user_${ name }.b`); + return retArr; + case 'a': + retArr.push(`user_${ name }.a`); 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 '[][]': - 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}_${name}`); - return retArr; - } - } - - const markupName = `${origin}_${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 'HTMLImage': - 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}`); + case 'this.constants.value': + if (typeof xProperty === 'undefined') { + switch (type) { + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + retArr.push(`constants_${ name }`); + return retArr; + } } - 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; - 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); - } - - if (functionName === 'atan2') { - functionName = 'atan'; - } - - 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); + 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 '[][]': + this.astArrayExpression(mNode.object, retArr); + retArr.push('['); + retArr.push(this.memberExpressionPropertyMarkup(property)); + retArr.push(']'); + return retArr; default: - this.astGeneric(argument, retArr); - break; - } + throw this.astErrorOutput('Unexpected expression', mNode); } - } 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) { + if (mNode.computed === false) { + switch (type) { 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') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast); - this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i); - retArr.push(`user_${argument.name}`); - continue; - } - break; - case 'HTMLImage': - 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); - retArr.push(`user_${argument.name},user_${argument.name}Size,user_${argument.name}Dim`); - continue; - } - break; + case 'Float': + case 'Boolean': + retArr.push(`${origin}_${name}`); + return retArr; } - throw this.astErrorOutput(`Unhandled argument combination of ${ argumentType } and ${ targetType } for argument named "${ argument.name }"`, ast); - } - } - retArr.push(')'); - - return retArr; - } - - astArrayExpression(arrNode, retArr) { - const arrLen = arrNode.elements.length; - - retArr.push('vec' + arrLen + '('); - for (let i = 0; i < arrLen; ++i) { - if (i > 0) { - retArr.push(', '); - } - const subNode = arrNode.elements[i]; - 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', - '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', - 'HTMLImage': 'sampler2D', - 'HTMLImageArray': 'sampler2DArray', -}; - -const operatorMap = { - '===': '==', - '!==': '!=' -}; - -module.exports = { - WebGLFunctionNode -}; -},{"../../utils":111,"../function-node":9}],37:[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 { WebGLKernelValueSingleArray2 } = require('./kernel-value/single-array2'); -const { WebGLKernelValueSingleArray3 } = require('./kernel-value/single-array3'); -const { WebGLKernelValueSingleArray4 } = require('./kernel-value/single-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)': false, - 'Array(3)': false, - 'Array(4)': false, - '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, - 'HTMLImage': WebGLKernelValueDynamicHTMLImage, - 'HTMLImageArray': false, - 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGLKernelValueBoolean, - 'Float': WebGLKernelValueFloat, - 'Integer': WebGLKernelValueInteger, - 'Array': WebGLKernelValueUnsignedArray, - 'Array(2)': false, - 'Array(3)': false, - 'Array(4)': false, - '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, - 'HTMLImage': WebGLKernelValueHTMLImage, - 'HTMLImageArray': false, - 'HTMLVideo': WebGLKernelValueHTMLVideo, - } - }, - single: { - dynamic: { - 'Boolean': WebGLKernelValueBoolean, - 'Integer': WebGLKernelValueInteger, - 'Float': WebGLKernelValueFloat, - 'Array': WebGLKernelValueDynamicSingleArray, - 'Array(2)': WebGLKernelValueSingleArray2, - 'Array(3)': WebGLKernelValueSingleArray3, - 'Array(4)': WebGLKernelValueSingleArray4, - '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, - 'HTMLImage': WebGLKernelValueDynamicHTMLImage, - 'HTMLImageArray': false, - 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGLKernelValueBoolean, - 'Float': WebGLKernelValueFloat, - 'Integer': WebGLKernelValueInteger, - 'Array': WebGLKernelValueSingleArray, - 'Array(2)': WebGLKernelValueSingleArray2, - 'Array(3)': WebGLKernelValueSingleArray3, - 'Array(4)': WebGLKernelValueSingleArray4, - '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, - 'HTMLImage': 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/boolean":38,"./kernel-value/dynamic-html-image":39,"./kernel-value/dynamic-html-video":40,"./kernel-value/dynamic-memory-optimized-number-texture":41,"./kernel-value/dynamic-number-texture":42,"./kernel-value/dynamic-single-array":43,"./kernel-value/dynamic-single-array1d-i":44,"./kernel-value/dynamic-single-array2d-i":45,"./kernel-value/dynamic-single-array3d-i":46,"./kernel-value/dynamic-single-input":47,"./kernel-value/dynamic-unsigned-array":48,"./kernel-value/dynamic-unsigned-input":49,"./kernel-value/float":50,"./kernel-value/html-image":51,"./kernel-value/html-video":52,"./kernel-value/integer":54,"./kernel-value/memory-optimized-number-texture":55,"./kernel-value/number-texture":56,"./kernel-value/single-array":57,"./kernel-value/single-array1d-i":58,"./kernel-value/single-array2":59,"./kernel-value/single-array2d-i":60,"./kernel-value/single-array3":61,"./kernel-value/single-array3d-i":62,"./kernel-value/single-array4":63,"./kernel-value/single-input":64,"./kernel-value/unsigned-array":65,"./kernel-value/unsigned-input":66}],38:[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":111,"./index":53}],39:[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":111,"./html-image":51}],40:[function(require,module,exports){ -const { WebGLKernelValueDynamicHTMLImage } = require('./dynamic-html-image'); - -class WebGLKernelValueDynamicHTMLVideo extends WebGLKernelValueDynamicHTMLImage {} - -module.exports = { - WebGLKernelValueDynamicHTMLVideo -}; -},{"./dynamic-html-image":39}],41:[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.checkSize(inputTexture.size[0], inputTexture.size[1]); - this.dimensions = inputTexture.dimensions; - 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":111,"./memory-optimized-number-texture":55}],42:[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":111,"./number-texture":56}],43:[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.bitRatio, this.textureSize[1] * this.bitRatio); - 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":111,"./single-array":57}],44:[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":111,"./single-array1d-i":58}],45:[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":111,"./single-array2d-i":60}],46:[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":111,"./single-array3d-i":62}],47:[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.bitRatio, this.textureSize[1] * this.bitRatio); - 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":111,"./single-input":64}],48:[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] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - 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":111,"./unsigned-array":65}],49:[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] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - 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":111,"./unsigned-input":66}],50:[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":111,"./index":53}],51:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueHTMLImage extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - const { width, height } = value; - this.checkSize(width, height); - this.dimensions = [width, height, 1]; - this.requestTexture(); - 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(); - return; - } - 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); - 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":111,"./index":53}],52:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueHTMLImage } = require('./html-image'); - -class WebGLKernelValueHTMLVideo extends WebGLKernelValueHTMLImage {} - -module.exports = { - WebGLKernelValueHTMLVideo -}; -},{"../../../utils":111,"./html-image":51}],53:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { Input } = require('../../../input'); -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; - } - - 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 width of ${width} larger than maximum size of ${maxTextureSize} for your GPU`); - } else { - throw new Error(`Argument height of ${height} larger than maximum size of ${maxTextureSize} for your GPU`); - } - } - } - - requestTexture() { - this.texture = this.onRequestTexture(); - this.setupTexture(); - } - - setupTexture() { - this.contextHandle = this.onRequestContextHandle(); - this.index = this.onRequestIndex(); - this.dimensionsId = this.id + 'Dim'; - this.sizeId = this.id + 'Size'; - } - - 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; - } - formatArrayTransfer(value, length, Type) { - if (utils.isArray(value[0]) || this.optimizeFloatMemory) { - const valuesFlat = new Float32Array(length); - utils.flattenTo(value, valuesFlat); - return valuesFlat; - } else { - switch (value.constructor) { - case Uint8ClampedArray: - case Uint8Array: - case Int8Array: - case Uint16Array: - case Int16Array: - case Float32Array: - case Int32Array: { - const valuesFlat = new(Type || value.constructor)(length); - utils.flattenTo(value, valuesFlat); - return valuesFlat; - } - default: { - const valuesFlat = new Float32Array(length); - utils.flattenTo(value, valuesFlat); - return valuesFlat; - } - } - } - } - - 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; - } - } - - getStringValueHandler() { - throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`); - } - - getVariablePrecisionString() { - switch (this.tactic) { - case 'speed': - return 'lowp'; - case 'performance': - return 'highp'; - case 'balanced': - default: - return 'mediump'; - } - } -} - -module.exports = { - WebGLKernelValue -}; -},{"../../../input":107,"../../../utils":111,"../../kernel-value":33}],54:[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":111,"./index":53}],55:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueMemoryOptimizedNumberTexture extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - const [width, height] = value.size; - this.checkSize(width, height); - this.setupTexture(); - this.dimensions = value.dimensions; - this.textureSize = value.size; - this.uploadValue = value.texture; - this.forceUploadEachRun = true; - } - - 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(); - return; - } - if (this.checkContext && inputTexture.context !== this.context) { - throw new Error(`Value ${this.name} (${this.type }) must be from same context`); - } - const { context: gl } = this; - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueMemoryOptimizedNumberTexture -}; -},{"../../../utils":111,"./index":53}],56:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueNumberTexture extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - const [width, height] = value.size; - this.checkSize(width, height); - this.setupTexture(); - const { size: textureSize, dimensions } = value; - this.bitRatio = this.getBitRatio(value); - this.dimensions = dimensions; - this.textureSize = textureSize; - this.uploadValue = value.texture; - this.forceUploadEachRun = true; - } - - 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(); - return; - } - if (this.checkContext && inputTexture.context !== this.context) { - throw new Error(`Value ${this.name} (${this.type}) must be from same context`); - } - const { context: gl } = this; - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueNumberTexture -}; -},{"../../../utils":111,"./index":53}],57:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - 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.bitRatio, this.textureSize[1] * this.bitRatio); - 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(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - 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); - 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":111,"./index":53}],58:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray1DI extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - 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.bitRatio, this.textureSize[1] * this.bitRatio); - 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(); - return; - } - const { context: gl } = this; - utils.flatten2dArrayTo(value, this.uploadValue); - 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); - 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":111,"./index":53}],59:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray2 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 = { - WebGLKernelValueSingleArray2 -}; -},{"../../../utils":111,"./index":53}],60:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray2DI extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - 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.bitRatio, this.textureSize[1] * this.bitRatio); - 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(); - return; - } - const { context: gl } = this; - utils.flatten3dArrayTo(value, this.uploadValue); - 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); - 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":111,"./index":53}],61:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray3 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 = { - WebGLKernelValueSingleArray3 -}; -},{"../../../utils":111,"./index":53}],62:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray3DI extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - 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.bitRatio, this.textureSize[1] * this.bitRatio); - 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(); - return; - } - const { context: gl } = this; - utils.flatten4dArrayTo(value, this.uploadValue); - 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); - 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":111,"./index":53}],63:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray4 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 = { - WebGLKernelValueSingleArray4 -}; -},{"../../../utils":111,"./index":53}],64:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleInput extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - 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.bitRatio, this.textureSize[1] * this.bitRatio); - 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(); - return; - } - const { context: gl } = this; - utils.flattenTo(input.value, this.uploadValue); - 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); - 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":111,"./index":53}],65:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueUnsignedArray extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - 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] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - 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(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.preUploadValue); - 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); - 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":111,"./index":53}],66:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueUnsignedInput extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - 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] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - 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(); - return; - } - const { context: gl } = this; - utils.flattenTo(input.value, this.preUploadValue); - 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); - 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":111,"./index":53}],67:[function(require,module,exports){ -const { GLKernel } = require('../gl/kernel'); -const { FunctionBuilder } = require('../function-builder'); -const { WebGLFunctionNode } = require('./function-node'); -const { utils } = require('../../utils'); -const triangleNoise = require('../../plugins/triangle-noise'); -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 = [triangleNoise]; -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 getFeatures() { - const isDrawBuffers = this.getIsDrawBuffers(); - return Object.freeze({ - isFloatRead: this.getIsFloatRead(), - isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), - isTextureFloat: this.getIsTextureFloat(), - isDrawBuffers, - kernelMap: isDrawBuffers, - channelCount: this.getChannelCount(), - maxTextureSize: this.getMaxTextureSize(), - }); - } - - 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.subKernelOutputTextures = null; - this.kernelArguments = null; - this.argumentTextureCount = 0; - this.constantTextureCount = 0; - this.compiledFragmentShader = null; - this.compiledVertexShader = null; - this.fragShader = null; - this.vertShader = null; - this.drawBuffersMap = null; - this.outputTexture = null; - - this.maxTexSize = null; - this.switchingKernels = false; - this.onRequestSwitchKernel = 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); - 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'); - } - - 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]; - } - } - - _oldtranslateSource() { - const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { - fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy - }); - - const translatedSource = functionBuilder.getPrototypeString('kernel'); - - if (!this.returnType) { - this.returnType = functionBuilder.getKernelResultType(); - } - - let requiredChannels = 0; - const returnTypes = functionBuilder.getReturnTypes(); - for (let i = 0; i < returnTypes.length; i++) { - switch (returnTypes[i]) { - case 'Float': - case 'Number': - case 'Integer': - requiredChannels++; - break; - case 'Array(2)': - requiredChannels += 2; - break; - case 'Array(3)': - requiredChannels += 3; - break; - case 'Array(4)': - requiredChannels += 4; - break; - } - } - - if (features && requiredChannels > features.channelCount) { - throw new Error('Too many channels!'); - } - - return this.translatedSource = translatedSource; - } - - 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; - 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: () => { - return this.context.createTexture(); - }, - onRequestIndex: () => { - return textureIndexes++; - }, - onUpdateValueMismatch: () => { - this.switchingKernels = true; - }, - onRequestContextHandle: () => { - return gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount++; - } - }); - this.kernelArguments.push(kernelArgument); - this.argumentSizes.push(kernelArgument.textureSize); - this.argumentBitRatios[index] = kernelArgument.bitRatio; - } - } - - 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.context.createTexture(); - }, - onRequestIndex: () => { - return textureIndexes++; - }, - onRequestContextHandle: () => { - return gl.TEXTURE0 + this.constantTextureCount++; - } - }); - this.constantBitRatios[name] = kernelValue.bitRatio; - this.kernelConstants.push(kernelValue); - if (kernelValue.forceUploadEachRun) { - this.forceUploadKernelConstants.push(kernelValue); - } - } - } - - build() { - 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]; - - 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]); - } - - if (!this.immutable) { - this._setupOutputTexture(); - if ( - this.subKernels !== null && - this.subKernels.length > 0 - ) { - this._setupSubOutputTextures(); - } - } - } - - translateSource() { - const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { - fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy - }); - this.translatedSource = functionBuilder.getPrototypeString('kernel'); - 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, forceUploadKernelConstants } = this; - const texSize = this.texSize; - const gl = this.context; - - 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]); - - this.switchingKernels = false; - 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.outputTexture || this.immutable) { - this._setupOutputTexture(); - } - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - return new this.TextureConstructor({ - texture: this.outputTexture, - size: texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }); - } - 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._setupOutputTexture(); - } - - if (this.subKernels !== null) { - if (this.immutable) { - this._setupSubOutputTextures(); - } - this.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(this.drawBuffersMap); - } - - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - } - - getOutputTexture() { - return this.outputTexture; - } - - _setupOutputTexture() { - const gl = this.context; - const texSize = this.texSize; - const texture = this.outputTexture = this.context.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); - if (this.precision === 'single') { - if (this.pipeline) { - switch (this.returnType) { - case 'Number': - case 'Float': - case 'Integer': - if (this.optimizeFloatMemory) { - 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.FLOAT, null); - } - break; - case 'Array(2)': - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - break; - case 'Array(3)': - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - break; - case 'Array(4)': - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - break; - default: - if (!this.graphical) { - throw new Error('Unhandled return type'); - } - } - } else { - 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, gl.TEXTURE_2D, texture, 0); - } - - _setupSubOutputTextures() { - const gl = this.context; - const texSize = this.texSize; - this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; - this.subKernelOutputTextures = []; - for (let i = 0; i < this.subKernels.length; i++) { - const texture = this.context.createTexture(); - this.subKernelOutputTextures.push(texture); - 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); - } - } - - getTextureCache(name) { - if (this.textureCache.hasOwnProperty(name)) { - return this.textureCache[name]; - } - return this.textureCache[name] = this.context.createTexture(); - } - - detachTextureCache(name) { - delete this.textureCache[name]; - } - - 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); - } - - 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); - } - - 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); - } - - 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); - } - - 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 div_with_int_check(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; -}` : - ''; - } - - _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) { - result.push(this.kernelConstants[i++].getSource(this.constants[name])); - } - } - return result.join(''); - } - - getKernelString() { - let kernelResultDeclaration; - switch (this.returnType) { - case 'Array(2)': - kernelResultDeclaration = 'vec2 kernelResult'; - break; - case 'Array(3)': - kernelResultDeclaration = 'vec3 kernelResult'; - break; - case 'Array(4)': - kernelResultDeclaration = 'vec4 kernelResult'; - break; - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - kernelResultDeclaration = 'float kernelResult'; - break; - default: - if (this.graphical) { - kernelResultDeclaration = 'float kernelResult'; - } else { - throw new Error(`unrecognized output type "${ this.returnType }"`); - } - } - - const result = []; - const subKernels = this.subKernels; - if (subKernels !== null) { - result.push( - kernelResultDeclaration - ); - 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; + const markupName = `${origin}_${name}`; + switch (type) { 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 }` - ); - } + this.astGeneric(mNode.object, retArr); + retArr.push('['); + retArr.push(this.memberExpressionPropertyMarkup(xProperty)); + retArr.push(']'); break; - } - } else { - result.push( - kernelResultDeclaration - ); - } - - 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})`, - ); + 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 'HTMLImage': + 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 { - result.push( - ` gl_FragData[${i + 1}] = subKernelResult_${this.subKernels[i].name}`, + const bitRatio = (origin === 'user' ? + this.lookupFunctionArgumentBitRatio(this.name, name) : + this.constantBitRatios[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.outputTexture) { - this.context.deleteTexture(this.outputTexture); - } - if (this.buffer) { - this.context.deleteBuffer(this.buffer); - } - if (this.framebuffer) { - this.context.deleteFramebuffer(this.framebuffer); - } - if (this.vertShader) { - this.context.deleteShader(this.vertShader); - } - if (this.fragShader) { - this.context.deleteShader(this.fragShader); - } - if (this.program) { - this.context.deleteProgram(this.program); - } - - const keys = Object.keys(this.textureCache); - - for (let i = 0; i < keys.length; i++) { - const name = keys[i]; - this.context.deleteTexture(this.textureCache[name]); - } - - if (this.subKernelOutputTextures) { - for (let i = 0; i < this.subKernelOutputTextures.length; i++) { - this.context.deleteTexture(this.subKernelOutputTextures[i]); - } - } - 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; - } - - 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(); - return json; - } -} - -module.exports = { - WebGLKernel -}; -},{"../../plugins/triangle-noise":109,"../../utils":111,"../function-builder":8,"../gl/kernel":12,"../gl/kernel-string":11,"./fragment-shader":35,"./function-node":36,"./kernel-value-maps":37,"./vertex-shader":68}],68:[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 -}; -},{}],69:[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; - -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); -} - -__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 -}; -},{}],70:[function(require,module,exports){ -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); - - if (idtNode.name === 'Infinity') { - retArr.push('intBitsToFloat(2139095039)'); - } else if (type === 'Boolean') { - if (this.argumentNames.indexOf(idtNode.name) > -1) { - retArr.push(`bool(user_${idtNode.name})`); - } else { - retArr.push(`user_${idtNode.name}`); - } - } else { - retArr.push(`user_${idtNode.name}`); - } - - return retArr; - } -} - -module.exports = { - WebGL2FunctionNode -}; -},{"../web-gl/function-node":36}],71:[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 { WebGL2KernelValueSingleArray2 } = require('./kernel-value/single-array2'); -const { WebGL2KernelValueSingleArray3 } = require('./kernel-value/single-array3'); -const { WebGL2KernelValueSingleArray4 } = require('./kernel-value/single-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)': false, - 'Array(3)': false, - 'Array(4)': false, - '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, - 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, - 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, - 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGL2KernelValueBoolean, - 'Float': WebGL2KernelValueFloat, - 'Integer': WebGL2KernelValueInteger, - 'Array': WebGL2KernelValueUnsignedArray, - 'Array(2)': false, - 'Array(3)': false, - 'Array(4)': false, - '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, - 'HTMLImage': WebGL2KernelValueHTMLImage, - 'HTMLImageArray': WebGL2KernelValueHTMLImageArray, - 'HTMLVideo': WebGL2KernelValueHTMLVideo, - } - }, - single: { - dynamic: { - 'Boolean': WebGL2KernelValueBoolean, - 'Integer': WebGL2KernelValueInteger, - 'Float': WebGL2KernelValueFloat, - 'Array': WebGL2KernelValueDynamicSingleArray, - 'Array(2)': WebGL2KernelValueSingleArray2, - 'Array(3)': WebGL2KernelValueSingleArray3, - 'Array(4)': WebGL2KernelValueSingleArray4, - '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, - 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, - 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, - 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGL2KernelValueBoolean, - 'Float': WebGL2KernelValueFloat, - 'Integer': WebGL2KernelValueInteger, - 'Array': WebGL2KernelValueSingleArray, - 'Array(2)': WebGL2KernelValueSingleArray2, - 'Array(3)': WebGL2KernelValueSingleArray3, - 'Array(4)': WebGL2KernelValueSingleArray4, - '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, - 'HTMLImage': 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/boolean":72,"./kernel-value/dynamic-html-image":74,"./kernel-value/dynamic-html-image-array":73,"./kernel-value/dynamic-html-video":75,"./kernel-value/dynamic-memory-optimized-number-texture":76,"./kernel-value/dynamic-number-texture":77,"./kernel-value/dynamic-single-array":78,"./kernel-value/dynamic-single-array1d-i":79,"./kernel-value/dynamic-single-array2d-i":80,"./kernel-value/dynamic-single-array3d-i":81,"./kernel-value/dynamic-single-input":82,"./kernel-value/dynamic-unsigned-array":83,"./kernel-value/dynamic-unsigned-input":84,"./kernel-value/float":85,"./kernel-value/html-image":87,"./kernel-value/html-image-array":86,"./kernel-value/html-video":88,"./kernel-value/integer":89,"./kernel-value/memory-optimized-number-texture":90,"./kernel-value/number-texture":91,"./kernel-value/single-array":92,"./kernel-value/single-array1d-i":93,"./kernel-value/single-array2":94,"./kernel-value/single-array2d-i":95,"./kernel-value/single-array3":96,"./kernel-value/single-array3d-i":97,"./kernel-value/single-array4":98,"./kernel-value/single-input":99,"./kernel-value/unsigned-array":100,"./kernel-value/unsigned-input":101}],72:[function(require,module,exports){ -const { WebGLKernelValueBoolean } = require('../../web-gl/kernel-value/boolean'); - -class WebGL2KernelValueBoolean extends WebGLKernelValueBoolean {} - -module.exports = { - WebGL2KernelValueBoolean -}; -},{"../../web-gl/kernel-value/boolean":38}],73:[function(require,module,exports){ -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 -}; -},{"./html-image-array":86}],74:[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":111,"../../web-gl/kernel-value/dynamic-html-image":39}],75:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueDynamicHTMLImage } = require('./dynamic-html-image'); - -class WebGL2KernelValueDynamicHTMLVideo extends WebGL2KernelValueDynamicHTMLImage {} - -module.exports = { - WebGL2KernelValueDynamicHTMLVideo -}; -},{"../../../utils":111,"./dynamic-html-image":74}],76:[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":111,"../../web-gl/kernel-value/dynamic-memory-optimized-number-texture":41}],77:[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":111,"../../web-gl/kernel-value/dynamic-number-texture":42}],78:[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.bitRatio, this.textureSize[1] * this.bitRatio); - 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":111,"../../web-gl2/kernel-value/single-array":92}],79:[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":111,"../../web-gl2/kernel-value/single-array1d-i":93}],80:[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":111,"../../web-gl2/kernel-value/single-array2d-i":95}],81:[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":111,"../../web-gl2/kernel-value/single-array3d-i":97}],82:[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.bitRatio, this.textureSize[1] * this.bitRatio); - 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":111,"../../web-gl2/kernel-value/single-input":99}],83:[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":111,"../../web-gl/kernel-value/dynamic-unsigned-array":48}],84:[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":111,"../../web-gl/kernel-value/dynamic-unsigned-input":49}],85:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueFloat } = require('../../web-gl/kernel-value/float'); - -class WebGL2KernelValueFloat extends WebGLKernelValueFloat {} - -module.exports = { - WebGL2KernelValueFloat -}; -},{"../../../utils":111,"../../web-gl/kernel-value/float":50}],86:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('../../web-gl/kernel-value/index'); - -class WebGL2KernelValueHTMLImageArray extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.checkSize(value[0].width, value[0].height); - this.requestTexture(); - this.dimensions = [value[0].width, value[0].height, value.length]; - this.textureSize = [value[0].width, value[0].height]; - } - 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.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - 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] - ); + 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; + default: + throw new Error(`unhandled member expression "${ type }"`); + } + return retArr; } - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGL2KernelValueHTMLImageArray -}; -},{"../../../utils":111,"../../web-gl/kernel-value/index":53}],87:[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":111,"../../web-gl/kernel-value/html-image":51}],88:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueHTMLImage } = require('./html-image'); - -class WebGL2KernelValueHTMLVideo extends WebGL2KernelValueHTMLImage {} - -module.exports = { - WebGL2KernelValueHTMLVideo -}; -},{"../../../utils":111,"./html-image":87}],89:[function(require,module,exports){ -const { utils } = require('../../../utils'); -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`; + 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); + } + if (functionName === 'atan2') { + functionName = 'atan'; + } + 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 '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') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast); + this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i); + retArr.push(`user_${argument.name}`); + continue; + } + break; + case 'HTMLImage': + 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); + retArr.push(`user_${argument.name},user_${argument.name}Size,user_${argument.name}Dim`); + continue; + } + break; + } + throw this.astErrorOutput(`Unhandled argument combination of ${ argumentType } and ${ targetType } for argument named "${ argument.name }"`, ast); + } + } + retArr.push(')'); + return retArr; } - 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 -}; -},{"../../../utils":111,"../../web-gl/kernel-value/integer":54}],90:[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":111,"../../web-gl/kernel-value/memory-optimized-number-texture":55}],91:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueNumberTexture } = require('../../web-gl/kernel-value/number-texture'); + astArrayExpression(arrNode, retArr) { + const arrLen = arrNode.elements.length; + retArr.push('vec' + arrLen + '('); + for (let i = 0; i < arrLen; ++i) { + if (i > 0) { + retArr.push(', '); + } + const subNode = arrNode.elements[i]; + 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$2 = { + 'Array': 'sampler2D', + 'Array(2)': 'vec2', + 'Array(3)': 'vec3', + 'Array(4)': 'vec4', + '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', + 'HTMLImage': 'sampler2D', + 'HTMLImageArray': 'sampler2DArray', + }; + const operatorMap = { + '===': '==', + '!==': '!=' + }; -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]})`, - ]); - } -} + const source = ` + +uniform highp float triangle_noise_seed; +highp float triangle_noise_shift = 0.000001; + +//https://www.shadertoy.com/view/4t2SDh +//note: uniformly distributed, normalized rand, [0;1[ +float nrand( vec2 n ) +{ + return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453); +} +//note: remaps v to [0;1] in interval [a;b] +float remap( float a, float b, float v ) +{ + return clamp( (v-a) / (b-a), 0.0, 1.0 ); +} + +float n4rand( vec2 n ) +{ + float t = fract( triangle_noise_seed + triangle_noise_shift ); + float nrnd0 = nrand( n + 0.07*t ); + float nrnd1 = nrand( n + 0.11*t ); + float nrnd2 = nrand( n + 0.13*t ); + float nrnd3 = nrand( n + 0.17*t ); + float result = (nrnd0+nrnd1+nrnd2+nrnd3) / 4.0; + triangle_noise_shift = result + 0.000001; + return result; +}`; + const name$1 = 'triangle-noise-noise'; + const functionMatch = 'Math.random()'; + const functionReplace = 'n4rand(vTexCoord)'; + const functionReturnType = 'Number'; + const onBeforeRun = (kernel) => { + kernel.setUniform1f('triangle_noise_seed', Math.random()); + }; + var triangleNoise = { + name: name$1, + onBeforeRun, + functionMatch, + functionReplace, + functionReturnType, + source + }; -module.exports = { - WebGL2KernelValueNumberTexture -}; -},{"../../../utils":111,"../../web-gl/kernel-value/number-texture":56}],92:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray } = require('../../web-gl/kernel-value/single-array'); + const fragmentShader = `__HEADER__; +__FLOAT_TACTIC_DECLARATION__; +__INT_TACTIC_DECLARATION__; +__SAMPLER_2D_TACTIC_DECLARATION__; + +const int LOOP_MAX = __LOOP_MAX__; + +__PLUGINS__; +__CONSTANTS__; + +varying vec2 vTexCoord; + +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); +} + +__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__; +}`; -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]})`, - ]); - } + 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; +}`; - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - 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); - 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); + function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; } -} - -module.exports = { - WebGL2KernelValueSingleArray -}; -},{"../../../utils":111,"../../web-gl/kernel-value/single-array":57}],93:[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(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - 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); - 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); + var glWiretap_1 = createCommonjsModule(function (module) { + 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; + } } -} - -module.exports = { - WebGL2KernelValueSingleArray1DI -}; -},{"../../../utils":111,"../../web-gl/kernel-value/single-array1d-i":58}],94:[function(require,module,exports){ -const { WebGLKernelValueSingleArray2 } = require('../../web-gl/kernel-value/single-array2'); - -class WebGL2KernelValueSingleArray2 extends WebGLKernelValueSingleArray2 {} - -module.exports = { - WebGL2KernelValueSingleArray2 -}; -},{"../../web-gl/kernel-value/single-array2":59}],95:[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(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - 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); - 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); + 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; + } } -} - -module.exports = { - WebGL2KernelValueSingleArray2DI -}; -},{"../../../utils":111,"../../web-gl/kernel-value/single-array2d-i":60}],96:[function(require,module,exports){ -const { WebGLKernelValueSingleArray3 } = require('../../web-gl/kernel-value/single-array3'); - -class WebGL2KernelValueSingleArray3 extends WebGLKernelValueSingleArray3 {} - -module.exports = { - WebGL2KernelValueSingleArray3 -}; -},{"../../web-gl/kernel-value/single-array3":61}],97:[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(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - 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); - 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); + 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; + } } -} - -module.exports = { - WebGL2KernelValueSingleArray3DI -}; -},{"../../../utils":111,"../../web-gl/kernel-value/single-array3d-i":62}],98:[function(require,module,exports){ -const { WebGLKernelValueSingleArray4 } = require('../../web-gl/kernel-value/single-array4'); - -class WebGL2KernelValueSingleArray4 extends WebGLKernelValueSingleArray4 {} - -module.exports = { - WebGL2KernelValueSingleArray4 -}; -},{"../../web-gl/kernel-value/single-array4":63}],99:[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]})`, - ]); + 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}`); + } } - - updateValue(input) { - const { context: gl } = this; - utils.flattenTo(input.value, this.uploadValue); - 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); - 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); + function trackablePrimitive(value) { + return new value.constructor(value); } -} - -module.exports = { - WebGL2KernelValueSingleInput -}; -},{"../../../utils":111,"../../web-gl/kernel-value/single-input":64}],100:[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 = { glWiretap, glExtensionWiretap }; } -} - -module.exports = { - WebGL2KernelValueUnsignedArray -}; -},{"../../../utils":111,"../../web-gl/kernel-value/unsigned-array":65}],101:[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]})`, - ]); + if (typeof window !== 'undefined') { + glWiretap.glExtensionWiretap = glExtensionWiretap; + window.glWiretap = glWiretap; } -} - -module.exports = { - WebGL2KernelValueUnsignedInput -}; -},{"../../../utils":111,"../../web-gl/kernel-value/unsigned-input":66}],102:[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; + }); + var glWiretap_2 = glWiretap_1.glWiretap; + var glWiretap_3 = glWiretap_1.glExtensionWiretap; + + function toStringWithoutUtils(fn) { + return fn.toString() + .replace('=>', '') + .replace(/^function /, '') + .replace(/utils[.]/g, '/*utils.*/'); + } + function glKernelString(Kernel, args, originKernel, setupContextString, destroyContextString) { + 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 postResult = []; + const context = glWiretap_2(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); + if (argumentName) { + return argumentName; + } + const constantName = findKernelValue(argument, kernel.kernelConstants, constants ? Object.keys(constants).map(key => constants[key]) : [], context); + 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, + } = originKernel; + const kernel = new Kernel(source, { + canvas, + context, + checkContext: false, + output, + pipeline, + graphical, + loopMaxIterations, + constants, + optimizeFloatMemory, + precision, + fixIntegerDivisionAccuracy, + functions, + nativeFunctions, + subKernels, + immutable, + argumentTypes, + constantTypes, + }); + 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 '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$1.flattenTo)}`); + result.push(`function ${toStringWithoutUtils(utils$1.flatten2dArrayTo)}`); + result.push(`function ${toStringWithoutUtils(utils$1.flatten3dArrayTo)}`); + result.push(`function ${toStringWithoutUtils(utils$1.flatten4dArrayTo)}`); + result.push(`function ${toStringWithoutUtils(utils$1.isArray)}`); + if (kernel.renderOutput !== kernel.renderTexture && kernel.formatValues) { + result.push( + ` const renderOutput = function ${toStringWithoutUtils(kernel.formatValues)};` + ); } - 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(); + 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 results = kernel.renderKernels(); + const textureName = context.getContextVariableName(kernel.outputTexture); + result.push(` return { + result: { + texture: ${ textureName }, + type: '${ results.result.type }', + toArray: ${ getToArrayString(results.result, textureName) } + },`); + const { subKernels, subKernelOutputTextures } = kernel; + for (let i = 0; i < subKernels.length; i++) { + const texture = subKernelOutputTextures[i]; + const subKernel = subKernels[i]; + const subKernelResult = results[subKernel.property]; + const subKernelTextureName = context.getContextVariableName(texture); + result.push(` + ${subKernel.property}: { + texture: ${ subKernelTextureName }, + type: '${ subKernelResult.type }', + toArray: ${ getToArrayString(subKernelResult, subKernelTextureName) } + },`); + } + result.push(` };`); + } + 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')} +}`; } - - static isContextMatch(context) { - if (typeof WebGL2RenderingContext !== 'undefined') { - return context instanceof WebGL2RenderingContext; + 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]})`; } - return false; + if (kernel.output[1]) { + return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]})`; + } + return `renderOutput(${readBackValue}, ${kernel.output[0]})`; } - - static getFeatures() { - return Object.freeze({ - isFloatRead: this.getIsFloatRead(), - isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), - kernelMap: true, - isTextureFloat: true, - channelCount: this.getChannelCount(), - maxTextureSize: this.getMaxTextureSize(), + function getGetPixelsString(kernel) { + const getPixels = kernel.getPixels.toString(); + const useFunctionKeyword = !/^function/.test(getPixels); + return utils$1.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ getPixels }`, { + findDependency: (object, name) => { + if (object === 'utils') { + return `const ${name} = ${utils$1[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 }`); + } }); } - - static getIsTextureFloat() { - return true; + function getToArrayString(kernelResult, textureName) { + const toArray = kernelResult.toArray.toString(); + const useFunctionKeyword = !/^function/.test(toArray); + const flattenedFunctions = utils$1.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ toArray }`, { + findDependency: (object, name) => { + if (object === 'utils') { + return `const ${name} = ${utils$1[name].toString()};`; + } else if (object === 'this') { + return `${useFunctionKeyword ? 'function ' : ''}${kernelResult[name].toString()}`; + } else { + throw new Error('unhandled fromObject'); + } + }, + thisLookup: (property) => { + if (property === 'texture') { + return textureName; + } + if (kernelResult.hasOwnProperty(property)) { + return JSON.stringify(kernelResult[property]); + } + throw new Error(`unhandled thisLookup ${ property }`); + } + }); + return `() => { + ${flattenedFunctions} + return toArray(); + }`; } - - static getIsIntegerDivisionAccurate() { - return super.getIsIntegerDivisionAccurate(); + function findKernelValue(argument, kernelValues, values, context, uploadedValues) { + if (argument === 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') 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; + } + return null; + } + 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; } - static getChannelCount() { - return testContext.getParameter(testContext.MAX_DRAW_BUFFERS); + 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 (!tactic) { + throw new Error('tactic 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.id = `${this.origin}_${name}`; + 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; + } + getSource() { + throw new Error(`"getSource" not defined on ${ this.constructor.name }`); + } + updateValue(value) { + throw new Error(`"updateValue" not defined on ${ this.constructor.name }`); + } + } + + 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; + } + 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 width of ${width} larger than maximum size of ${maxTextureSize} for your GPU`); + } else { + throw new Error(`Argument height of ${height} larger than maximum size of ${maxTextureSize} for your GPU`); + } + } + } + requestTexture() { + this.texture = this.onRequestTexture(); + this.setupTexture(); + } + setupTexture() { + this.contextHandle = this.onRequestContextHandle(); + this.index = this.onRequestIndex(); + this.dimensionsId = this.id + 'Dim'; + this.sizeId = this.id + 'Size'; + } + 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; + } + formatArrayTransfer(value, length, Type) { + if (utils$1.isArray(value[0]) || this.optimizeFloatMemory) { + const valuesFlat = new Float32Array(length); + utils$1.flattenTo(value, valuesFlat); + return valuesFlat; + } else { + switch (value.constructor) { + case Uint8ClampedArray: + case Uint8Array: + case Int8Array: + case Uint16Array: + case Int16Array: + case Float32Array: + case Int32Array: { + const valuesFlat = new(Type || value.constructor)(length); + utils$1.flattenTo(value, valuesFlat); + return valuesFlat; + } + default: { + const valuesFlat = new Float32Array(length); + utils$1.flattenTo(value, valuesFlat); + return valuesFlat; + } + } + } + } + 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; + } + } + getStringValueHandler() { + throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`); + } + getVariablePrecisionString() { + switch (this.tactic) { + case 'speed': + return 'lowp'; + case 'performance': + return 'highp'; + case 'balanced': + default: + return 'mediump'; + } + } } - static getMaxTextureSize() { - return testContext.getParameter(testContext.MAX_TEXTURE_SIZE); + 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); + } } - static lookupKernelValueType(type, dynamic, precision, value) { - return lookupKernelValueType(type, dynamic, precision, value); + 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); + } } - static get testCanvas() { - return testCanvas; + 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); + } } - static get testContext() { - return testContext; + class WebGLKernelValueHTMLImage extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + const { width, height } = value; + this.checkSize(width, height); + this.dimensions = [width, height, 1]; + this.requestTexture(); + this.textureSize = [width, height]; + this.uploadValue = value; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + getSource() { + return utils$1.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(); + return; + } + 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); + 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); + } + } + + class WebGLKernelValueDynamicHTMLImage extends WebGLKernelValueHTMLImage { + getSource() { + return utils$1.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); + } + } + + class WebGLKernelValueHTMLVideo extends WebGLKernelValueHTMLImage {} + + class WebGLKernelValueDynamicHTMLVideo extends WebGLKernelValueDynamicHTMLImage {} + + class WebGLKernelValueSingleInput extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + let [w, h, d] = value.size; + this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}.value, uploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.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(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(input.value, this.uploadValue); + 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); + 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); + } + } + + class WebGLKernelValueDynamicSingleInput extends WebGLKernelValueSingleInput { + getSource() { + return utils$1.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$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + class WebGLKernelValueUnsignedInput extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = this.getBitRatio(value); + const [w, h, d] = value.size; + this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); + this.textureSize = utils$1.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); + this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + this.TranserArrayType = this.getTransferArrayType(value.value); + this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength); + this.uploadValue = new Uint8Array(this.preUploadValue.buffer); + } + getStringValueHandler() { + return utils$1.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$1.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(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(input.value, this.preUploadValue); + 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); + 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); + } + } + + class WebGLKernelValueDynamicUnsignedInput extends WebGLKernelValueUnsignedInput { + getSource() { + return utils$1.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$1.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); + this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + 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); + } + } + + class WebGLKernelValueMemoryOptimizedNumberTexture extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + const [width, height] = value.size; + this.checkSize(width, height); + this.setupTexture(); + this.dimensions = value.dimensions; + this.textureSize = value.size; + this.uploadValue = value.texture; + this.forceUploadEachRun = true; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName}.texture;\n`; + } + getSource() { + return utils$1.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(); + return; + } + if (this.checkContext && inputTexture.context !== this.context) { + throw new Error(`Value ${this.name} (${this.type }) must be from same context`); + } + const { context: gl } = this; + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(inputTexture) { + this.checkSize(inputTexture.size[0], inputTexture.size[1]); + this.dimensions = inputTexture.dimensions; + this.textureSize = inputTexture.size; + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(inputTexture); + } + } + + class WebGLKernelValueNumberTexture extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + const [width, height] = value.size; + this.checkSize(width, height); + this.setupTexture(); + const { size: textureSize, dimensions } = value; + this.bitRatio = this.getBitRatio(value); + this.dimensions = dimensions; + this.textureSize = textureSize; + this.uploadValue = value.texture; + this.forceUploadEachRun = true; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName}.texture;\n`; + } + getSource() { + return utils$1.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(); + return; + } + if (this.checkContext && inputTexture.context !== this.context) { + throw new Error(`Value ${this.name} (${this.type}) must be from same context`); + } + const { context: gl } = this; + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicNumberTexture extends WebGLKernelValueNumberTexture { + getSource() { + return utils$1.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); + } + } + + class WebGLKernelValueSingleArray extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + this.dimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}, uploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.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(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(value, this.uploadValue); + 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); + 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); + } + } + + class WebGLKernelValueDynamicSingleArray extends WebGLKernelValueSingleArray { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.dimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + class WebGLKernelValueSingleArray1DI extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + this.setShape(value); + } + setShape(value) { + const valueDimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.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.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}, uploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.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(); + return; + } + const { context: gl } = this; + utils$1.flatten2dArrayTo(value, this.uploadValue); + 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); + 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); + } + } + + class WebGLKernelValueDynamicSingleArray1DI extends WebGLKernelValueSingleArray1DI { + getSource() { + return utils$1.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); + } + } + + class WebGLKernelValueSingleArray2DI extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + this.setShape(value); + } + setShape(value) { + const valueDimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.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.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}, uploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.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(); + return; + } + const { context: gl } = this; + utils$1.flatten3dArrayTo(value, this.uploadValue); + 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); + 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); + } + } + + class WebGLKernelValueDynamicSingleArray2DI extends WebGLKernelValueSingleArray2DI { + getSource() { + return utils$1.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); + } + } + + class WebGLKernelValueSingleArray3DI extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + this.setShape(value); + } + setShape(value) { + const valueDimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.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.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}, uploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.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(); + return; + } + const { context: gl } = this; + utils$1.flatten4dArrayTo(value, this.uploadValue); + 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); + 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); + } } - static get features() { - return features; + class WebGLKernelValueDynamicSingleArray3DI extends WebGLKernelValueSingleArray3DI { + getSource() { + return utils$1.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); + } } - static get fragmentShader() { - return fragmentShader; - } - static get vertexShader() { - return vertexShader; + class WebGLKernelValueSingleArray2 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); + } } - initContext() { - const settings = { - alpha: false, - depth: false, - antialias: false - }; - const context = this.canvas.getContext('webgl2', settings); - return context; + class WebGLKernelValueSingleArray3 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); + } } - 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'), - }; + class WebGLKernelValueSingleArray4 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); + } } - validateSettings(args) { - if (!this.validate) { - this.texSize = utils.getKernelTextureSize({ + class WebGLKernelValueUnsignedArray extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = this.getBitRatio(value); + this.dimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); + this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + this.TranserArrayType = this.getTransferArrayType(value); + this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength); + this.uploadValue = new Uint8Array(this.preUploadValue.buffer); + } + getStringValueHandler() { + return utils$1.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$1.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(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(value, this.preUploadValue); + 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); + 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); + } + } + + class WebGLKernelValueDynamicUnsignedArray extends WebGLKernelValueUnsignedArray { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.dimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); + this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + 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); + } + } + + const kernelValueMaps = { + unsigned: { + dynamic: { + 'Boolean': WebGLKernelValueBoolean, + 'Integer': WebGLKernelValueInteger, + 'Float': WebGLKernelValueFloat, + 'Array': WebGLKernelValueDynamicUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + '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': WebGLKernelValueMemoryOptimizedNumberTexture, + 'HTMLImage': WebGLKernelValueDynamicHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGLKernelValueBoolean, + 'Float': WebGLKernelValueFloat, + 'Integer': WebGLKernelValueInteger, + 'Array': WebGLKernelValueUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + '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': WebGLKernelValueDynamicMemoryOptimizedNumberTexture, + 'HTMLImage': WebGLKernelValueHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueHTMLVideo, + } + }, + single: { + dynamic: { + 'Boolean': WebGLKernelValueBoolean, + 'Integer': WebGLKernelValueInteger, + 'Float': WebGLKernelValueFloat, + 'Array': WebGLKernelValueDynamicSingleArray, + 'Array(2)': WebGLKernelValueSingleArray2, + 'Array(3)': WebGLKernelValueSingleArray3, + 'Array(4)': WebGLKernelValueSingleArray4, + '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, + 'HTMLImage': WebGLKernelValueDynamicHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGLKernelValueBoolean, + 'Float': WebGLKernelValueFloat, + 'Integer': WebGLKernelValueInteger, + 'Array': WebGLKernelValueSingleArray, + 'Array(2)': WebGLKernelValueSingleArray2, + 'Array(3)': WebGLKernelValueSingleArray3, + 'Array(4)': WebGLKernelValueSingleArray4, + '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, + 'HTMLImage': 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]; + } + + let isSupported = null; + let testCanvas = null; + let testContext = null; + let testExtensions = null; + let features = null; + const plugins = [triangleNoise]; + 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 getFeatures() { + const isDrawBuffers = this.getIsDrawBuffers(); + return Object.freeze({ + isFloatRead: this.getIsFloatRead(), + isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), + isTextureFloat: this.getIsTextureFloat(), + isDrawBuffers, + kernelMap: isDrawBuffers, + channelCount: this.getChannelCount(), + }); + } + 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 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$1.systemEndianness(); + this.extensions = {}; + this.subKernelOutputTextures = null; + this.kernelArguments = null; + this.argumentTextureCount = 0; + this.constantTextureCount = 0; + this.compiledFragmentShader = null; + this.compiledVertexShader = null; + this.fragShader = null; + this.vertShader = null; + this.drawBuffersMap = null; + this.outputTexture = null; + this.maxTexSize = null; + this.switchingKernels = false; + this.onRequestSwitchKernel = 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$1.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$1.getVariableType(args[0], this.strictIntegers); + if (argType === 'Array') { + this.output = utils$1.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'); + } + if (this.precision === 'precision') { + this.precision = 'unsigned'; + console.warn('Cannot use graphical mode and single precision at the same time'); + } + this.texSize = utils$1.clone(this.output); + return; + } else if (this.precision === null && features.isTextureFloat) { + this.precision = 'single'; + } + this.texSize = utils$1.getKernelTextureSize({ optimizeFloatMemory: this.optimizeFloatMemory, precision: this.precision, }, this.output); - return; + this.checkTextureSize(); } - - const features = this.constructor.features; - 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'; + 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]; + } } - - if (this.fixIntegerDivisionAccuracy === null) { - this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate; - } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) { - this.fixIntegerDivisionAccuracy = false; + _oldtranslateSource() { + const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { + fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy + }); + const translatedSource = functionBuilder.getPrototypeString('kernel'); + if (!this.returnType) { + this.returnType = functionBuilder.getKernelResultType(); + } + let requiredChannels = 0; + const returnTypes = functionBuilder.getReturnTypes(); + for (let i = 0; i < returnTypes.length; i++) { + switch (returnTypes[i]) { + case 'Float': + case 'Number': + case 'Integer': + requiredChannels++; + break; + case 'Array(2)': + requiredChannels += 2; + break; + case 'Array(3)': + requiredChannels += 3; + break; + case 'Array(4)': + requiredChannels += 4; + break; + } + } + if (features && requiredChannels > features.channelCount) { + throw new Error('Too many channels!'); + } + return this.translatedSource = translatedSource; } - - 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'); + setupArguments(args) { + this.kernelArguments = []; + this.argumentTextureCount = 0; + const needsArgumentTypes = this.argumentTypes === null; + if (needsArgumentTypes) { + this.argumentTypes = []; } - - 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); + 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; + for (let index = 0; index < args.length; index++) { + const value = args[index]; + const name = this.argumentNames[index]; + let type; + if (needsArgumentTypes) { + type = utils$1.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: () => { + return this.context.createTexture(); + }, + onRequestIndex: () => { + return textureIndexes++; + }, + onUpdateValueMismatch: () => { + this.switchingKernels = true; + }, + onRequestContextHandle: () => { + return gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount++; + } + }); + this.kernelArguments.push(kernelArgument); + this.argumentSizes.push(kernelArgument.textureSize); + this.argumentBitRatios[index] = kernelArgument.bitRatio; } } - - if (this.graphical) { - if (this.output.length !== 2) { - throw new Error('Output must have 2 dimensions on graphical mode'); + setupConstants(args) { + const { context: gl } = this; + this.kernelConstants = []; + this.forceUploadKernelConstants = []; + let needsConstantTypes = this.constantTypes === null; + if (needsConstantTypes) { + this.constantTypes = {}; } - - if (this.precision === 'single') { - console.warn('Cannot use graphical mode and single precision at the same time'); - this.precision = 'unsigned'; + this.constantBitRatios = {}; + let textureIndexes = 0; + for (const name in this.constants) { + const value = this.constants[name]; + let type; + if (needsConstantTypes) { + type = utils$1.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.context.createTexture(); + }, + onRequestIndex: () => { + return textureIndexes++; + }, + onRequestContextHandle: () => { + return gl.TEXTURE0 + this.constantTextureCount++; + } + }); + this.constantBitRatios[name] = kernelValue.bitRatio; + this.kernelConstants.push(kernelValue); + if (kernelValue.forceUploadEachRun) { + this.forceUploadKernelConstants.push(kernelValue); + } } - - 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'); - if (!this.graphical && !this.returnType) { - this.returnType = functionBuilder.getKernelResultType(); + build() { + 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]; + 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]); + } + if (!this.immutable) { + this._setupOutputTexture(); + if ( + this.subKernels !== null && + this.subKernels.length > 0 + ) { + this._setupSubOutputTextures(); + } + } } - - if (this.subKernels && this.subKernels.length > 0) { + translateSource() { + const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { + fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy + }); + this.translatedSource = functionBuilder.getPrototypeString('kernel'); + 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, forceUploadKernelConstants } = this; + const texSize = this.texSize; + const gl = this.context; + 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]); + this.switchingKernels = false; + 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.outputTexture || this.immutable) { + this._setupOutputTexture(); + } + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + return new this.TextureConstructor({ + texture: this.outputTexture, + size: texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }); + } + 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._setupOutputTexture(); + } + if (this.subKernels !== null) { + if (this.immutable) { + this._setupSubOutputTextures(); + } + this.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(this.drawBuffersMap); + } + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + } + getOutputTexture() { + return this.outputTexture; + } + _setupOutputTexture() { + const gl = this.context; + const texSize = this.texSize; + const texture = this.outputTexture = this.context.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); + if (this.precision === 'single') { + if (this.pipeline) { + switch (this.returnType) { + case 'Number': + case 'Float': + case 'Integer': + if (this.optimizeFloatMemory) { + 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.FLOAT, null); + } + break; + case 'Array(2)': + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + break; + case 'Array(3)': + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + break; + case 'Array(4)': + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + break; + default: + if (!this.graphical) { + throw new Error('Unhandled return type'); + } + } + } else { + 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, gl.TEXTURE_2D, texture, 0); + } + _setupSubOutputTextures() { + const gl = this.context; + const texSize = this.texSize; + this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; + this.subKernelOutputTextures = []; for (let i = 0; i < this.subKernels.length; i++) { - const subKernel = this.subKernels[i]; - if (!subKernel.returnType) { - subKernel.returnType = functionBuilder.getSubKernelResultType(i); + const texture = this.context.createTexture(); + this.subKernelOutputTextures.push(texture); + 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); } } - } - - run() { - const { kernelArguments, texSize, forceUploadKernelConstants } = this; - const gl = this.context; - - 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); + getTextureCache(name) { + if (this.textureCache.hasOwnProperty(name)) { + return this.textureCache[name]; + } + return this.textureCache[name] = this.context.createTexture(); } - - this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]); - - this.switchingKernels = false; - for (let i = 0; i < forceUploadKernelConstants.length; i++) { - const constant = forceUploadKernelConstants[i]; - constant.updateValue(this.constants[constant.name]); - if (this.switchingKernels) return; + detachTextureCache(name) { + delete this.textureCache[name]; } - for (let i = 0; i < kernelArguments.length; i++) { - kernelArguments[i].updateValue(arguments[i]); - if (this.switchingKernels) return; + 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); } - - if (this.plugins) { - for (let i = 0; i < this.plugins.length; i++) { - const plugin = this.plugins[i]; - if (plugin.onBeforeRun) { - plugin.onBeforeRun(this); + 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); } - - if (this.graphical) { - if (this.pipeline) { - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - if (!this.outputTexture || this.immutable) { - this._setupOutputTexture(); + setUniform2f(name, value1, value2) { + if (this.uniform2fCache.hasOwnProperty(name)) { + const cache = this.uniform2fCache[name]; + if ( + value1 === cache[0] && + value2 === cache[1] + ) { + return; } - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - return new this.TextureConstructor({ - texture: this.outputTexture, - size: texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context - }); } - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - 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); + } + 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); + } + 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); + } + 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); + } + 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$1.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 div_with_int_check(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; +}` : + ''; + } + _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(''); } - - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - if (this.immutable) { - this._setupOutputTexture(); + _getInjectedNative() { + return this.injectedNative || ''; } - - if (this.subKernels !== null) { - if (this.immutable) { - this._setupSubOutputTextures(); + _getMainConstantsString() { + const result = []; + const { constants } = this; + if (constants) { + let i = 0; + for (const name in constants) { + result.push(this.kernelConstants[i++].getSource(this.constants[name])); + } } - gl.drawBuffers(this.drawBuffersMap); + return result.join(''); } - - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - } - - drawBuffers() { - this.context.drawBuffers(this.drawBuffersMap); - } - - getOutputTexture() { - return this.outputTexture; - } - - _setupOutputTexture() { - const { texSize } = this; - const gl = this.context; - const texture = this.outputTexture = gl.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); - if (this.precision === 'single') { - if (this.pipeline) { + getKernelString() { + let kernelResultDeclaration; + switch (this.returnType) { + case 'Array(2)': + kernelResultDeclaration = 'vec2 kernelResult'; + break; + case 'Array(3)': + kernelResultDeclaration = 'vec3 kernelResult'; + break; + case 'Array(4)': + kernelResultDeclaration = 'vec4 kernelResult'; + break; + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + kernelResultDeclaration = 'float kernelResult'; + break; + default: + if (this.graphical) { + kernelResultDeclaration = 'float kernelResult'; + } else { + throw new Error(`unrecognized output type "${ this.returnType }"`); + } + } + const result = []; + const subKernels = this.subKernels; + if (subKernels !== null) { + result.push( + kernelResultDeclaration + ); switch (this.returnType) { case 'Number': case 'Float': case 'Integer': - if (this.optimizeFloatMemory) { - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); - } else { - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.R32F, texSize[0], texSize[1]); + 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)': - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RG32F, texSize[0], texSize[1]); + 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(3)': case 'Array(4)': - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); + for (let i = 0; i < subKernels.length; i++) { + result.push( + `vec4 subKernelResult_${ subKernels[i].name }` + ); + } break; - default: - throw new Error('Unhandled return type'); } } else { - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); + result.push( + kernelResultDeclaration + ); } - } else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + return utils$1.linesToString(result) + this.translatedSource; } - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); - } - - _setupSubOutputTextures() { - const { texSize } = this; - const gl = this.context; - this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; - this.subKernelOutputTextures = []; - for (let i = 0; i < this.subKernels.length; i++) { - const texture = this.context.createTexture(); - this.subKernelOutputTextures.push(texture); - 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.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); + getMainResultGraphical() { + return utils$1.linesToString([ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' gl_FragColor = actualColor', + ]); } - } - - _getHeaderString() { - return ''; - } - - _getTextureCoordinate() { - const subKernels = this.subKernels; - if (subKernels === null || subKernels.length < 1) { - switch (this.tactic) { - case 'speed': - return 'in lowp vec2 vTexCoord;\n'; - case 'performance': - return 'in highp vec2 vTexCoord;\n'; - case 'balanced': - default: - return 'in mediump vec2 vTexCoord;\n'; - } - } else { - switch (this.tactic) { - case 'speed': - return 'out lowp vec2 vTexCoord;\n'; - case 'performance': - return 'out highp vec2 vTexCoord;\n'; - case 'balanced': + getMainResultPackedPixels() { + switch (this.returnType) { + case 'LiteralInteger': + case 'Number': + case 'Integer': + case 'Float': + return this.getMainResultKernelPackedPixels() + + this.getMainResultSubKernelPackedPixels(); default: - return 'out mediump vec2 vTexCoord;\n'; + throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`); } } - } - - _getMainArgumentsString(args) { - const result = []; - const argumentNames = this.argumentNames; - for (let i = 0; i < argumentNames.length; i++) { - result.push(this.kernelArguments[i].getSource(args[i])); + getMainResultKernelPackedPixels() { + return utils$1.linesToString([ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ` gl_FragData[0] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)` + ]); } - return result.join(''); - } - - getKernelString() { - let kernelResultDeclaration; - switch (this.returnType) { - case 'Array(2)': - kernelResultDeclaration = 'vec2 kernelResult'; - break; - case 'Array(3)': - kernelResultDeclaration = 'vec3 kernelResult'; - break; - case 'Array(4)': - kernelResultDeclaration = 'vec4 kernelResult'; - break; - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - kernelResultDeclaration = 'float kernelResult'; - break; - default: - if (this.graphical) { - kernelResultDeclaration = 'float 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 { - throw new Error(`unrecognized output type "${ this.returnType }"`); + result.push( + ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})` + ); } + } + return utils$1.linesToString(result); } - - const result = []; - const subKernels = this.subKernels; - if (subKernels !== null) { - result.push( - kernelResultDeclaration, - 'layout(location = 0) out vec4 data0' - ); - 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 }` - ); + 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`); } - } else { + return utils$1.linesToString(result); + } + getMainResultKernelMemoryOptimizedFloats(result, channel) { result.push( - 'out vec4 data0', - kernelResultDeclaration + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ` gl_FragData[0].${channel} = kernelResult`, ); } - - 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})` - ); + 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}`, + ); + } } } - 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`); + getMainResultKernelNumberTexture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' gl_FragData[0][0] = kernelResult', + ]; } - - 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}`, - ); + 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; } - } - - 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') { + 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( - ` data${i + 1}[0] = float(subKernelResult_${subKernel.name})`, + ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, + ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, ); - } else { + } + 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( - ` data${i + 1}[0] = subKernelResult_${subKernel.name}`, + ` 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; } - 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]`, - ); + getMainResultKernelArray4Texture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' gl_FragData[0] = kernelResult', + ]; } - 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}`, - ); + 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; } - 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(); - return json; - } -} - -module.exports = { - WebGL2Kernel -}; -},{"../../utils":111,"../function-builder":8,"../web-gl/kernel":67,"./fragment-shader":69,"./function-node":70,"./kernel-value-maps":71,"./vertex-shader":103}],103:[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 -}; -},{}],104:[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]; -} -module.exports = GPU; -},{"./index":106}],105:[function(require,module,exports){ -const { gpuMock } = require('gpu-mock.js'); -const { utils } = require('./utils'); -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]); + 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)); } - - if (settings.nativeFunctions) { - for (const p in settings.nativeFunctions) { - this.addNativeFunction(p, settings.nativeFunctions[p]); + getVertexShader(args) { + if (this.compiledVertexShader !== null) { + return this.compiledVertexShader; } + return this.compiledVertexShader = this.replaceArtifacts(this.constructor.vertexShader, this._getVertShaderArtifactMap(args)); } - } - - 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; - } + toString() { + const setupContextString = utils$1.linesToString([ + `const gl = context`, + ]); + return glKernelString(this.constructor, arguments, this, setupContextString); + } + destroy(removeCanvasReferences) { + if (this.outputTexture) { + this.context.deleteTexture(this.outputTexture); } - if (Kernel === null) { - throw new Error('unknown Context'); + if (this.buffer) { + this.context.deleteBuffer(this.buffer); } - } 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 (this.framebuffer) { + this.context.deleteFramebuffer(this.framebuffer); } - if (!Kernel) { - throw new Error(`A requested mode of "${this.mode}" and is not supported`); + if (this.vertShader) { + this.context.deleteShader(this.vertShader); } - } else { - for (let i = 0; i < kernelOrder.length; i++) { - if (kernelOrder[i].isSupported) { - Kernel = kernelOrder[i]; - break; + if (this.fragShader) { + this.context.deleteShader(this.fragShader); + } + if (this.program) { + this.context.deleteProgram(this.program); + } + const keys = Object.keys(this.textureCache); + for (let i = 0; i < keys.length; i++) { + const name = keys[i]; + this.context.deleteTexture(this.textureCache[name]); + } + if (this.subKernelOutputTextures) { + for (let i = 0; i < this.subKernelOutputTextures.length; i++) { + this.context.deleteTexture(this.subKernelOutputTextures[i]); } } - if (!Kernel) { - Kernel = CPUKernel; + 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.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'); - } - - if (this.mode === 'dev') { - const devKernel = gpuMock(source, upgradeDeprecatedCreateKernelSettings(settings)); - this.kernels.push(devKernel); - return devKernel; + 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; } - - 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]); + static destroyContext(context) { + const extension = context.getExtension('WEBGL_lose_context'); + if (extension) { + extension.loseContext(); + } } - - function onRequestFallback(args) { - 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, - warnVarUsage: kernelRun.warnVarUsage, - }); - fallbackKernel.build.apply(fallbackKernel, args); - const result = fallbackKernel.run.apply(fallbackKernel, args); - kernelRun.replaceKernel(fallbackKernel); - return result; + toJSON() { + const json = super.toJSON(); + json.functionNodes = FunctionBuilder.fromKernel(this, WebGLFunctionNode).toJSON(); + return json; } + } - function onRequestSwitchKernel(args, kernel) { - 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; - } - } + class WebGL2FunctionNode extends WebGLFunctionNode { + astIdentifierExpression(idtNode, retArr) { + if (idtNode.type !== 'Identifier') { + throw this.astErrorOutput( + 'IdentifierExpression - not an Identifier', + idtNode + ); } - const signature = argumentTypes.join(','); - const existingKernel = switchableKernels[signature]; - if (existingKernel) { - existingKernel.run.apply(existingKernel, args); - if (existingKernel.renderKernels) { - return existingKernel.renderKernels(); + const type = this.getType(idtNode); + if (idtNode.name === 'Infinity') { + retArr.push('intBitsToFloat(2139095039)'); + } else if (type === 'Boolean') { + if (this.argumentNames.indexOf(idtNode.name) > -1) { + retArr.push(`bool(user_${idtNode.name})`); } else { - return existingKernel.renderOutput(); + retArr.push(`user_${idtNode.name}`); } - } - - const newKernel = switchableKernels[signature] = new kernel.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: 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, - warnVarUsage: kernel.warnVarUsage, - returnType: kernel.returnType, - onRequestFallback, - onRequestSwitchKernel, - }); - newKernel.build.apply(newKernel, args); - newKernel.run.apply(newKernel, args); - kernelRun.replaceKernel(newKernel); - if (newKernel.renderKernels) { - return newKernel.renderKernels(); } else { - return newKernel.renderOutput(); - } - } - 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 kernelRun = kernelRunShortcut(new this.Kernel(source, mergedSettings)); - - if (!this.canvas) { - this.canvas = kernelRun.canvas; + retArr.push(`user_${idtNode.name}`); + } + return retArr; } + } - if (!this.context) { - this.context = kernelRun.context; - } + const fragmentShader$1 = `#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; + +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); +} + +__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__; +}`; - this.kernels.push(kernelRun); + const vertexShader$1 = `#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; +}`; - return kernelRun; - } + class WebGL2KernelValueBoolean extends WebGLKernelValueBoolean {} - 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]; - } + class WebGL2KernelValueFloat extends WebGLKernelValueFloat {} - 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}`); - } + 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`; } - - const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings); - if (settings && typeof settings.argumentTypes === 'object') { - settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]); + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform1i(this.id, this.uploadValue = value); } + } - 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, - }); - } + class WebGL2KernelValueHTMLImage extends WebGLKernelValueHTMLImage { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.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]})`, + ]); } - const kernel = this.createKernel(fn, settingsCopy); - - return kernel; } - 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); + class WebGL2KernelValueDynamicHTMLImage extends WebGLKernelValueDynamicHTMLImage { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); } + } - return function() { - const texture = combinedKernel.apply(this, arguments); - if (texture.toArray) { - return texture.toArray(); + class WebGL2KernelValueHTMLImageArray extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.checkSize(value[0].width, value[0].height); + this.requestTexture(); + this.dimensions = [value[0].width, value[0].height, value.length]; + this.textureSize = [value[0].width, value[0].height]; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.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.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + 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] + ); } - return texture; - }; + this.kernel.setUniform1i(this.id, this.index); + } } - addFunction(source, settings) { - this.functions.push(utils.functionToIFunction(source, settings)); - return this; + 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); + } } - addNativeFunction(name, source, settings) { - if (this.kernels.length > 0) { - throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.'); + class WebGL2KernelValueHTMLVideo extends WebGL2KernelValueHTMLImage {} + + class WebGL2KernelValueDynamicHTMLVideo extends WebGL2KernelValueDynamicHTMLImage {} + + class WebGL2KernelValueSingleInput extends WebGLKernelValueSingleInput { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.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$1.flattenTo(input.value, this.uploadValue); + 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); + 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); } - settings = settings || {}; - const { argumentTypes, argumentNames } = this.Kernel.nativeFunctionArguments(source) || {}; - this.nativeFunctions.push({ - name, - source, - settings, - argumentTypes, - argumentNames, - returnType: settings.returnType || this.Kernel.nativeFunctionReturnType(source), - }); - return this; } - injectNative(source) { - this.injectedNative = source; - return this; + class WebGL2KernelValueDynamicSingleInput extends WebGL2KernelValueSingleInput { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.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$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } } - destroy() { - if (!this.kernels) return; - setTimeout(() => { - 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); - } - } - }, 0); + class WebGL2KernelValueUnsignedInput extends WebGLKernelValueUnsignedInput { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.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]})`, + ]); + } } -} - -function upgradeDeprecatedCreateKernelSettings(settings) { - if (!settings) { - return {}; + class WebGL2KernelValueDynamicUnsignedInput extends WebGLKernelValueDynamicUnsignedInput { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } } - 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); + class WebGL2KernelValueMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture { + getSource() { + const { id, sizeId, textureSize, dimensionsId, dimensions } = this; + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform sampler2D ${id}`, + `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`, + `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`, + ]); + } } - return upgradedSettings; -} - -module.exports = { - GPU, - kernelOrder, - kernelTypes -}; -},{"./backend/cpu/kernel":7,"./backend/headless-gl/kernel":32,"./backend/web-gl/kernel":67,"./backend/web-gl2/kernel":102,"./kernel-run-shortcut":108,"./utils":111,"gpu-mock.js":3}],106:[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'); -module.exports = { - alias, - CPUFunctionNode, - CPUKernel, - GPU, - FunctionBuilder, - FunctionNode, - HeadlessGLKernel, - Input, - input, - Texture, - utils, - - WebGL2FunctionNode, - WebGL2Kernel, - webGL2KernelValueMaps, - - WebGLFunctionNode, - WebGLKernel, - webGLKernelValueMaps, - - GLKernel, - Kernel, - FunctionTracer, -}; -},{"./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":32,"./backend/kernel":34,"./backend/web-gl/function-node":36,"./backend/web-gl/kernel":67,"./backend/web-gl/kernel-value-maps":37,"./backend/web-gl2/function-node":70,"./backend/web-gl2/kernel":102,"./backend/web-gl2/kernel-value-maps":71,"./gpu":105,"./input":107,"./texture":110,"./utils":111}],107:[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]); - } + class WebGL2KernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueDynamicMemoryOptimizedNumberTexture { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); } + } - 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}`); - } + class WebGL2KernelValueNumberTexture extends WebGLKernelValueNumberTexture { + getSource() { + const { id, sizeId, textureSize, dimensionsId, dimensions } = this; + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${id}`, + `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`, + `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`, + ]); } - } - 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; + class WebGL2KernelValueDynamicNumberTexture extends WebGLKernelValueDynamicNumberTexture { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); } } -} - -function input(value, size) { - return new Input(value, size); -} - -module.exports = { - Input, - input -}; -},{"./utils":111}],108:[function(require,module,exports){ -const { utils } = require('./utils'); -function kernelRunShortcut(kernel) { - let run = function() { - kernel.build.apply(kernel, arguments); - if (kernel.renderKernels) { - run = function() { - kernel.run.apply(kernel, arguments); - if (kernel.switchingKernels) { - kernel.switchingKernels = false; - return kernel.onRequestSwitchKernel(arguments, kernel); - } - return kernel.renderKernels(); - }; - } else if (kernel.renderOutput) { - run = function() { - kernel.run.apply(kernel, arguments); - if (kernel.switchingKernels) { - kernel.switchingKernels = false; - return kernel.onRequestSwitchKernel(arguments, kernel); - } - return kernel.renderOutput(); - }; - } else { - run = function() { - return kernel.run.apply(kernel, arguments); - }; + class WebGL2KernelValueSingleArray extends WebGLKernelValueSingleArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.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]})`, + ]); } - 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); + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; } - }); - }; - shortcut.replaceKernel = function(replacementKernel) { - kernel = replacementKernel; - bindKernelToShortcut(kernel, shortcut); - shortcut.kernel = kernel; - }; + const { context: gl } = this; + utils$1.flattenTo(value, this.uploadValue); + 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); + 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); + } + } - bindKernelToShortcut(kernel, shortcut); - shortcut.kernel = kernel; - return shortcut; -} + class WebGL2KernelValueDynamicSingleArray extends WebGL2KernelValueSingleArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.dimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } -function bindKernelToShortcut(kernel, shortcut) { - 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() { - kernel[property].apply(kernel, arguments); - return shortcut; - }; - } else { - if (property === 'toString') { - shortcut.toString = function() { - return kernel.toString.apply(kernel, arguments); - }; - } else { - shortcut[property] = kernel[property].bind(kernel); - } + class WebGL2KernelValueSingleArray1DI extends WebGLKernelValueSingleArray1DI { + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; } - } else { - shortcut.__defineGetter__(property, () => { - return kernel[property]; - }); - shortcut.__defineSetter__(property, (value) => { - kernel[property] = value; - }); + const { context: gl } = this; + utils$1.flattenTo(value, this.uploadValue); + 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); + 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 = { - kernelRunShortcut -}; -},{"./utils":111}],109:[function(require,module,exports){ -const source = ` - -uniform highp float triangle_noise_seed; -highp float triangle_noise_shift = 0.000001; - -//https://www.shadertoy.com/view/4t2SDh -//note: uniformly distributed, normalized rand, [0;1[ -float nrand( vec2 n ) -{ - return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453); -} -//note: remaps v to [0;1] in interval [a;b] -float remap( float a, float b, float v ) -{ - return clamp( (v-a) / (b-a), 0.0, 1.0 ); -} - -float n4rand( vec2 n ) -{ - float t = fract( triangle_noise_seed + triangle_noise_shift ); - float nrnd0 = nrand( n + 0.07*t ); - float nrnd1 = nrand( n + 0.11*t ); - float nrnd2 = nrand( n + 0.13*t ); - float nrnd3 = nrand( n + 0.17*t ); - float result = (nrnd0+nrnd1+nrnd2+nrnd3) / 4.0; - triangle_noise_shift = result + 0.000001; - return result; -}`; - -const name = 'triangle-noise-noise'; - -const functionMatch = 'Math.random()'; -const functionReplace = 'n4rand(vTexCoord)'; - -const functionReturnType = 'Number'; - -const onBeforeRun = (kernel) => { - kernel.setUniform1f('triangle_noise_seed', Math.random()); -}; - -module.exports = { - name, - onBeforeRun, - functionMatch, - functionReplace, - functionReturnType, - source -}; -},{}],110:[function(require,module,exports){ -class Texture { - constructor(settings) { - const { - texture, - size, - dimensions, - output, - context, - type = 'NumberTexture', - } = settings; - if (!output) throw new Error('settings property "output" required.'); - if (!context) throw new Error('settings property "context" required.'); - this.texture = texture; - this.size = size; - this.dimensions = dimensions; - this.output = output; - this.context = context; - this.kernel = null; - this.type = type; + class WebGL2KernelValueDynamicSingleArray1DI extends WebGL2KernelValueSingleArray1DI { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.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); + } } - toArray() { - throw new Error(`Not implemented on ${this.constructor.name}`); + class WebGL2KernelValueSingleArray2DI extends WebGLKernelValueSingleArray2DI { + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(value, this.uploadValue); + 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); + 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); + } } - delete() { - return this.context.deleteTexture(this.texture); + class WebGL2KernelValueDynamicSingleArray2DI extends WebGL2KernelValueSingleArray2DI { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.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 = { - Texture -}; -},{}],111:[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'); + class WebGL2KernelValueSingleArray3DI extends WebGLKernelValueSingleArray3DI { + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(value, this.uploadValue); + 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); + 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); + } + } + + class WebGL2KernelValueDynamicSingleArray3DI extends WebGL2KernelValueSingleArray3DI { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.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); + } + } + + class WebGL2KernelValueSingleArray2 extends WebGLKernelValueSingleArray2 {} + + class WebGL2KernelValueSingleArray3 extends WebGLKernelValueSingleArray3 {} + + class WebGL2KernelValueSingleArray4 extends WebGLKernelValueSingleArray4 {} + + class WebGL2KernelValueUnsignedArray extends WebGLKernelValueUnsignedArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.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]})`, + ]); + } + } + + class WebGL2KernelValueDynamicUnsignedArray extends WebGLKernelValueDynamicUnsignedArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + } + + const kernelValueMaps$1 = { + unsigned: { + dynamic: { + 'Boolean': WebGL2KernelValueBoolean, + 'Integer': WebGL2KernelValueInteger, + 'Float': WebGL2KernelValueFloat, + 'Array': WebGL2KernelValueDynamicUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + '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, + 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, + 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGL2KernelValueBoolean, + 'Float': WebGL2KernelValueFloat, + 'Integer': WebGL2KernelValueInteger, + 'Array': WebGL2KernelValueUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + '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, + 'HTMLImage': WebGL2KernelValueHTMLImage, + 'HTMLImageArray': WebGL2KernelValueHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueHTMLVideo, + } + }, + single: { + dynamic: { + 'Boolean': WebGL2KernelValueBoolean, + 'Integer': WebGL2KernelValueInteger, + 'Float': WebGL2KernelValueFloat, + 'Array': WebGL2KernelValueDynamicSingleArray, + 'Array(2)': WebGL2KernelValueSingleArray2, + 'Array(3)': WebGL2KernelValueSingleArray3, + 'Array(4)': WebGL2KernelValueSingleArray4, + '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, + 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, + 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGL2KernelValueBoolean, + 'Float': WebGL2KernelValueFloat, + 'Integer': WebGL2KernelValueInteger, + 'Array': WebGL2KernelValueSingleArray, + 'Array(2)': WebGL2KernelValueSingleArray2, + 'Array(3)': WebGL2KernelValueSingleArray3, + 'Array(4)': WebGL2KernelValueSingleArray4, + '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, + 'HTMLImage': WebGL2KernelValueHTMLImage, + 'HTMLImageArray': WebGL2KernelValueHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueHTMLVideo, + } + }, + }; + function lookupKernelValueType$1(type, dynamic, precision, value) { + if (!type) { + throw new Error('type missing'); } - return false; - }, - - getFunctionNameFromString(funcStr) { - return FUNCTION_NAME.exec(funcStr)[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 = []; + if (!dynamic) { + throw new Error('dynamic missing'); + } + if (!precision) { + throw new Error('precision missing'); + } + if (value.type) { + type = value.type; + } + const types = kernelValueMaps$1[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]; + } + + let isSupported$1 = null; + let testCanvas$1 = null; + let testContext$1 = null; + let testExtensions$1 = null; + let features$1 = null; + class WebGL2Kernel extends WebGLKernel { + static get isSupported() { + if (isSupported$1 !== null) { + return isSupported$1; + } + this.setupFeatureChecks(); + isSupported$1 = this.isContextMatch(testContext$1); + return isSupported$1; + } + static setupFeatureChecks() { + if (typeof document !== 'undefined') { + testCanvas$1 = document.createElement('canvas'); + } else if (typeof OffscreenCanvas !== 'undefined') { + testCanvas$1 = new OffscreenCanvas(0, 0); + } + if (!testCanvas$1) return; + testContext$1 = testCanvas$1.getContext('webgl2'); + if (!testContext$1 || !testContext$1.getExtension) return; + testExtensions$1 = { + EXT_color_buffer_float: testContext$1.getExtension('EXT_color_buffer_float'), + OES_texture_float_linear: testContext$1.getExtension('OES_texture_float_linear'), + }; + features$1 = this.getFeatures(); } - 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; + static isContextMatch(context) { + if (typeof WebGL2RenderingContext !== 'undefined') { + return context instanceof WebGL2RenderingContext; } + return false; } - - return temp; - }, - - isArray(array) { - return !isNaN(array.length); - }, - - getVariableType(value, strictIntegers) { - if (utils.isArray(value)) { - if (value[0].nodeName === 'IMG') { - return 'HTMLImageArray'; - } - return 'Array'; + static getFeatures() { + return Object.freeze({ + isFloatRead: this.getIsFloatRead(), + isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), + kernelMap: true, + isTextureFloat: true, + channelCount: this.getChannelCount(), + maxTextureSize: this.getMaxTextureSize(), + }); } - - 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'; + static getIsTextureFloat() { + return true; } - switch (value.nodeName) { - case 'IMG': - return 'HTMLImage'; - case 'VIDEO': - return 'HTMLVideo'; + static getIsIntegerDivisionAccurate() { + return super.getIsIntegerDivisionAccurate(); } - if (value.hasOwnProperty('type')) { - return value.type; + static getChannelCount() { + return testContext$1.getParameter(testContext$1.MAX_DRAW_BUFFERS); } - 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); + static getMaxTextureSize() { + return testContext$1.getParameter(testContext$1.MAX_TEXTURE_SIZE); } - if (h > 1 && w * h === texelCount) { - return new Int32Array([w, h]); + static lookupKernelValueType(type, dynamic, precision, value) { + return lookupKernelValueType$1(type, dynamic, precision, value); } - 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}`); + static get testCanvas() { + return testCanvas$1; } - - if (pad) { - ret = Array.from(ret); - while (ret.length < 3) { - ret.push(1); - } + static get testContext() { + return testContext$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; + static get features() { + return features$1; } - }, - - 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; + static get fragmentShader() { + return fragmentShader$1; + } + static get vertexShader() { + return vertexShader$1; + } + initContext() { + const settings = { + alpha: false, + depth: false, + antialias: false + }; + const context = this.canvas.getContext('webgl2', settings); + return context; + } + 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$1.getKernelTextureSize({ + optimizeFloatMemory: this.optimizeFloatMemory, + precision: this.precision, + }, this.output); + return; + } + const features = this.constructor.features; + 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$1.getVariableType(args[0], this.strictIntegers); + switch (argType) { + case 'Array': + this.output = utils$1.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$1.clone(this.output); + return; + } else if (!this.graphical && this.precision === null && features.isTextureFloat) { + this.precision = 'single'; } + this.texSize = utils$1.getKernelTextureSize({ + optimizeFloatMemory: this.optimizeFloatMemory, + precision: this.precision, + }, this.output); + this.checkTextureSize(); } - }, - - 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; + translateSource() { + const functionBuilder = FunctionBuilder.fromKernel(this, WebGL2FunctionNode, { + fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy + }); + this.translatedSource = functionBuilder.getPrototypeString('kernel'); + 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); + } } } } - }, - - 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); + run() { + const { kernelArguments, texSize, forceUploadKernelConstants } = this; + const gl = this.context; + 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]); + this.switchingKernels = false; + 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.outputTexture || this.immutable) { + this._setupOutputTexture(); + } + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + return new this.TextureConstructor({ + texture: this.outputTexture, + size: texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context + }); + } + 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._setupOutputTexture(); + } + if (this.subKernels !== null) { + if (this.immutable) { + this._setupSubOutputTextures(); + } + gl.drawBuffers(this.drawBuffersMap); + } + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + } + drawBuffers() { + this.context.drawBuffers(this.drawBuffersMap); + } + getOutputTexture() { + return this.outputTexture; + } + _setupOutputTexture() { + const { texSize } = this; + const gl = this.context; + const texture = this.outputTexture = gl.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); + if (this.precision === 'single') { + if (this.pipeline) { + switch (this.returnType) { + case 'Number': + case 'Float': + case 'Integer': + if (this.optimizeFloatMemory) { + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); + } else { + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.R32F, texSize[0], texSize[1]); + } + break; + case 'Array(2)': + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RG32F, texSize[0], texSize[1]); + break; + case 'Array(3)': + case 'Array(4)': + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); + break; + default: + throw new Error('Unhandled return type'); + } } else { - utils.flatten3dArrayTo(array, target); + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); } } else { - utils.flatten2dArrayTo(array, target); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); } - } 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)); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); } - 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]); + _setupSubOutputTextures() { + const { texSize } = this; + const gl = this.context; + this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; + this.subKernelOutputTextures = []; + for (let i = 0; i < this.subKernels.length; i++) { + const texture = this.context.createTexture(); + this.subKernelOutputTextures.push(texture); + 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.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); } - 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'; + _getHeaderString() { + return ''; } - }, - 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.`); + _getTextureCoordinate() { + const subKernels = this.subKernels; + if (subKernels === null || subKernels.length < 1) { + switch (this.tactic) { + case 'speed': + return 'in lowp vec2 vTexCoord;\n'; + case 'performance': + return 'in highp vec2 vTexCoord;\n'; + case 'balanced': + default: + return 'in mediump vec2 vTexCoord;\n'; + } + } else { + switch (this.tactic) { + case 'speed': + return 'out lowp vec2 vTexCoord;\n'; + case 'performance': + return 'out highp vec2 vTexCoord;\n'; + case 'balanced': + default: + return 'out mediump vec2 vTexCoord;\n'; + } + } } - }, - functionToIFunction(source, settings) { - settings = 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 || []; + _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(''); } - - return { - source: sourceString, - argumentTypes, - returnType: settings.returnType || null, - }; - }, - 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); + getKernelString() { + let kernelResultDeclaration; + switch (this.returnType) { + case 'Array(2)': + kernelResultDeclaration = 'vec2 kernelResult'; + break; + case 'Array(3)': + kernelResultDeclaration = 'vec3 kernelResult'; + break; + case 'Array(4)': + kernelResultDeclaration = 'vec4 kernelResult'; + break; + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + kernelResultDeclaration = 'float kernelResult'; + break; + default: + if (this.graphical) { + kernelResultDeclaration = 'float kernelResult'; + } else { + throw new Error(`unrecognized output type "${ this.returnType }"`); + } + } + const result = []; + const subKernels = this.subKernels; + if (subKernels !== null) { + result.push( + kernelResultDeclaration, + 'layout(location = 0) out vec4 data0' + ); + 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 }` + ); + } + } else { + result.push( + 'out vec4 data0', + kernelResultDeclaration + ); + } + return utils$1.linesToString(result) + this.translatedSource; } - 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); + getMainResultGraphical() { + return utils$1.linesToString([ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' data0 = actualColor', + ]); } - 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); + 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`); } - 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); + getMainResultKernelPackedPixels() { + return utils$1.linesToString([ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ` data0 = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)` + ]); } - 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); + 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$1.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`); } - zResults[z] = yResults; + return utils$1.linesToString(result); } - 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; + getMainResultKernelMemoryOptimizedFloats(result, channel) { + result.push( + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ` data0.${channel} = kernelResult`, + ); } - 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; + 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}`, + ); } - 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; + getMainResultKernelNumberTexture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' data0[0] = kernelResult', + ]; } - 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); + 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}`, + ); } - yResults[y] = xResults; } - zResults[z] = yResults; + return result; } - 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); + 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]`, + ); } - yResults[y] = xResults; + return result; } - 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; + 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]`, + ); } - zResults[z] = yResults; + return result; } - 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); + 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}`, + ); } - yResults[y] = xResults; + return result; } - 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); + 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(); + return json; + } + } + + function kernelRunShortcut(kernel) { + let run = function() { + kernel.build.apply(kernel, arguments); + if (kernel.renderKernels) { + run = function() { + kernel.run.apply(kernel, arguments); + if (kernel.switchingKernels) { + kernel.switchingKernels = false; + return kernel.onRequestSwitchKernel(arguments, kernel); + } + return kernel.renderKernels(); + }; + } else if (kernel.renderOutput) { + run = function() { + kernel.run.apply(kernel, arguments); + if (kernel.switchingKernels) { + kernel.switchingKernels = false; + return kernel.onRequestSwitchKernel(arguments, kernel); + } + return kernel.renderOutput(); + }; + } else { + run = function() { + return kernel.run.apply(kernel, arguments); + }; + } + 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); } - yResults[y] = xResults; + }); + }; + shortcut.replaceKernel = function(replacementKernel) { + kernel = replacementKernel; + bindKernelToShortcut(kernel, shortcut); + shortcut.kernel = kernel; + }; + bindKernelToShortcut(kernel, shortcut); + shortcut.kernel = kernel; + return shortcut; + } + function bindKernelToShortcut(kernel, shortcut) { + const properties = utils$1.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() { + kernel[property].apply(kernel, arguments); + return shortcut; + }; + } else { + if (property === 'toString') { + shortcut.toString = function() { + return kernel.toString.apply(kernel, arguments); + }; + } else { + shortcut[property] = kernel[property].bind(kernel); + } + } + } else { + shortcut.__defineGetter__(property, () => { + return kernel[property]; + }); + shortcut.__defineSetter__(property, (value) => { + kernel[property] = value; + }); } - 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 = []; + } - function flatten(ast) { - if (Array.isArray(ast)) { - const results = []; - for (let i = 0; i < ast.length; i++) { - results.push(flatten(ast[i])); + const kernelOrder = [ WebGL2Kernel, WebGLKernel ]; + const kernelTypes = [ 'gpu', 'cpu' ]; + const internalKernels = { + '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 false; + } + static get isCanvasSupported() { + return typeof HTMLCanvasElement !== 'undefined'; + } + static get isGPUHTMLImageArraySupported() { + return WebGL2Kernel.isSupported; + } + static get isSinglePrecisionSupported() { + return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.isFloatRead && Kernel.features.isTextureFloat); + } + constructor(settings) { + settings = settings || {}; + this.canvas = settings.canvas || null; + this.context = settings.context || null; + this.mode = settings.mode; + this.Kernel = null; + this.kernels = []; + this.functions = []; + this.nativeFunctions = []; + this.injectedNative = null; + if (this.mode === 'dev') return; + this.chooseKernel(); + if (settings.functions) { + for (let i = 0; i < settings.functions.length; i++) { + this.addFunction(settings.functions[i]); } - return results.join(''); } - switch (ast.type) { - case 'Program': - return flatten(ast.body); - case 'FunctionDeclaration': - return `function ${ast.id.name}(${ast.params.map(flatten).join(', ')}) ${ flatten(ast.body) }`; - case 'BlockStatement': { - const result = []; - for (let i = 0; i < ast.body.length; i++) { - result.push(flatten(ast.body[i]), ';\n'); - } - return `{\n${result.join('')}}`; + if (settings.nativeFunctions) { + for (const p in settings.nativeFunctions) { + this.addNativeFunction(p, settings.nativeFunctions[p]); } - case 'VariableDeclaration': - switch (ast.declarations[0].id.type) { - case 'ObjectPattern': { - const source = flatten(ast.declarations[0].init); - const properties = ast.declarations.map(declaration => declaration.id.properties.map(flatten))[0]; - if (/this/.test(source)) { - const result = []; - const lookups = properties.map(thisLookup); - for (let i = 0; i < lookups.length; i++) { - const lookup = lookups[i]; - if (lookup === null) continue; - const property = properties[i]; - result.push(`${ast.kind} ${ property } = ${ lookup };\n`); - } - - return result.join(''); - } - return `${ast.kind} { ${properties} } = ${source}`; + } + } + getValidate() { + return validate; + } + 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`); } - case 'ArrayPattern': - return `${ast.kind} [ ${ ast.declarations.map(declaration => flatten(declaration.id)).join(', ') } ] = ${flatten(ast.declarations[0].init)}`; - } - if (doNotDefine && doNotDefine.indexOf(ast.declarations[0].id.name) !== -1) { - return ''; - } - return `${ast.kind} ${ast.declarations[0].id.name} = ${flatten(ast.declarations[0].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(', ')})`; + 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 (ast.callee.object.type === 'MemberExpression') { - return `${flatten(ast.callee.object)}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } + } 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' && !isFunction(source) && typeof source !== 'string') { + throw new Error('source parameter not a function'); + } + if (this.mode === 'dev') { + const devKernel = gpuMock_js_1(source, upgradeDeprecatedCreateKernelSettings(settings)); + this.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) { + 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, + warnVarUsage: kernelRun.warnVarUsage, + }); + fallbackKernel.build.apply(fallbackKernel, args); + const result = fallbackKernel.run.apply(fallbackKernel, args); + kernelRun.replaceKernel(fallbackKernel); + return result; + } + function onRequestSwitchKernel(args, kernel) { + 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 { - throw new Error('unknown ast.callee'); + switch (type) { + case 'Number': + case 'Integer': + case 'Float': + case 'ArrayTexture(1)': + argumentTypes[i] = getVariableType(arg); + break; + default: + argumentTypes[i] = type; + } } } - 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)}`; + const signature = argumentTypes.join(','); + const existingKernel = switchableKernels[signature]; + if (existingKernel) { + existingKernel.run.apply(existingKernel, args); + if (existingKernel.renderKernels) { + return existingKernel.renderKernels(); } else { - return `${flatten(ast.argument)} ${ast.operator}`; + return existingKernel.renderOutput(); } - case 'ExpressionStatement': - return `(${flatten(ast.expression)})`; - 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); - } + } + const newKernel = switchableKernels[signature] = new kernel.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: 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, + warnVarUsage: kernel.warnVarUsage, + returnType: kernel.returnType, + onRequestFallback, + onRequestSwitchKernel, + }); + newKernel.build.apply(newKernel, args); + newKernel.run.apply(newKernel, args); + kernelRun.replaceKernel(newKernel); + if (newKernel.renderKernels) { + return newKernel.renderKernels(); + } else { + return newKernel.renderOutput(); + } + } + 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 kernelRun = kernelRunShortcut(new this.Kernel(source, mergedSettings)); + if (!this.canvas) { + this.canvas = kernelRun.canvas; + } + if (!this.context) { + this.context = kernelRun.context; + } + this.kernels.push(kernelRun); + return kernelRun; + } + 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]; } - throw new Error(`unhandled ast.type of ${ ast.type }`); + 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 = 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 = getFunctionNameFromString(source); + settingsCopy.subKernels.push({ + name: name || p, + source, + property: p, + }); + } + } + const kernel = this.createKernel(fn, settingsCopy); + return kernel; } - 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; + 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(); } - flattenedFunctionDependencies.push(utils.flattenFunctionToString(functionDependency, settings) + ';\n'); + return texture; + }; + } + addFunction(source, settings) { + this.functions.push(functionToIFunction(source, settings)); + return this; + } + addNativeFunction(name, source, settings) { + if (this.kernels.length > 0) { + throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.'); } - return flattenedFunctionDependencies.join('') + result; + settings = settings || {}; + const { argumentTypes, argumentNames } = this.Kernel.nativeFunctionArguments(source) || {}; + this.nativeFunctions.push({ + name, + source, + settings, + argumentTypes, + argumentNames, + returnType: settings.returnType || this.Kernel.nativeFunctionReturnType(source), + }); + return this; + } + injectNative(source) { + this.injectedNative = source; + return this; + } + destroy() { + if (!this.kernels) return; + setTimeout(() => { + 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); + } + } + }, 0); } - return result; - }, - - splitHTMLImageToRGB: (image, mode) => { - const gpu = new GPU({ mode }); - - 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: ['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: ['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: ['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: ['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: (rgba, width, height, mode) => { - const { GPU } = require('./gpu.js'); - - const visualGPUR = new GPU({ mode }); - const visualKernelR = visualGPUR.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 visualGPUG = new GPU({ mode }); - const visualKernelG = visualGPUG.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 visualGPUB = new GPU({ mode }); - const visualKernelB = visualGPUB.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 visualGPUA = new GPU({ mode }); - const visualKernelA = visualGPUA.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); - - visualGPUR.destroy(); - visualGPUG.destroy(); - visualGPUB.destroy(); - visualGPUA.destroy(); - - return [ - visualKernelR.canvas, - visualKernelG.canvas, - visualKernelB.canvas, - visualKernelA.canvas, - ]; } -}; + function upgradeDeprecatedCreateKernelSettings(settings) { + if (!settings) { + return {}; + } + const upgradedSettings = Object.assign({}, settings); + if (settings.hasOwnProperty('floatOutput')) { + warnDeprecated('setting', 'floatOutput', 'precision'); + upgradedSettings.precision = settings.floatOutput ? 'single' : 'unsigned'; + } + if (settings.hasOwnProperty('outputToTexture')) { + warnDeprecated('setting', 'outputToTexture', 'pipeline'); + upgradedSettings.pipeline = Boolean(settings.outputToTexture); + } + if (settings.hasOwnProperty('outputImmutable')) { + warnDeprecated('setting', 'outputImmutable', 'immutable'); + upgradedSettings.immutable = Boolean(settings.outputImmutable); + } + if (settings.hasOwnProperty('floatTextures')) { + warnDeprecated('setting', 'floatTextures', 'optimizeFloatMemory'); + upgradedSettings.optimizeFloatMemory = Boolean(settings.floatTextures); + } + return upgradedSettings; + } -const _systemEndianness = utils.getSystemEndianness(); + function alias(name, source) { + const fnString = source.toString(); + return new Function(`return function ${ name } (${ utils$1.getArgumentNamesFromString(fnString).join(', ') }) { + ${ utils$1.getFunctionBodyFromString(fnString) } +}`)(); + } -module.exports = { - utils -}; -},{"./gpu.js":105,"./input":107,"./texture":110,"acorn":1}]},{},[104])(104) -}); + class HeadlessGLKernel extends WebGLKernel { + static get isSupported() { return false } + static isContextMatch() { return false } + static getIsTextureFloat() { return false } + static getIsDrawBuffers() { return false } + static getChannelCount() { return 1 } + static get testCanvas() { return null } + static get testContext() { return null } + static get features() { return null } + static setupFeatureChecks() {} + static destroyContext() {} + initCanvas() { return {} } + initContext() { return null } + toString() { return '' } + initExtensions() {} + build() {} + destroyExtensions() {} + setOutput() {} + static getFeatures() { + return Object.freeze({ + isFloatRead: false, + isIntegerDivisionAccurate: false, + isTextureFloat: false, + isDrawBuffers: false, + kernelMap: false, + channelCount: 1, + }); + } + }const lib = GPU; + lib.alias = alias; + lib.CPUFunctionNode = CPUFunctionNode; + lib.CPUKernel = CPUKernel; + lib.FunctionBuilder = FunctionBuilder; + lib.FunctionNode = FunctionNode; + lib.HeadlessGLKernel = HeadlessGLKernel; + lib.Input = Input; + lib.input = input; + lib.Texture = Texture; + lib.utils = { ...common, ...utils$1 }; + lib.WebGL2FunctionNode = WebGL2FunctionNode; + lib.WebGL2Kernel = WebGL2Kernel; + lib.WebGLFunctionNode = WebGLFunctionNode; + lib.WebGLKernel = WebGLKernel; + lib.GLKernel = GLKernel; + lib.Kernel = Kernel; + + return lib; + +}(acorn)); +//# sourceMappingURL=gpu-browser-core.js.map diff --git a/dist/gpu-browser-core.js.map b/dist/gpu-browser-core.js.map new file mode 100644 index 00000000..8e8e4f3d --- /dev/null +++ b/dist/gpu-browser-core.js.map @@ -0,0 +1 @@ +{"version":3,"file":"gpu-browser-core.js","sources":["../node_modules/gpu-mock.js/index.js","../src/common.js","../src/input.js","../src/texture.js","../src/utils.js","../src/backend/kernel.js","../src/backend/function-builder.js","../src/backend/function-tracer.js","../src/backend/function-node.js","../src/backend/cpu/function-node.js","../src/backend/cpu/kernel-string.js","../src/backend/cpu/kernel.js","../src/backend/gl/texture/float.js","../src/backend/gl/texture/array-2-float.js","../src/backend/gl/texture/array-2-float-2d.js","../src/backend/gl/texture/array-2-float-3d.js","../src/backend/gl/texture/array-3-float.js","../src/backend/gl/texture/array-3-float-2d.js","../src/backend/gl/texture/array-3-float-3d.js","../src/backend/gl/texture/array-4-float.js","../src/backend/gl/texture/array-4-float-2d.js","../src/backend/gl/texture/array-4-float-3d.js","../src/backend/gl/texture/float-2d.js","../src/backend/gl/texture/float-3d.js","../src/backend/gl/texture/memory-optimized.js","../src/backend/gl/texture/memory-optimized-2d.js","../src/backend/gl/texture/memory-optimized-3d.js","../src/backend/gl/texture/unsigned.js","../src/backend/gl/texture/unsigned-2d.js","../src/backend/gl/texture/unsigned-3d.js","../src/backend/gl/texture/graphical.js","../src/backend/gl/kernel.js","../src/backend/web-gl/function-node.js","../src/plugins/triangle-noise.js","../src/backend/web-gl/fragment-shader.js","../src/backend/web-gl/vertex-shader.js","../node_modules/gl-wiretap/index.js","../src/backend/gl/kernel-string.js","../src/backend/kernel-value.js","../src/backend/web-gl/kernel-value/index.js","../src/backend/web-gl/kernel-value/boolean.js","../src/backend/web-gl/kernel-value/float.js","../src/backend/web-gl/kernel-value/integer.js","../src/backend/web-gl/kernel-value/html-image.js","../src/backend/web-gl/kernel-value/dynamic-html-image.js","../src/backend/web-gl/kernel-value/html-video.js","../src/backend/web-gl/kernel-value/dynamic-html-video.js","../src/backend/web-gl/kernel-value/single-input.js","../src/backend/web-gl/kernel-value/dynamic-single-input.js","../src/backend/web-gl/kernel-value/unsigned-input.js","../src/backend/web-gl/kernel-value/dynamic-unsigned-input.js","../src/backend/web-gl/kernel-value/memory-optimized-number-texture.js","../src/backend/web-gl/kernel-value/dynamic-memory-optimized-number-texture.js","../src/backend/web-gl/kernel-value/number-texture.js","../src/backend/web-gl/kernel-value/dynamic-number-texture.js","../src/backend/web-gl/kernel-value/single-array.js","../src/backend/web-gl/kernel-value/dynamic-single-array.js","../src/backend/web-gl/kernel-value/single-array1d-i.js","../src/backend/web-gl/kernel-value/dynamic-single-array1d-i.js","../src/backend/web-gl/kernel-value/single-array2d-i.js","../src/backend/web-gl/kernel-value/dynamic-single-array2d-i.js","../src/backend/web-gl/kernel-value/single-array3d-i.js","../src/backend/web-gl/kernel-value/dynamic-single-array3d-i.js","../src/backend/web-gl/kernel-value/single-array2.js","../src/backend/web-gl/kernel-value/single-array3.js","../src/backend/web-gl/kernel-value/single-array4.js","../src/backend/web-gl/kernel-value/unsigned-array.js","../src/backend/web-gl/kernel-value/dynamic-unsigned-array.js","../src/backend/web-gl/kernel-value-maps.js","../src/backend/web-gl/kernel.js","../src/backend/web-gl2/function-node.js","../src/backend/web-gl2/fragment-shader.js","../src/backend/web-gl2/vertex-shader.js","../src/backend/web-gl2/kernel-value/boolean.js","../src/backend/web-gl2/kernel-value/float.js","../src/backend/web-gl2/kernel-value/integer.js","../src/backend/web-gl2/kernel-value/html-image.js","../src/backend/web-gl2/kernel-value/dynamic-html-image.js","../src/backend/web-gl2/kernel-value/html-image-array.js","../src/backend/web-gl2/kernel-value/dynamic-html-image-array.js","../src/backend/web-gl2/kernel-value/html-video.js","../src/backend/web-gl2/kernel-value/dynamic-html-video.js","../src/backend/web-gl2/kernel-value/single-input.js","../src/backend/web-gl2/kernel-value/dynamic-single-input.js","../src/backend/web-gl2/kernel-value/unsigned-input.js","../src/backend/web-gl2/kernel-value/dynamic-unsigned-input.js","../src/backend/web-gl2/kernel-value/memory-optimized-number-texture.js","../src/backend/web-gl2/kernel-value/dynamic-memory-optimized-number-texture.js","../src/backend/web-gl2/kernel-value/number-texture.js","../src/backend/web-gl2/kernel-value/dynamic-number-texture.js","../src/backend/web-gl2/kernel-value/single-array.js","../src/backend/web-gl2/kernel-value/dynamic-single-array.js","../src/backend/web-gl2/kernel-value/single-array1d-i.js","../src/backend/web-gl2/kernel-value/dynamic-single-array1d-i.js","../src/backend/web-gl2/kernel-value/single-array2d-i.js","../src/backend/web-gl2/kernel-value/dynamic-single-array2d-i.js","../src/backend/web-gl2/kernel-value/single-array3d-i.js","../src/backend/web-gl2/kernel-value/dynamic-single-array3d-i.js","../src/backend/web-gl2/kernel-value/single-array2.js","../src/backend/web-gl2/kernel-value/single-array3.js","../src/backend/web-gl2/kernel-value/single-array4.js","../src/backend/web-gl2/kernel-value/unsigned-array.js","../src/backend/web-gl2/kernel-value/dynamic-unsigned-array.js","../src/backend/web-gl2/kernel-value-maps.js","../src/backend/web-gl2/kernel.js","../src/kernel-run-shortcut.js","../src/base-gpu.js","../src/alias.js","../src/browser.js"],"sourcesContent":["function setupArguments(args) {\n const newArguments = new Array(args.length);\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg.toArray) {\n newArguments[i] = arg.toArray();\n } else {\n newArguments[i] = arg;\n }\n }\n return newArguments;\n}\n\nfunction mock1D() {\n const args = setupArguments(arguments);\n const row = new Float32Array(this.output.x);\n for (let x = 0; x < this.output.x; x++) {\n this.thread.x = x;\n this.thread.y = 0;\n this.thread.z = 0;\n row[x] = this._fn.apply(this, args);\n }\n return row;\n}\n\nfunction mock2D() {\n const args = setupArguments(arguments);\n const matrix = new Array(this.output.y);\n for (let y = 0; y < this.output.y; y++) {\n const row = new Float32Array(this.output.x);\n for (let x = 0; x < this.output.x; x++) {\n this.thread.x = x;\n this.thread.y = y;\n this.thread.z = 0;\n row[x] = this._fn.apply(this, args);\n }\n matrix[y] = row;\n }\n return matrix;\n}\n\nfunction mock2DGraphical() {\n const args = setupArguments(arguments);\n for (let y = 0; y < this.output.y; y++) {\n for (let x = 0; x < this.output.x; x++) {\n this.thread.x = x;\n this.thread.y = y;\n this.thread.z = 0;\n this._fn.apply(this, args);\n }\n }\n}\n\nfunction mock3D() {\n const args = setupArguments(arguments);\n const cube = new Array(this.output.z);\n for (let z = 0; z < this.output.z; z++) {\n const matrix = new Array(this.output.y);\n for (let y = 0; y < this.output.y; y++) {\n const row = new Float32Array(this.output.x);\n for (let x = 0; x < this.output.x; x++) {\n this.thread.x = x;\n this.thread.y = y;\n this.thread.z = z;\n row[x] = this._fn.apply(this, args);\n }\n matrix[y] = row;\n }\n cube[z] = matrix;\n }\n return cube;\n}\n\nfunction apiDecorate(kernel) {\n kernel.setOutput = (output) => {\n kernel.output = setupOutput(output);\n if (kernel.graphical) {\n setupGraphical(kernel);\n }\n };\n kernel.toJSON = () => {\n throw new Error('Not usable with gpuMock');\n };\n kernel.setConstants = (flag) => {\n kernel.constants = flag;\n return kernel;\n };\n kernel.setGraphical = (flag) => {\n kernel.graphical = flag;\n return kernel;\n };\n kernel.setCanvas = (flag) => {\n kernel.canvas = flag;\n return kernel;\n };\n kernel.setContext = (flag) => {\n kernel.context = flag;\n return kernel;\n };\n kernel.exec = function() {\n return new Promise((resolve, reject) => {\n try {\n resolve(kernel.apply(kernel, arguments));\n } catch(e) {\n reject(e);\n }\n });\n };\n kernel.getPixels = (flip) => {\n const {x, y} = kernel.output;\n // cpu is not flipped by default\n return flip ? flipPixels(kernel._imageData.data, x, y) : kernel._imageData.data.slice(0);\n };\n kernel.color = function(r, g, b, a) {\n if (typeof a === 'undefined') {\n a = 1;\n }\n\n r = Math.floor(r * 255);\n g = Math.floor(g * 255);\n b = Math.floor(b * 255);\n a = Math.floor(a * 255);\n\n const width = kernel.output.x;\n const height = kernel.output.y;\n\n const x = kernel.thread.x;\n const y = height - kernel.thread.y - 1;\n\n const index = x + y * width;\n\n kernel._colorData[index * 4 + 0] = r;\n kernel._colorData[index * 4 + 1] = g;\n kernel._colorData[index * 4 + 2] = b;\n kernel._colorData[index * 4 + 3] = a;\n };\n\n // these are added for api compatibility, but have no affect\n kernel.setWarnVarUsage = () => {\n return kernel;\n };\n kernel.setOptimizeFloatMemory = () => {\n return kernel;\n };\n kernel.setArgumentTypes = () => {\n return kernel;\n };\n kernel.setDebug = () => {\n return kernel;\n };\n kernel.setLoopMaxIterations = () => {\n return kernel;\n };\n kernel.setPipeline = () => {\n return kernel;\n };\n kernel.setPrecision = () => {\n return kernel;\n };\n kernel.setImmutable = () => {\n return kernel;\n };\n kernel.setFunctions = () => {\n return kernel;\n };\n kernel.addSubKernel = () => {\n return kernel;\n };\n kernel.destroy = () => {};\n kernel.validateSettings = () => {};\n if (kernel.graphical && kernel.output) {\n setupGraphical(kernel);\n }\n return kernel;\n}\n\nfunction setupGraphical(kernel) {\n const {x, y} = kernel.output;\n if (kernel.context && kernel.context.createImageData) {\n const data = new Uint8ClampedArray(x * y * 4);\n kernel._imageData = kernel.context.createImageData(x, y);\n kernel._colorData = data;\n } else {\n const data = new Uint8ClampedArray(x * y * 4);\n kernel._imageData = { data };\n kernel._colorData = data;\n }\n}\n\nfunction setupOutput(output) {\n let result = null;\n if (output.length) {\n if (output.length === 3) {\n const [x,y,z] = output;\n result = { x, y, z };\n } else if (output.length === 2) {\n const [x,y] = output;\n result = { x, y };\n } else {\n const [x] = output;\n result = { x };\n }\n } else {\n result = output;\n }\n return result;\n}\n\nfunction gpuMock(fn, settings = {}) {\n const output = settings.output ? setupOutput(settings.output) : null;\n function kernel() {\n if (kernel.output.z) {\n return mock3D.apply(kernel, arguments);\n } else if (kernel.output.y) {\n if (kernel.graphical) {\n return mock2DGraphical.apply(kernel, arguments);\n }\n return mock2D.apply(kernel, arguments);\n } else {\n return mock1D.apply(kernel, arguments);\n }\n }\n kernel._fn = fn;\n kernel.constants = settings.constants || null;\n kernel.context = settings.context || null;\n kernel.canvas = settings.canvas || null;\n kernel.graphical = settings.graphical || false;\n kernel._imageData = null;\n kernel._colorData = null;\n kernel.output = output;\n kernel.thread = {\n x: 0,\n y: 0,\n z: 0\n };\n return apiDecorate(kernel);\n}\n\nfunction flipPixels(pixels, width, height) {\n // https://stackoverflow.com/a/41973289/1324039\n const halfHeight = height / 2 | 0; // the | 0 keeps the result an int\n const bytesPerRow = width * 4;\n // make a temp buffer to hold one row\n const temp = new Uint8ClampedArray(width * 4);\n const result = pixels.slice(0);\n for (let y = 0; y < halfHeight; ++y) {\n const topOffset = y * bytesPerRow;\n const bottomOffset = (height - y - 1) * bytesPerRow;\n\n // make copy of a row on the top half\n temp.set(result.subarray(topOffset, topOffset + bytesPerRow));\n\n // copy a row from the bottom half to the top\n result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow);\n\n // copy the copy of the top half row to the bottom half\n result.set(temp, bottomOffset);\n }\n return result;\n}\n\nmodule.exports = {\n gpuMock\n};\n","/**\r\n * @fileoverview Branch of utils to prevent circular dependencies.\r\n */\r\n\r\nconst ARGUMENT_NAMES = /([^\\s,]+)/g;\r\nconst FUNCTION_NAME = /function ([^(]*)/;\r\nconst STRIP_COMMENTS = /((\\/\\/.*$)|(\\/\\*[\\s\\S]*?\\*\\/))/mg;\r\n\r\n/**\r\n * @descReturn TRUE, on a JS function\r\n * @param {Function} funcObj - Object to validate if its a function\r\n * @returns {Boolean} TRUE if the object is a JS function\r\n */\r\nexport function isFunction(funcObj) {\r\n return typeof(funcObj) === 'function';\r\n};\r\n\r\n/**\r\n * @desc Return the function name from a JS function string\r\n * @param {String} funcStr - String of JS function to validate\r\n * @returns {String} Function name string (if found)\r\n */\r\nexport function getFunctionNameFromString(funcStr) {\r\n return FUNCTION_NAME.exec(funcStr)[1].trim();\r\n};\r\n\r\n/**\r\n *\r\n * @param {String|Function} source\r\n * @param {IFunctionSettings} [settings]\r\n * @returns {IFunction}\r\n */\r\nexport function functionToIFunction(source, settings) {\r\n settings = settings || {};\r\n if (typeof source !== 'string' && typeof source !== 'function') throw new Error('source not a string or function');\r\n const sourceString = typeof source === 'string' ? source : source.toString();\r\n\r\n let argumentTypes = [];\r\n\r\n if (Array.isArray(settings.argumentTypes)) {\r\n argumentTypes = settings.argumentTypes;\r\n } else if (typeof settings.argumentTypes === 'object') {\r\n argumentTypes = getArgumentNamesFromString(sourceString)\r\n .map(name => settings.argumentTypes[name]) || [];\r\n } else {\r\n argumentTypes = settings.argumentTypes || [];\r\n }\r\n\r\n return {\r\n source: sourceString,\r\n argumentTypes,\r\n returnType: settings.returnType || null,\r\n };\r\n};\r\n\r\nexport function warnDeprecated(type, oldName, newName) {\r\n const msg = newName\r\n ? `It has been replaced with \"${ newName }\"`\r\n : 'It has been removed';\r\n console.warn(`You are using a deprecated ${ type } \"${ oldName }\". ${msg}. Fixing, but please upgrade as it will soon be removed.`)\r\n};\r\n\r\n/**\r\n * @desc Return TRUE, on a valid JS function string\r\n * Note: This does just a VERY simply sanity check. And may give false positives.\r\n *\r\n * @param {String} fn - String of JS function to validate\r\n * @returns {Boolean} TRUE if the string passes basic validation\r\n */\r\nexport function isFunctionString(fn) {\r\n if (typeof fn === 'string') {\r\n return (fn\r\n .slice(0, 'function'.length)\r\n .toLowerCase() === 'function');\r\n }\r\n return false;\r\n};\r\n\r\n/**\r\n * @desc Return list of argument names extracted from a javascript function\r\n * @param {String} fn - String of JS function to validate\r\n * @returns {String[]} Array representing all the parameter names\r\n */\r\nexport function getArgumentNamesFromString(fn) {\r\n const fnStr = fn.replace(STRIP_COMMENTS, '');\r\n let result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);\r\n if (result === null) {\r\n result = [];\r\n }\r\n return result;\r\n};\r\n\r\n/**\r\n * @desc Checks if is an array or Array-like object\r\n * @param {Object} array - The argument object to check if is array\r\n * @returns {Boolean} true if is array or Array-like object\r\n */\r\nexport function isArray(array) {\r\n return !isNaN(array.length);\r\n};\r\n\r\nexport function erectMemoryOptimized2DFloat(array, width, height) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const offset = y * width;\r\n yResults[y] = array.subarray(offset, offset + width);\r\n }\r\n return yResults;\r\n};\r\n\r\nexport function erectMemoryOptimized3DFloat(array, width, height, depth) {\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const offset = (z * height * width) + (y * width);\r\n yResults[y] = array.subarray(offset, offset + width);\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n};\r\n\r\nexport function getAstString(source, ast) {\r\n const lines = Array.isArray(source) ? source : source.split(/\\r?\\n/g);\r\n const start = ast.loc.start;\r\n const end = ast.loc.end;\r\n const result = [];\r\n if (start.line === end.line) {\r\n result.push(lines[start.line - 1].substring(start.column, end.column));\r\n } else {\r\n result.push(lines[start.line - 1].slice(start.column));\r\n for (let i = start.line; i < end.line; i++) {\r\n result.push(lines[i]);\r\n }\r\n result.push(lines[end.line - 1].slice(0, end.column));\r\n }\r\n return result.join('\\n');\r\n};\r\n","import { erectMemoryOptimized2DFloat, erectMemoryOptimized3DFloat } from './common';\r\n\r\nexport class Input {\r\n constructor(value, size) {\r\n this.value = value;\r\n if (Array.isArray(size)) {\r\n this.size = size;\r\n } else {\r\n this.size = new Int32Array(3);\r\n if (size.z) {\r\n this.size = new Int32Array([size.x, size.y, size.z]);\r\n } else if (size.y) {\r\n this.size = new Int32Array([size.x, size.y]);\r\n } else {\r\n this.size = new Int32Array([size.x]);\r\n }\r\n }\r\n\r\n const [w, h, d] = this.size;\r\n if (d) {\r\n if (this.value.length !== (w * h * d)) {\r\n throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} * ${d} = ${(h * w * d)}`);\r\n }\r\n } else if (h) {\r\n if (this.value.length !== (w * h)) {\r\n throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} = ${(h * w)}`);\r\n }\r\n } else {\r\n if (this.value.length !== w) {\r\n throw new Error(`Input size ${this.value.length} does not match ${w}`);\r\n }\r\n }\r\n\r\n }\r\n\r\n toArray() {\r\n const [ w, h, d ] = this.size;\r\n if (d) {\r\n return erectMemoryOptimized3DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h, d);\r\n } else if (h) {\r\n return erectMemoryOptimized2DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h);\r\n } else {\r\n return this.value;\r\n }\r\n }\r\n};\r\n\r\nexport function input(value, size) {\r\n return new Input(value, size);\r\n};\r\n","/**\r\n * @desc WebGl Texture implementation in JS\r\n * @param {ITextureSettings} settings\r\n */\r\nexport class Texture {\r\n constructor(settings) {\r\n const {\r\n texture,\r\n size,\r\n dimensions,\r\n output,\r\n context,\r\n type = 'NumberTexture',\r\n } = settings;\r\n if (!output) throw new Error('settings property \"output\" required.');\r\n if (!context) throw new Error('settings property \"context\" required.');\r\n this.texture = texture;\r\n this.size = size;\r\n this.dimensions = dimensions;\r\n this.output = output;\r\n this.context = context;\r\n this.kernel = null;\r\n this.type = type;\r\n }\r\n\r\n /**\r\n * @desc Converts the Texture into a JavaScript Array\r\n * @returns {Number[]|Number[][]|Number[][][]}\r\n */\r\n toArray() {\r\n throw new Error(`Not implemented on ${this.constructor.name}`);\r\n }\r\n\r\n /**\r\n * @desc Deletes the Texture\r\n */\r\n delete() {\r\n return this.context.deleteTexture(this.texture);\r\n }\r\n};\r\n","import { parse } from 'acorn';\r\nimport { Texture } from './texture';\r\nimport { Input } from './input';\r\nimport {\r\n getAstString,\r\n erectMemoryOptimized2DFloat,\r\n erectMemoryOptimized3DFloat,\r\n functionToIFunction,\r\n getArgumentNamesFromString,\r\n getFunctionNameFromString,\r\n isArray,\r\n isFunction,\r\n isFunctionString,\r\n warnDeprecated\r\n} from './common';\r\n\r\nexport function getSystemEndianness() {\r\n const b = new ArrayBuffer(4);\r\n const a = new Uint32Array(b);\r\n const c = new Uint8Array(b);\r\n a[0] = 0xdeadbeef;\r\n if (c[0] === 0xef) return 'LE';\r\n if (c[0] === 0xde) return 'BE';\r\n throw new Error('unknown endianness');\r\n};\r\n\r\nconst _systemEndianness = getSystemEndianness();\r\n\r\n/**\r\n *\r\n * @desc Gets the system endianness, and cache it\r\n * @returns {String} 'LE' or 'BE' depending on system architecture\r\n * Credit: https://gist.github.com/TooTallNate/4750953\r\n */\r\nexport function systemEndianness() {\r\n return _systemEndianness;\r\n};\r\n\r\n/**\r\n * @desc Evaluate the argument type, to apply respective logic for it\r\n * @param {Object} value - The argument object to evaluate type\r\n * @returns {String} Argument type Array/Number/Float/Texture/Unknown\r\n */\r\nexport function getVariableType(value, strictIntegers) {\r\n if (isArray(value)) {\r\n if (value[0].nodeName === 'IMG') {\r\n return 'HTMLImageArray';\r\n }\r\n return 'Array';\r\n }\r\n\r\n switch (value.constructor) {\r\n case Boolean:\r\n return 'Boolean';\r\n case Number:\r\n return strictIntegers && Number.isInteger(value) ? 'Integer' : 'Float';\r\n case Texture:\r\n return value.type;\r\n case Input:\r\n return 'Input';\r\n }\r\n\r\n switch (value.nodeName) {\r\n case 'IMG':\r\n return 'HTMLImage';\r\n case 'VIDEO':\r\n return 'HTMLVideo';\r\n }\r\n\r\n return value.hasOwnProperty('type') ? value.type : 'Unknown';\r\n};\r\n\r\n/**\r\n * @desc Various utility functions / snippets of code that GPU.JS uses internally.\r\n * This covers various snippets of code that is not entirely gpu.js specific (ie. may find uses elsewhere)\r\n */\r\nconst utils = {\r\n systemEndianness,\r\n getSystemEndianness,\r\n isFunction,\r\n isFunctionString,\r\n getFunctionNameFromString,\r\n\r\n getFunctionBodyFromString(funcStr) {\r\n return funcStr.substring(funcStr.indexOf('{') + 1, funcStr.lastIndexOf('}'));\r\n },\r\n\r\n getArgumentNamesFromString,\r\n\r\n /**\r\n * @desc Returns a clone\r\n * @param {Object} obj - Object to clone\r\n * @returns {Object|Array} Cloned object\r\n */\r\n clone(obj) {\r\n if (obj === null || typeof obj !== 'object' || obj.hasOwnProperty('isActiveClone')) return obj;\r\n\r\n const temp = obj.constructor(); // changed\r\n\r\n for (let key in obj) {\r\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\r\n obj.isActiveClone = null;\r\n temp[key] = utils.clone(obj[key]);\r\n delete obj.isActiveClone;\r\n }\r\n }\r\n\r\n return temp;\r\n },\r\n\r\n isArray,\r\n getVariableType,\r\n\r\n getKernelTextureSize(settings, dimensions) {\r\n let [w, h, d] = dimensions;\r\n let texelCount = (w || 1) * (h || 1) * (d || 1);\r\n\r\n if (settings.optimizeFloatMemory && settings.precision === 'single') {\r\n w = texelCount = Math.ceil(texelCount / 4);\r\n }\r\n // if given dimensions == a 2d image\r\n if (h > 1 && w * h === texelCount) {\r\n return new Int32Array([w, h]);\r\n }\r\n return utils.closestSquareDimensions(texelCount);\r\n },\r\n\r\n /**\r\n *\r\n * @param {Number} length\r\n * @returns {TextureDimensions}\r\n */\r\n closestSquareDimensions(length) {\r\n const sqrt = Math.sqrt(length);\r\n let high = Math.ceil(sqrt);\r\n let low = Math.floor(sqrt);\r\n while (high * low < length) {\r\n high--;\r\n low = Math.ceil(length / high);\r\n }\r\n return new Int32Array([low, Math.ceil(length / low)]);\r\n },\r\n\r\n /**\r\n * A texture takes up four\r\n * @param {OutputDimensions} dimensions\r\n * @param {Number} bitRatio\r\n * @returns {TextureDimensions}\r\n */\r\n getMemoryOptimizedFloatTextureSize(dimensions, bitRatio) {\r\n const totalArea = utils.roundTo((dimensions[0] || 1) * (dimensions[1] || 1) * (dimensions[2] || 1) * (dimensions[3] || 1), 4);\r\n const texelCount = totalArea / bitRatio;\r\n return utils.closestSquareDimensions(texelCount);\r\n },\r\n\r\n /**\r\n *\r\n * @param dimensions\r\n * @param bitRatio\r\n * @returns {*|TextureDimensions}\r\n */\r\n getMemoryOptimizedPackedTextureSize(dimensions, bitRatio) {\r\n const [w, h, d] = dimensions;\r\n const totalArea = utils.roundTo((w || 1) * (h || 1) * (d || 1), 4);\r\n const texelCount = totalArea / (4 / bitRatio);\r\n return utils.closestSquareDimensions(texelCount);\r\n },\r\n\r\n roundTo(n, d) {\r\n return Math.floor((n + d - 1) / d) * d;\r\n },\r\n /**\r\n * @desc Return the dimension of an array.\r\n * @param {Array|String|Texture|Input} x - The array\r\n * @param {Boolean} [pad] - To include padding in the dimension calculation\r\n * @returns {OutputDimensions}\r\n */\r\n getDimensions(x, pad) {\r\n let ret;\r\n if (isArray(x)) {\r\n const dim = [];\r\n let temp = x;\r\n while (isArray(temp)) {\r\n dim.push(temp.length);\r\n temp = temp[0];\r\n }\r\n ret = dim.reverse();\r\n } else if (x instanceof Texture) {\r\n ret = x.output;\r\n } else if (x instanceof Input) {\r\n ret = x.size;\r\n } else {\r\n throw new Error(`Unknown dimensions of ${x}`);\r\n }\r\n\r\n if (pad) {\r\n ret = Array.from(ret);\r\n while (ret.length < 3) {\r\n ret.push(1);\r\n }\r\n }\r\n\r\n return new Int32Array(ret);\r\n },\r\n\r\n /**\r\n * Puts a nested 2d array into a one-dimensional target array\r\n * @param {Array|*} array\r\n * @param {Float32Array|Float64Array} target\r\n */\r\n flatten2dArrayTo(array, target) {\r\n let offset = 0;\r\n for (let y = 0; y < array.length; y++) {\r\n target.set(array[y], offset);\r\n offset += array[y].length;\r\n }\r\n },\r\n\r\n /**\r\n * Puts a nested 3d array into a one-dimensional target array\r\n * @param {Array|*} array\r\n * @param {Float32Array|Float64Array} target\r\n */\r\n flatten3dArrayTo(array, target) {\r\n let offset = 0;\r\n for (let z = 0; z < array.length; z++) {\r\n for (let y = 0; y < array[z].length; y++) {\r\n target.set(array[z][y], offset);\r\n offset += array[z][y].length;\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Puts a nested 4d array into a one-dimensional target array\r\n * @param {Array|*} array\r\n * @param {Float32Array|Float64Array} target\r\n */\r\n flatten4dArrayTo(array, target) {\r\n let offset = 0;\r\n for (let l = 0; l < array.length; l++) {\r\n for (let z = 0; z < array[l].length; z++) {\r\n for (let y = 0; y < array[l][z].length; y++) {\r\n target.set(array[l][z][y], offset);\r\n offset += array[l][z][y].length;\r\n }\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Puts a nested 1d, 2d, or 3d array into a one-dimensional target array\r\n * @param {Float32Array|Uint16Array|Uint8Array} array\r\n * @param {Float32Array} target\r\n */\r\n flattenTo(array, target) {\r\n if (isArray(array[0])) {\r\n if (isArray(array[0][0])) {\r\n if (isArray(array[0][0][0])) {\r\n utils.flatten4dArrayTo(array, target);\r\n } else {\r\n utils.flatten3dArrayTo(array, target);\r\n }\r\n } else {\r\n utils.flatten2dArrayTo(array, target);\r\n }\r\n } else {\r\n target.set(array);\r\n }\r\n },\r\n\r\n /**\r\n *\r\n * @desc Splits an array into smaller arrays.\r\n * Number of elements in one small chunk is given by `part`\r\n *\r\n * @param {Number[]} array - The array to split into chunks\r\n * @param {Number} part - elements in one chunk\r\n *\r\n * @returns {Number[]} An array of smaller chunks\r\n */\r\n splitArray(array, part) {\r\n const result = [];\r\n for (let i = 0; i < array.length; i += part) {\r\n result.push(new array.constructor(array.buffer, i * 4 + array.byteOffset, part));\r\n }\r\n return result;\r\n },\r\n\r\n getAstString,\r\n\r\n allPropertiesOf(obj) {\r\n const props = [];\r\n\r\n do {\r\n props.push.apply(props, Object.getOwnPropertyNames(obj));\r\n } while (obj = Object.getPrototypeOf(obj));\r\n\r\n return props;\r\n },\r\n\r\n /**\r\n * @param {Array} lines - An Array of strings\r\n * @returns {String} Single combined String, separated by *\\n*\r\n */\r\n linesToString(lines) {\r\n if (lines.length > 0) {\r\n return lines.join(';\\n') + ';\\n';\r\n } else {\r\n return '\\n';\r\n }\r\n },\r\n\r\n warnDeprecated,\r\n functionToIFunction,\r\n\r\n flipPixels(pixels, width, height) {\r\n // https://stackoverflow.com/a/41973289/1324039\r\n const halfHeight = height / 2 | 0; // the | 0 keeps the result an int\r\n const bytesPerRow = width * 4;\r\n // make a temp buffer to hold one row\r\n const temp = new Uint8ClampedArray(width * 4);\r\n const result = pixels.slice(0);\r\n for (let y = 0; y < halfHeight; ++y) {\r\n const topOffset = y * bytesPerRow;\r\n const bottomOffset = (height - y - 1) * bytesPerRow;\r\n\r\n // make copy of a row on the top half\r\n temp.set(result.subarray(topOffset, topOffset + bytesPerRow));\r\n\r\n // copy a row from the bottom half to the top\r\n result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow);\r\n\r\n // copy the copy of the top half row to the bottom half\r\n result.set(temp, bottomOffset);\r\n }\r\n return result;\r\n },\r\n\r\n erectPackedFloat: (array, width) => {\r\n return array.subarray(0, width);\r\n },\r\n erect2DPackedFloat: (array, width, height) => {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xStart = y * width;\r\n const xEnd = xStart + width;\r\n yResults[y] = array.subarray(xStart, xEnd);\r\n }\r\n return yResults;\r\n },\r\n erect3DPackedFloat: (array, width, height, depth) => {\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xStart = (z * height * width) + y * width;\r\n const xEnd = xStart + width;\r\n yResults[y] = array.subarray(xStart, xEnd);\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n },\r\n erectMemoryOptimizedFloat: (array, width) => {\r\n return array.subarray(0, width);\r\n },\r\n erectMemoryOptimized2DFloat,\r\n erectMemoryOptimized3DFloat,\r\n erectFloat: (array, width) => {\r\n const xResults = new Float32Array(width);\r\n let i = 0;\r\n for (let x = 0; x < width; x++) {\r\n xResults[x] = array[i];\r\n i += 4;\r\n }\r\n return xResults;\r\n },\r\n erect2DFloat: (array, width, height) => {\r\n const yResults = new Array(height);\r\n let i = 0;\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Float32Array(width);\r\n for (let x = 0; x < width; x++) {\r\n xResults[x] = array[i];\r\n i += 4;\r\n }\r\n yResults[y] = xResults;\r\n }\r\n return yResults;\r\n },\r\n erect3DFloat: (array, width, height, depth) => {\r\n const zResults = new Array(depth);\r\n let i = 0;\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Float32Array(width);\r\n for (let x = 0; x < width; x++) {\r\n xResults[x] = array[i];\r\n i += 4;\r\n }\r\n yResults[y] = xResults;\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n },\r\n erectArray2: (array, width) => {\r\n const xResults = new Array(width);\r\n const xResultsMax = width * 4;\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x, x + 2);\r\n }\r\n return xResults;\r\n },\r\n erect2DArray2: (array, width, height) => {\r\n const yResults = new Array(height);\r\n const XResultsMax = width * 4;\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = y * XResultsMax;\r\n let i = 0;\r\n for (let x = 0; x < XResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 2);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n return yResults;\r\n },\r\n erect3DArray2: (array, width, height, depth) => {\r\n const xResultsMax = width * 4;\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = (z * xResultsMax * height) + (y * xResultsMax);\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 2);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n },\r\n erectArray3: (array, width) => {\r\n const xResults = new Array(width);\r\n const xResultsMax = width * 4;\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x, x + 3);\r\n }\r\n return xResults;\r\n },\r\n erect2DArray3: (array, width, height) => {\r\n const xResultsMax = width * 4;\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = y * xResultsMax;\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 3);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n return yResults;\r\n },\r\n erect3DArray3: (array, width, height, depth) => {\r\n const xResultsMax = width * 4;\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = (z * xResultsMax * height) + (y * xResultsMax);\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 3);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n },\r\n erectArray4: (array, width) => {\r\n const xResults = new Array(array);\r\n const xResultsMax = width * 4;\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x, x + 4);\r\n }\r\n return xResults;\r\n },\r\n erect2DArray4: (array, width, height) => {\r\n const xResultsMax = width * 4;\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = y * xResultsMax;\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 4);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n return yResults;\r\n },\r\n erect3DArray4: (array, width, height, depth) => {\r\n const xResultsMax = width * 4;\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = (z * xResultsMax * height) + (y * xResultsMax);\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 4);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n },\r\n\r\n /**\r\n * @param {String} source\r\n * @param {Object} settings\r\n * @return {String}\r\n */\r\n flattenFunctionToString: (source, settings) => {\r\n const { findDependency, thisLookup, doNotDefine } = settings;\r\n let flattened = settings.flattened;\r\n if (!flattened) {\r\n flattened = settings.flattened = {};\r\n }\r\n\r\n const ast = parse(source);\r\n const functionDependencies = [];\r\n\r\n function flatten(ast) {\r\n if (Array.isArray(ast)) {\r\n const results = [];\r\n for (let i = 0; i < ast.length; i++) {\r\n results.push(flatten(ast[i]));\r\n }\r\n return results.join('');\r\n }\r\n switch (ast.type) {\r\n case 'Program':\r\n return flatten(ast.body);\r\n case 'FunctionDeclaration':\r\n return `function ${ast.id.name}(${ast.params.map(flatten).join(', ')}) ${ flatten(ast.body) }`;\r\n case 'BlockStatement': {\r\n const result = [];\r\n for (let i = 0; i < ast.body.length; i++) {\r\n result.push(flatten(ast.body[i]), ';\\n');\r\n }\r\n return `{\\n${result.join('')}}`;\r\n }\r\n case 'VariableDeclaration':\r\n switch (ast.declarations[0].id.type) {\r\n case 'ObjectPattern': {\r\n const source = flatten(ast.declarations[0].init);\r\n const properties = ast.declarations.map(declaration => declaration.id.properties.map(flatten))[0];\r\n if (/this/.test(source)) {\r\n const result = [];\r\n const lookups = properties.map(thisLookup);\r\n for (let i = 0; i < lookups.length; i++) {\r\n const lookup = lookups[i];\r\n if (lookup === null) continue;\r\n const property = properties[i];\r\n result.push(`${ast.kind} ${ property } = ${ lookup };\\n`);\r\n }\r\n\r\n return result.join('');\r\n }\r\n return `${ast.kind} { ${properties} } = ${source}`;\r\n }\r\n case 'ArrayPattern':\r\n return `${ast.kind} [ ${ ast.declarations.map(declaration => flatten(declaration.id)).join(', ') } ] = ${flatten(ast.declarations[0].init)}`;\r\n }\r\n if (doNotDefine && doNotDefine.indexOf(ast.declarations[0].id.name) !== -1) {\r\n return '';\r\n }\r\n return `${ast.kind} ${ast.declarations[0].id.name} = ${flatten(ast.declarations[0].init)}`;\r\n case 'CallExpression': {\r\n if (ast.callee.property.name === 'subarray') {\r\n return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n }\r\n if (ast.callee.object.name === 'gl' || ast.callee.object.name === 'context') {\r\n return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n }\r\n if (ast.callee.object.type === 'ThisExpression') {\r\n functionDependencies.push(findDependency('this', ast.callee.property.name));\r\n return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n } else if (ast.callee.object.name) {\r\n const foundSource = findDependency(ast.callee.object.name, ast.callee.property.name);\r\n if (foundSource === null) {\r\n // we're not flattening it\r\n return `${ast.callee.object.name}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n } else {\r\n functionDependencies.push(foundSource);\r\n // we're flattening it\r\n return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n }\r\n } else if (ast.callee.object.type === 'MemberExpression') {\r\n return `${flatten(ast.callee.object)}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n } else {\r\n throw new Error('unknown ast.callee');\r\n }\r\n }\r\n case 'ReturnStatement':\r\n return `return ${flatten(ast.argument)}`;\r\n case 'BinaryExpression':\r\n return `(${flatten(ast.left)}${ast.operator}${flatten(ast.right)})`;\r\n case 'UnaryExpression':\r\n if (ast.prefix) {\r\n return `${ast.operator} ${flatten(ast.argument)}`;\r\n } else {\r\n return `${flatten(ast.argument)} ${ast.operator}`;\r\n }\r\n case 'ExpressionStatement':\r\n return `(${flatten(ast.expression)})`;\r\n case 'ArrowFunctionExpression':\r\n return `(${ast.params.map(flatten).join(', ')}) => ${flatten(ast.body)}`;\r\n case 'Literal':\r\n return ast.raw;\r\n case 'Identifier':\r\n return ast.name;\r\n case 'MemberExpression':\r\n if (ast.object.type === 'ThisExpression') {\r\n return thisLookup(ast.property.name);\r\n }\r\n if (ast.computed) {\r\n return `${flatten(ast.object)}[${flatten(ast.property)}]`;\r\n }\r\n return flatten(ast.object) + '.' + flatten(ast.property);\r\n case 'ThisExpression':\r\n return 'this';\r\n case 'NewExpression':\r\n return `new ${flatten(ast.callee)}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n case 'ForStatement':\r\n return `for (${flatten(ast.init)};${flatten(ast.test)};${flatten(ast.update)}) ${flatten(ast.body)}`;\r\n case 'AssignmentExpression':\r\n return `${flatten(ast.left)}${ast.operator}${flatten(ast.right)}`;\r\n case 'UpdateExpression':\r\n return `${flatten(ast.argument)}${ast.operator}`;\r\n case 'IfStatement':\r\n return `if (${flatten(ast.test)}) ${flatten(ast.consequent)}`;\r\n case 'ThrowStatement':\r\n return `throw ${flatten(ast.argument)}`;\r\n case 'ObjectPattern':\r\n return ast.properties.map(flatten).join(', ');\r\n case 'ArrayPattern':\r\n return ast.elements.map(flatten).join(', ');\r\n case 'DebuggerStatement':\r\n return 'debugger;';\r\n case 'ConditionalExpression':\r\n return `${flatten(ast.test)}?${flatten(ast.consequent)}:${flatten(ast.alternate)}`;\r\n case 'Property':\r\n if (ast.kind === 'init') {\r\n return flatten(ast.key);\r\n }\r\n }\r\n throw new Error(`unhandled ast.type of ${ ast.type }`);\r\n }\r\n const result = flatten(ast);\r\n if (functionDependencies.length > 0) {\r\n const flattenedFunctionDependencies = [];\r\n for (let i = 0; i < functionDependencies.length; i++) {\r\n const functionDependency = functionDependencies[i];\r\n if (!flattened[functionDependency]) {\r\n flattened[functionDependency] = true;\r\n }\r\n flattenedFunctionDependencies.push(utils.flattenFunctionToString(functionDependency, settings) + ';\\n');\r\n }\r\n return flattenedFunctionDependencies.join('') + result;\r\n }\r\n return result;\r\n },\r\n};\r\n\r\nexport { utils };\r\n","import { Input } from '../input';\r\nimport {\r\n functionToIFunction,\r\n getArgumentNamesFromString,\r\n isArray,\r\n isFunctionString,\r\n warnDeprecated\r\n} from '../common';\r\nimport { getVariableType } from '../utils';\r\n\r\nexport class Kernel {\r\n /**\r\n * @type {Boolean}\r\n */\r\n static get isSupported() {\r\n throw new Error(`\"isSupported\" not implemented on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @type {Boolean}\r\n */\r\n static isContextMatch(context) {\r\n throw new Error(`\"isContextMatch\" not implemented on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @type {IKernelFeatures}\r\n * Used internally to populate the kernel.feature, which is a getter for the output of this value\r\n */\r\n static getFeatures() {\r\n throw new Error(`\"getFeatures\" not implemented on ${ this.name }`);\r\n }\r\n\r\n static destroyContext(context) {\r\n throw new Error(`\"destroyContext\" called on ${ this.name }`);\r\n }\r\n\r\n static nativeFunctionArguments() {\r\n throw new Error(`\"nativeFunctionArguments\" called on ${ this.name }`);\r\n }\r\n\r\n static nativeFunctionReturnType() {\r\n throw new Error(`\"nativeFunctionReturnType\" called on ${ this.name }`);\r\n }\r\n\r\n static combineKernels() {\r\n throw new Error(`\"combineKernels\" called on ${ this.name }`);\r\n }\r\n\r\n /**\r\n *\r\n * @param {string|object} source\r\n * @param [settings]\r\n */\r\n constructor(source, settings) {\r\n if (typeof source !== 'object') {\r\n if (typeof source !== 'string') {\r\n throw new Error('source not a string');\r\n }\r\n if (!isFunctionString(source)) {\r\n throw new Error('source not a function string');\r\n }\r\n }\r\n this.useLegacyEncoder = false;\r\n this.fallbackRequested = false;\r\n this.onRequestFallback = null;\r\n\r\n /**\r\n * Name of the arguments found from parsing source argument\r\n * @type {String[]}\r\n */\r\n this.argumentNames = typeof source === 'string' ? getArgumentNamesFromString(source) : null;\r\n this.argumentTypes = null;\r\n this.argumentSizes = null;\r\n this.argumentBitRatios = null;\r\n this.kernelArguments = null;\r\n this.kernelConstants = null;\r\n\r\n\r\n /**\r\n * The function source\r\n * @type {String}\r\n */\r\n this.source = source;\r\n\r\n /**\r\n * The size of the kernel's output\r\n * @type {Number[]}\r\n */\r\n this.output = null;\r\n\r\n /**\r\n * Debug mode\r\n * @type {Boolean}\r\n */\r\n this.debug = false;\r\n\r\n /**\r\n * Graphical mode\r\n * @type {Boolean}\r\n */\r\n this.graphical = false;\r\n\r\n /**\r\n * Maximum loops when using argument values to prevent infinity\r\n * @type {Number}\r\n */\r\n this.loopMaxIterations = 0;\r\n\r\n /**\r\n * Constants used in kernel via `this.constants`\r\n * @type {Object}\r\n */\r\n this.constants = null;\r\n this.constantTypes = null;\r\n this.constantBitRatios = null;\r\n this.dynamicArguments = false;\r\n this.dynamicOutput = false;\r\n\r\n /**\r\n *\r\n * @type {Object}\r\n */\r\n this.canvas = null;\r\n\r\n /**\r\n *\r\n * @type {WebGLRenderingContext}\r\n */\r\n this.context = null;\r\n\r\n /**\r\n *\r\n * @type {Boolean}\r\n */\r\n this.checkContext = null;\r\n\r\n /**\r\n *\r\n * @type {GPU}\r\n */\r\n this.gpu = null;\r\n\r\n /**\r\n *\r\n * @type {IGPUFunction[]}\r\n */\r\n this.functions = null;\r\n\r\n /**\r\n *\r\n * @type {IGPUNativeFunction[]}\r\n */\r\n this.nativeFunctions = null;\r\n\r\n /**\r\n *\r\n * @type {String}\r\n */\r\n this.injectedNative = null;\r\n\r\n /**\r\n *\r\n * @type {ISubKernel[]}\r\n */\r\n this.subKernels = null;\r\n\r\n /**\r\n *\r\n * @type {Boolean}\r\n */\r\n this.validate = true;\r\n\r\n /**\r\n * Enforces kernel to write to a new array or texture on run\r\n * @type {Boolean}\r\n */\r\n this.immutable = false;\r\n\r\n /**\r\n * Enforces kernel to write to a texture on run\r\n * @type {Boolean}\r\n */\r\n this.pipeline = false;\r\n\r\n /**\r\n * Make GPU use single precison or unsigned. Acceptable values: 'single' or 'unsigned'\r\n * @type {String|null}\r\n * @enum 'single' | 'unsigned'\r\n */\r\n this.precision = null;\r\n\r\n /**\r\n *\r\n * @type {String|null}\r\n * @enum 'speed' | 'balanced' | 'precision'\r\n */\r\n this.tactic = 'balanced';\r\n\r\n this.plugins = null;\r\n\r\n this.returnType = null;\r\n this.leadingReturnStatement = null;\r\n this.followingReturnStatement = null;\r\n this.optimizeFloatMemory = null;\r\n this.strictIntegers = false;\r\n this.fixIntegerDivisionAccuracy = null;\r\n this.warnVarUsage = true;\r\n }\r\n\r\n mergeSettings(settings) {\r\n for (let p in settings) {\r\n if (!settings.hasOwnProperty(p) || !this.hasOwnProperty(p)) continue;\r\n switch (p) {\r\n case 'output':\r\n if (!Array.isArray(settings.output)) {\r\n this.setOutput(settings.output); // Flatten output object\r\n continue;\r\n }\r\n break;\r\n case 'functions':\r\n if (typeof settings.functions[0] === 'function') {\r\n this.functions = settings.functions.map(source => functionToIFunction(source));\r\n continue;\r\n }\r\n break;\r\n case 'graphical':\r\n if (settings[p] && !settings.hasOwnProperty('precision')) {\r\n this.precision = 'unsigned';\r\n }\r\n this[p] = settings[p];\r\n continue;\r\n }\r\n this[p] = settings[p];\r\n }\r\n\r\n if (!this.canvas) this.canvas = this.initCanvas();\r\n if (!this.context) this.context = this.initContext();\r\n if (!this.plugins) this.plugins = this.initPlugins(settings);\r\n }\r\n /**\r\n * @desc Builds the Kernel, by compiling Fragment and Vertical Shaders,\r\n * and instantiates the program.\r\n * @abstract\r\n */\r\n build() {\r\n throw new Error(`\"build\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @desc Run the kernel program, and send the output to renderOutput\r\n *

This method calls a helper method *renderOutput* to return the result.

\r\n * @returns {Float32Array|Float32Array[]|Float32Array[][]|void} Result The final output of the program, as float, and as Textures for reuse.\r\n * @abstract\r\n */\r\n run() {\r\n throw new Error(`\"run\" not defined on ${ this.constructor.name }`)\r\n }\r\n\r\n /**\r\n * @abstract\r\n * @return {Object}\r\n */\r\n initCanvas() {\r\n throw new Error(`\"initCanvas\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @abstract\r\n * @return {Object}\r\n */\r\n initContext() {\r\n throw new Error(`\"initContext\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @param {IFunctionSettings} settings\r\n * @return {Object};\r\n * @abstract\r\n */\r\n initPlugins(settings) {\r\n throw new Error(`\"initPlugins\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @desc Setup the parameter types for the parameters\r\n * supplied to the Kernel function\r\n *\r\n * @param {IArguments} args - The actual parameters sent to the Kernel\r\n */\r\n setupArguments(args) {\r\n this.kernelArguments = [];\r\n if (!this.argumentTypes) {\r\n if (!this.argumentTypes) {\r\n this.argumentTypes = [];\r\n for (let i = 0; i < args.length; i++) {\r\n const argType = getVariableType(args[i], this.strictIntegers);\r\n const type = argType === 'Integer' ? 'Number' : argType;\r\n this.argumentTypes.push(type);\r\n this.kernelArguments.push({\r\n type\r\n });\r\n }\r\n }\r\n } else {\r\n for (let i = 0; i < this.argumentTypes.length; i++) {\r\n this.kernelArguments.push({\r\n type: this.argumentTypes[i]\r\n });\r\n }\r\n }\r\n\r\n // setup sizes\r\n this.argumentSizes = new Array(args.length);\r\n this.argumentBitRatios = new Int32Array(args.length);\r\n\r\n for (let i = 0; i < args.length; i++) {\r\n const arg = args[i];\r\n this.argumentSizes[i] = arg.constructor === Input ? arg.size : null;\r\n this.argumentBitRatios[i] = this.getBitRatio(arg);\r\n }\r\n\r\n if (this.argumentNames.length !== args.length) {\r\n throw new Error(`arguments are miss-aligned`);\r\n }\r\n }\r\n\r\n /**\r\n * Setup constants\r\n */\r\n setupConstants() {\r\n this.kernelConstants = [];\r\n let needsConstantTypes = this.constantTypes === null;\r\n if (needsConstantTypes) {\r\n this.constantTypes = {};\r\n }\r\n this.constantBitRatios = {};\r\n if (this.constants) {\r\n for (let name in this.constants) {\r\n if (needsConstantTypes) {\r\n const type = getVariableType(this.constants[name], this.strictIntegers);\r\n this.constantTypes[name] = type;\r\n this.kernelConstants.push({\r\n name,\r\n type\r\n });\r\n } else {\r\n this.kernelConstants.push({\r\n name,\r\n type: this.constantTypes[name]\r\n });\r\n }\r\n this.constantBitRatios[name] = this.getBitRatio(this.constants[name]);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setOptimizeFloatMemory(flag) {\r\n this.optimizeFloatMemory = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Set output dimensions of the kernel function\r\n * @param {Array|Object} output - The output array to set the kernel output size to\r\n */\r\n setOutput(output) {\r\n if (output.hasOwnProperty('x')) {\r\n if (output.hasOwnProperty('y')) {\r\n if (output.hasOwnProperty('z')) {\r\n this.output = [output.x, output.y, output.z];\r\n } else {\r\n this.output = [output.x, output.y];\r\n }\r\n } else {\r\n this.output = [output.x];\r\n }\r\n } else {\r\n this.output = output;\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Toggle debug mode\r\n * @param {Boolean} flag - true to enable debug\r\n */\r\n setDebug(flag) {\r\n this.debug = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Toggle graphical output mode\r\n * @param {Boolean} flag - true to enable graphical output\r\n */\r\n setGraphical(flag) {\r\n this.graphical = flag;\r\n this.precision = 'unsigned';\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Set the maximum number of loop iterations\r\n * @param {number} max - iterations count\r\n *\r\n */\r\n setLoopMaxIterations(max) {\r\n this.loopMaxIterations = max;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Set Constants\r\n */\r\n setConstants(constants) {\r\n this.constants = constants;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param [IKernelValueTypes] constantTypes\r\n * @return {Kernel}\r\n */\r\n setConstantTypes(constantTypes) {\r\n this.constantTypes = constantTypes;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param {IFunction[]|KernelFunction[]} functions\r\n * @return {Kernel}\r\n */\r\n setFunctions(functions) {\r\n if (typeof functions[0] === 'function') {\r\n this.functions = functions.map(source => functionToIFunction(source));\r\n } else {\r\n this.functions = functions;\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param {IGPUNativeFunction} nativeFunctions\r\n * @return {Kernel}\r\n */\r\n setNativeFunctions(nativeFunctions) {\r\n this.nativeFunctions = nativeFunctions;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param {String} injectedNative\r\n * @return {Kernel}\r\n */\r\n setInjectedNative(injectedNative) {\r\n this.injectedNative = injectedNative;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set writing to texture on/off\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setPipeline(flag) {\r\n this.pipeline = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set precision to 'unsigned' or 'single'\r\n * @param {String} flag 'unsigned' or 'single'\r\n * @return {Kernel}\r\n */\r\n setPrecision(flag) {\r\n this.precision = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param flag\r\n * @return {Kernel}\r\n * @deprecated\r\n */\r\n setOutputToTexture(flag) {\r\n warnDeprecated('method', 'setOutputToTexture', 'setPipeline');\r\n this.pipeline = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set to immutable\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setImmutable(flag) {\r\n this.immutable = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Bind the canvas to kernel\r\n * @param {Object} canvas\r\n */\r\n setCanvas(canvas) {\r\n this.canvas = canvas;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param {Boolean} flag\r\n * @return {Kernel}\r\n */\r\n setStrictIntegers(flag) {\r\n this.strictIntegers = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setDynamicOutput(flag) {\r\n this.dynamicOutput = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @deprecated\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setHardcodeConstants(flag) {\r\n warnDeprecated('method', 'setHardcodeConstants');\r\n this.setDynamicOutput(flag);\r\n this.setDynamicArguments(flag);\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setDynamicArguments(flag) {\r\n this.dynamicArguments = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param {Boolean} flag\r\n * @return {Kernel}\r\n */\r\n setUseLegacyEncoder(flag) {\r\n this.useLegacyEncoder = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Boolean} flag\r\n * @return {Kernel}\r\n */\r\n setWarnVarUsage(flag) {\r\n this.warnVarUsage = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @deprecated\r\n * @returns {Object}\r\n */\r\n getCanvas() {\r\n warnDeprecated('method', 'getCanvas');\r\n return this.canvas;\r\n }\r\n\r\n /**\r\n * @deprecated\r\n * @returns {Object}\r\n */\r\n getWebGl() {\r\n warnDeprecated('method', 'getWebGl');\r\n return this.context;\r\n }\r\n\r\n /**\r\n * @desc Bind the webGL instance to kernel\r\n * @param {WebGLRenderingContext} context - webGl instance to bind\r\n */\r\n setContext(context) {\r\n this.context = context;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param [IKernelValueTypes|GPUVariableType[]] argumentTypes\r\n * @return {Kernel}\r\n */\r\n setArgumentTypes(argumentTypes) {\r\n if (Array.isArray(argumentTypes)) {\r\n this.argumentTypes = argumentTypes;\r\n } else {\r\n this.argumentTypes = [];\r\n for (const p in argumentTypes) {\r\n const argumentIndex = this.argumentNames.indexOf(p);\r\n if (argumentIndex === -1) throw new Error(`unable to find argument ${ p }`);\r\n this.argumentTypes[argumentIndex] = argumentTypes[p];\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param [Tactic] tactic\r\n * @return {Kernel}\r\n */\r\n setTactic(tactic) {\r\n this.tactic = tactic;\r\n return this;\r\n }\r\n\r\n requestFallback(args) {\r\n if (!this.onRequestFallback) {\r\n throw new Error(`\"onRequestFallback\" not defined on ${ this.constructor.name }`);\r\n }\r\n this.fallbackRequested = true;\r\n return this.onRequestFallback(args);\r\n }\r\n\r\n /**\r\n * @desc Validate settings\r\n * @abstract\r\n */\r\n validateSettings() {\r\n throw new Error(`\"validateSettings\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @desc Add a sub kernel to the root kernel instance.\r\n * This is what `createKernelMap` uses.\r\n *\r\n * @param {ISubKernel} subKernel - function (as a String) of the subKernel to add\r\n */\r\n addSubKernel(subKernel) {\r\n if (this.subKernels === null) {\r\n this.subKernels = [];\r\n }\r\n if (!subKernel.source) throw new Error('subKernel missing \"source\" property');\r\n if (!subKernel.property && isNaN(subKernel.property)) throw new Error('subKernel missing \"property\" property');\r\n if (!subKernel.name) throw new Error('subKernel missing \"name\" property');\r\n this.subKernels.push(subKernel);\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Destroys all memory associated with this kernel\r\n * @param {Boolean} [removeCanvasReferences] remove any associated canvas references\r\n */\r\n destroy(removeCanvasReferences) {\r\n throw new Error(`\"destroy\" called on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * bit storage ratio of source to target 'buffer', i.e. if 8bit array -> 32bit tex = 4\r\n * @param value\r\n * @returns {number}\r\n */\r\n getBitRatio(value) {\r\n if (this.precision === 'single') {\r\n // 8 and 16 are upconverted to float32\r\n return 4;\r\n } else if (Array.isArray(value[0])) {\r\n return this.getBitRatio(value[0]);\r\n } else if (value.constructor === Input) {\r\n return this.getBitRatio(value.value);\r\n }\r\n switch (value.constructor) {\r\n case Uint8ClampedArray:\r\n case Uint8Array:\r\n case Int8Array:\r\n return 1;\r\n case Uint16Array:\r\n case Int16Array:\r\n return 2;\r\n case Float32Array:\r\n case Int32Array:\r\n default:\r\n return 4;\r\n }\r\n }\r\n\r\n /**\r\n * @returns {number[]}\r\n */\r\n getPixels() {\r\n throw new Error(`\"getPixels\" called on ${ this.constructor.name }`);\r\n }\r\n\r\n checkOutput() {\r\n if (!this.output || !isArray(this.output)) throw new Error('kernel.output not an array');\r\n if (this.output.length < 1) throw new Error('kernel.output is empty, needs at least 1 value');\r\n for (let i = 0; i < this.output.length; i++) {\r\n if (isNaN(this.output[i]) || this.output[i] < 1) {\r\n throw new Error(`${ this.constructor.name }.output[${ i }] incorrectly defined as \\`${ this.output[i] }\\`, needs to be numeric, and greater than 0`);\r\n }\r\n }\r\n }\r\n\r\n toJSON() {\r\n const settings = {\r\n output: this.output,\r\n threadDim: this.threadDim,\r\n pipeline: this.pipeline,\r\n argumentNames: this.argumentNames,\r\n argumentsTypes: this.argumentTypes,\r\n constants: this.constants,\r\n pluginNames: this.plugins ? this.plugins.map(plugin => plugin.name) : null,\r\n returnType: this.returnType,\r\n };\r\n return {\r\n settings\r\n };\r\n }\r\n}\r\n","/**\r\n * @desc This handles all the raw state, converted state, etc. of a single function.\r\n * [INTERNAL] A collection of functionNodes.\r\n * @class\r\n */\r\nexport class FunctionBuilder {\r\n /**\r\n *\r\n * @param {Kernel} kernel\r\n * @param {FunctionNode} FunctionNode\r\n * @param {object} [extraNodeOptions]\r\n * @returns {FunctionBuilder}\r\n * @static\r\n */\r\n static fromKernel(kernel, FunctionNode, extraNodeOptions) {\r\n const {\r\n kernelArguments,\r\n kernelConstants,\r\n argumentNames,\r\n argumentSizes,\r\n argumentBitRatios,\r\n constants,\r\n constantBitRatios,\r\n debug,\r\n loopMaxIterations,\r\n nativeFunctions,\r\n output,\r\n optimizeFloatMemory,\r\n precision,\r\n plugins,\r\n source,\r\n subKernels,\r\n functions,\r\n leadingReturnStatement,\r\n followingReturnStatement,\r\n dynamicArguments,\r\n dynamicOutput,\r\n warnVarUsage,\r\n } = kernel;\r\n\r\n const argumentTypes = new Array(kernelArguments.length);\r\n const constantTypes = {};\r\n\r\n for (let i = 0; i < kernelArguments.length; i++) {\r\n argumentTypes[i] = kernelArguments[i].type;\r\n }\r\n\r\n for (let i = 0; i < kernelConstants.length; i++) {\r\n const kernelConstant = kernelConstants[i]\r\n constantTypes[kernelConstant.name] = kernelConstant.type;\r\n }\r\n\r\n const needsArgumentType = (functionName, index) => {\r\n return functionBuilder.needsArgumentType(functionName, index);\r\n };\r\n\r\n const assignArgumentType = (functionName, index, type) => {\r\n functionBuilder.assignArgumentType(functionName, index, type);\r\n };\r\n\r\n const lookupReturnType = (functionName, ast, requestingNode) => {\r\n return functionBuilder.lookupReturnType(functionName, ast, requestingNode);\r\n };\r\n\r\n const lookupFunctionArgumentTypes = (functionName) => {\r\n return functionBuilder.lookupFunctionArgumentTypes(functionName);\r\n };\r\n\r\n const lookupFunctionArgumentName = (functionName, argumentIndex) => {\r\n return functionBuilder.lookupFunctionArgumentName(functionName, argumentIndex);\r\n };\r\n\r\n const lookupFunctionArgumentBitRatio = (functionName, argumentName) => {\r\n return functionBuilder.lookupFunctionArgumentBitRatio(functionName, argumentName);\r\n };\r\n\r\n const triggerImplyArgumentType = (functionName, i, argumentType, requestingNode) => {\r\n functionBuilder.assignArgumentType(functionName, i, argumentType, requestingNode);\r\n };\r\n\r\n const triggerTrackArgumentSynonym = (functionName, argumentName, calleeFunctionName, argumentIndex) => {\r\n functionBuilder.trackArgumentSynonym(functionName, argumentName, calleeFunctionName, argumentIndex);\r\n };\r\n\r\n const lookupArgumentSynonym = (originFunctionName, functionName, argumentName) => {\r\n return functionBuilder.lookupArgumentSynonym(originFunctionName, functionName, argumentName);\r\n };\r\n\r\n const onFunctionCall = (functionName, calleeFunctionName, args) => {\r\n functionBuilder.trackFunctionCall(functionName, calleeFunctionName, args);\r\n };\r\n\r\n const onNestedFunction = (ast, returnType) => {\r\n const argumentNames = [];\r\n for (let i = 0; i < ast.params.length; i++) {\r\n argumentNames.push(ast.params[i].name);\r\n }\r\n const nestedFunction = new FunctionNode(null, Object.assign({}, nodeOptions, {\r\n returnType: null,\r\n ast,\r\n name: ast.id.name,\r\n argumentNames,\r\n lookupReturnType,\r\n lookupFunctionArgumentTypes,\r\n lookupFunctionArgumentName,\r\n lookupFunctionArgumentBitRatio,\r\n needsArgumentType,\r\n assignArgumentType,\r\n triggerImplyArgumentType,\r\n triggerTrackArgumentSynonym,\r\n lookupArgumentSynonym,\r\n onFunctionCall,\r\n warnVarUsage,\r\n }));\r\n nestedFunction.traceFunctionAST(ast);\r\n functionBuilder.addFunctionNode(nestedFunction);\r\n };\r\n\r\n const nodeOptions = Object.assign({\r\n isRootKernel: false,\r\n onNestedFunction,\r\n lookupReturnType,\r\n lookupFunctionArgumentTypes,\r\n lookupFunctionArgumentName,\r\n lookupFunctionArgumentBitRatio,\r\n needsArgumentType,\r\n assignArgumentType,\r\n triggerImplyArgumentType,\r\n triggerTrackArgumentSynonym,\r\n lookupArgumentSynonym,\r\n onFunctionCall,\r\n optimizeFloatMemory,\r\n precision,\r\n constants,\r\n constantTypes,\r\n constantBitRatios,\r\n debug,\r\n loopMaxIterations,\r\n output,\r\n plugins,\r\n dynamicArguments,\r\n dynamicOutput,\r\n }, extraNodeOptions || {});\r\n\r\n const rootNodeOptions = Object.assign({}, nodeOptions, {\r\n isRootKernel: true,\r\n name: 'kernel',\r\n argumentNames,\r\n argumentTypes,\r\n argumentSizes,\r\n argumentBitRatios,\r\n leadingReturnStatement,\r\n followingReturnStatement,\r\n });\r\n\r\n if (typeof source === 'object' && source.functionNodes) {\r\n return new FunctionBuilder().fromJSON(source.functionNodes, FunctionNode);\r\n }\r\n\r\n const rootNode = new FunctionNode(source, rootNodeOptions);\r\n\r\n let functionNodes = null;\r\n if (functions) {\r\n functionNodes = functions.map((fn) => new FunctionNode(fn.source, {\r\n returnType: fn.returnType,\r\n argumentTypes: fn.argumentTypes,\r\n output,\r\n plugins,\r\n constants,\r\n constantTypes,\r\n constantBitRatios,\r\n optimizeFloatMemory,\r\n precision,\r\n lookupReturnType,\r\n lookupFunctionArgumentTypes,\r\n lookupFunctionArgumentName,\r\n lookupFunctionArgumentBitRatio,\r\n needsArgumentType,\r\n assignArgumentType,\r\n triggerImplyArgumentType,\r\n triggerTrackArgumentSynonym,\r\n lookupArgumentSynonym,\r\n onFunctionCall,\r\n }));\r\n }\r\n\r\n let subKernelNodes = null;\r\n if (subKernels) {\r\n subKernelNodes = subKernels.map((subKernel) => {\r\n const { name, source } = subKernel;\r\n return new FunctionNode(source, Object.assign({}, nodeOptions, {\r\n name,\r\n isSubKernel: true,\r\n isRootKernel: false,\r\n }));\r\n });\r\n }\r\n\r\n const functionBuilder = new FunctionBuilder({\r\n kernel,\r\n rootNode,\r\n functionNodes,\r\n nativeFunctions,\r\n subKernelNodes\r\n });\r\n\r\n return functionBuilder;\r\n }\r\n\r\n /**\r\n *\r\n * @param {IFunctionBuilderSettings} [settings]\r\n */\r\n constructor(settings) {\r\n settings = settings || {};\r\n this.kernel = settings.kernel;\r\n this.rootNode = settings.rootNode;\r\n this.functionNodes = settings.functionNodes || [];\r\n this.subKernelNodes = settings.subKernelNodes || [];\r\n this.nativeFunctions = settings.nativeFunctions || [];\r\n this.functionMap = {};\r\n this.nativeFunctionNames = [];\r\n this.lookupChain = [];\r\n this.argumentChain = [];\r\n this.functionNodeDependencies = {};\r\n this.functionCalls = {};\r\n\r\n if (this.rootNode) {\r\n this.functionMap['kernel'] = this.rootNode;\r\n }\r\n\r\n if (this.functionNodes) {\r\n for (let i = 0; i < this.functionNodes.length; i++) {\r\n this.functionMap[this.functionNodes[i].name] = this.functionNodes[i];\r\n }\r\n }\r\n\r\n if (this.subKernelNodes) {\r\n for (let i = 0; i < this.subKernelNodes.length; i++) {\r\n this.functionMap[this.subKernelNodes[i].name] = this.subKernelNodes[i];\r\n }\r\n }\r\n\r\n if (this.nativeFunctions) {\r\n for (let i = 0; i < this.nativeFunctions.length; i++) {\r\n const nativeFunction = this.nativeFunctions[i];\r\n this.nativeFunctionNames.push(nativeFunction.name);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @desc Add the function node directly\r\n *\r\n * @param {FunctionNode} functionNode - functionNode to add\r\n *\r\n */\r\n addFunctionNode(functionNode) {\r\n if (!functionNode.name) throw new Error('functionNode.name needs set');\r\n this.functionMap[functionNode.name] = functionNode;\r\n if (functionNode.isRootKernel) {\r\n this.rootNode = functionNode;\r\n }\r\n }\r\n\r\n /**\r\n * @desc Trace all the depending functions being called, from a single function\r\n *\r\n * This allow for 'unneeded' functions to be automatically optimized out.\r\n * Note that the 0-index, is the starting function trace.\r\n *\r\n * @param {String} functionName - Function name to trace from, default to 'kernel'\r\n * @param {String[]} [retList] - Returning list of function names that is traced. Including itself.\r\n *\r\n * @returns {String[]} Returning list of function names that is traced. Including itself.\r\n */\r\n traceFunctionCalls(functionName, retList) {\r\n functionName = functionName || 'kernel';\r\n retList = retList || [];\r\n\r\n if (this.nativeFunctionNames.indexOf(functionName) > -1) {\r\n if (retList.indexOf(functionName) === -1) {\r\n retList.push(functionName);\r\n }\r\n return retList;\r\n }\r\n\r\n const functionNode = this.functionMap[functionName];\r\n if (functionNode) {\r\n // Check if function already exists\r\n const functionIndex = retList.indexOf(functionName);\r\n if (functionIndex === -1) {\r\n retList.push(functionName);\r\n functionNode.toString(); //ensure JS trace is done\r\n for (let i = 0; i < functionNode.calledFunctions.length; ++i) {\r\n this.traceFunctionCalls(functionNode.calledFunctions[i], retList);\r\n }\r\n } else {\r\n /**\r\n * https://github.com/gpujs/gpu.js/issues/207\r\n * if dependent function is already in the list, because a function depends on it, and because it has\r\n * already been traced, we know that we must move the dependent function to the end of the the retList.\r\n * */\r\n const dependantFunctionName = retList.splice(functionIndex, 1)[0];\r\n retList.push(dependantFunctionName);\r\n }\r\n }\r\n\r\n return retList;\r\n }\r\n\r\n /**\r\n * @desc Return the string for a function\r\n * @param {String} functionName - Function name to trace from. If null, it returns the WHOLE builder stack\r\n * @returns {String} The full string, of all the various functions. Trace optimized if functionName given\r\n */\r\n getPrototypeString(functionName) {\r\n return this.getPrototypes(functionName).join('\\n');\r\n }\r\n\r\n /**\r\n * @desc Return the string for a function\r\n * @param {String} [functionName] - Function name to trace from. If null, it returns the WHOLE builder stack\r\n * @returns {Array} The full string, of all the various functions. Trace optimized if functionName given\r\n */\r\n getPrototypes(functionName) {\r\n if (this.rootNode) {\r\n this.rootNode.toString();\r\n }\r\n if (functionName) {\r\n return this.getPrototypesFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse());\r\n }\r\n return this.getPrototypesFromFunctionNames(Object.keys(this.functionMap));\r\n }\r\n\r\n /**\r\n * @desc Get string from function names\r\n * @param {String[]} functionList - List of function to build string\r\n * @returns {String} The string, of all the various functions. Trace optimized if functionName given\r\n */\r\n getStringFromFunctionNames(functionList) {\r\n const ret = [];\r\n for (let i = 0; i < functionList.length; ++i) {\r\n const node = this.functionMap[functionList[i]];\r\n if (node) {\r\n ret.push(this.functionMap[functionList[i]].toString());\r\n }\r\n }\r\n return ret.join('\\n');\r\n }\r\n\r\n /**\r\n * @desc Return string of all functions converted\r\n * @param {String[]} functionList - List of function names to build the string.\r\n * @returns {Array} Prototypes of all functions converted\r\n */\r\n getPrototypesFromFunctionNames(functionList) {\r\n const ret = [];\r\n for (let i = 0; i < functionList.length; ++i) {\r\n const functionName = functionList[i];\r\n const functionIndex = this.nativeFunctionNames.indexOf(functionName);\r\n if (functionIndex > -1) {\r\n ret.push(this.nativeFunctions[functionIndex].source);\r\n continue;\r\n }\r\n const node = this.functionMap[functionName];\r\n if (node) {\r\n ret.push(node.toString());\r\n }\r\n }\r\n return ret;\r\n }\r\n\r\n toJSON() {\r\n return this.traceFunctionCalls(this.rootNode.name).reverse().map(name => {\r\n const nativeIndex = this.nativeFunctions.indexOf(name);\r\n if (nativeIndex > -1) {\r\n return {\r\n name,\r\n source: this.nativeFunctions[nativeIndex].source\r\n };\r\n } else if (this.functionMap[name]) {\r\n return this.functionMap[name].toJSON();\r\n } else {\r\n throw new Error(`function ${ name } not found`);\r\n }\r\n });\r\n }\r\n\r\n fromJSON(jsonFunctionNodes, FunctionNode) {\r\n this.functionMap = {};\r\n for (let i = 0; i < jsonFunctionNodes.length; i++) {\r\n const jsonFunctionNode = jsonFunctionNodes[i];\r\n this.functionMap[jsonFunctionNode.settings.name] = new FunctionNode(jsonFunctionNode.ast, jsonFunctionNode.settings);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Get string for a particular function name\r\n * @param {String} functionName - Function name to trace from. If null, it returns the WHOLE builder stack\r\n * @returns {String} settings - The string, of all the various functions. Trace optimized if functionName given\r\n */\r\n getString(functionName) {\r\n if (functionName) {\r\n return this.getStringFromFunctionNames(this.traceFunctionCalls(functionName).reverse());\r\n }\r\n return this.getStringFromFunctionNames(Object.keys(this.functionMap));\r\n }\r\n\r\n lookupReturnType(functionName, ast, requestingNode) {\r\n if (ast.type !== 'CallExpression') {\r\n throw new Error(`expected ast type of \"CallExpression\", but is ${ ast.type }`);\r\n }\r\n if (this._isNativeFunction(functionName)) {\r\n return this._lookupNativeFunctionReturnType(functionName);\r\n } else if (this._isFunction(functionName)) {\r\n const node = this._getFunction(functionName);\r\n if (node.returnType) {\r\n return node.returnType;\r\n } else {\r\n for (let i = 0; i < this.lookupChain.length; i++) {\r\n // detect circlical logic\r\n if (this.lookupChain[i].ast === ast) {\r\n // detect if arguments have not resolved, preventing a return type\r\n // if so, go ahead and resolve them, so we can resolve the return type\r\n if (node.argumentTypes.length === 0 && ast.arguments.length > 0) {\r\n const args = ast.arguments;\r\n for (let j = 0; j < args.length; j++) {\r\n this.lookupChain.push({\r\n name: requestingNode.name,\r\n ast: args[i],\r\n requestingNode\r\n });\r\n node.argumentTypes[j] = requestingNode.getType(args[j]);\r\n this.lookupChain.pop();\r\n }\r\n return node.returnType = node.getType(node.getJsAST());\r\n }\r\n\r\n throw new Error('circlical logic detected!');\r\n }\r\n }\r\n // get ready for a ride!\r\n this.lookupChain.push({\r\n name: requestingNode.name,\r\n ast,\r\n requestingNode\r\n });\r\n const type = node.getType(node.getJsAST());\r\n this.lookupChain.pop();\r\n return node.returnType = type;\r\n }\r\n }\r\n\r\n // function not found, maybe native?\r\n return null;\r\n\r\n /**\r\n * first iteration\r\n * kernel.outputs = Array\r\n * kernel.targets = Array\r\n * kernel.returns = null\r\n * kernel.calls.calcErrorOutput = [kernel.output, kernel.targets]\r\n * kernel.calls.calcDeltas = [calcErrorOutput.returns, kernel.output]\r\n * calcErrorOutput.output = null\r\n * calcErrorOutput.targets = null\r\n * calcErrorOutput.returns = null\r\n * calcDeltasSigmoid.error = null\r\n * calcDeltasSigmoid.output = Number\r\n * calcDeltasSigmoid.returns = null\r\n *\r\n * resolvable are:\r\n * calcErrorOutput.output\r\n * calcErrorOutput.targets\r\n * calcErrorOutput.returns\r\n *\r\n * second iteration\r\n * kernel.outputs = Array\r\n * kernel.targets = Array\r\n * kernel.returns = null\r\n * kernel.calls.calcErrorOutput = [kernel.output, kernel.targets]\r\n * kernel.calls.calcDeltas = [calcErrorOutput.returns, kernel.output]\r\n * calcErrorOutput.output = Number\r\n * calcErrorOutput.targets = Array\r\n * calcErrorOutput.returns = Number\r\n * calcDeltasSigmoid.error = null\r\n * calcDeltasSigmoid.output = Number\r\n * calcDeltasSigmoid.returns = null\r\n *\r\n * resolvable are:\r\n * calcDeltasSigmoid.error\r\n * calcDeltasSigmoid.returns\r\n * kernel.returns\r\n *\r\n * third iteration\r\n * kernel.outputs = Array\r\n * kernel.targets = Array\r\n * kernel.returns = Number\r\n * kernel.calls.calcErrorOutput = [kernel.output, kernel.targets]\r\n * kernel.calls.calcDeltas = [calcErrorOutput.returns, kernel.output]\r\n * calcErrorOutput.output = Number\r\n * calcErrorOutput.targets = Array\r\n * calcErrorOutput.returns = Number\r\n * calcDeltasSigmoid.error = Number\r\n * calcDeltasSigmoid.output = Number\r\n * calcDeltasSigmoid.returns = Number\r\n *\r\n *\r\n */\r\n }\r\n\r\n _getFunction(functionName) {\r\n if (!this._isFunction(functionName)) {\r\n new Error(`Function ${functionName} not found`);\r\n }\r\n return this.functionMap[functionName];\r\n }\r\n\r\n _isFunction(functionName) {\r\n return Boolean(this.functionMap[functionName]);\r\n }\r\n\r\n _getNativeFunction(functionName) {\r\n for (let i = 0; i < this.nativeFunctions.length; i++) {\r\n if (this.nativeFunctions[i].name === functionName) return this.nativeFunctions[i];\r\n }\r\n return null;\r\n }\r\n\r\n _isNativeFunction(functionName) {\r\n return Boolean(this._getNativeFunction(functionName));\r\n }\r\n\r\n _lookupNativeFunctionReturnType(functionName) {\r\n let nativeFunction = this._getNativeFunction(functionName);\r\n if (nativeFunction) {\r\n return nativeFunction.returnType;\r\n }\r\n throw new Error(`Native function ${ functionName } not found`);\r\n }\r\n\r\n lookupFunctionArgumentTypes(functionName) {\r\n if (this._isNativeFunction(functionName)) {\r\n return this._getNativeFunction(functionName).argumentTypes;\r\n } else if (this._isFunction(functionName)) {\r\n return this._getFunction(functionName).argumentTypes;\r\n }\r\n return null;\r\n }\r\n\r\n lookupFunctionArgumentName(functionName, argumentIndex) {\r\n return this._getFunction(functionName).argumentNames[argumentIndex];\r\n }\r\n\r\n lookupFunctionArgumentBitRatio(functionName, argumentName) {\r\n if (!this._isFunction(functionName)) {\r\n throw new Error('function not found');\r\n }\r\n if (this.rootNode.name === functionName) {\r\n const i = this.rootNode.argumentNames.indexOf(argumentName);\r\n if (i !== -1) {\r\n return this.rootNode.argumentBitRatios[i];\r\n } else {\r\n throw new Error('argument bit ratio not found');\r\n }\r\n } else {\r\n const node = this._getFunction(functionName);\r\n const argumentSynonym = node.argumentSynonym[node.synonymIndex];\r\n if (!argumentSynonym) {\r\n throw new Error('argument synonym not found');\r\n }\r\n return this.lookupFunctionArgumentBitRatio(argumentSynonym.functionName, argumentSynonym.argumentName);\r\n }\r\n }\r\n\r\n needsArgumentType(functionName, i) {\r\n if (!this._isFunction(functionName)) return false;\r\n const fnNode = this._getFunction(functionName);\r\n return !fnNode.argumentTypes[i];\r\n }\r\n\r\n assignArgumentType(functionName, i, argumentType, requestingNode) {\r\n if (!this._isFunction(functionName)) return;\r\n const fnNode = this._getFunction(functionName);\r\n if (!fnNode.argumentTypes[i]) {\r\n fnNode.argumentTypes[i] = argumentType;\r\n }\r\n }\r\n\r\n trackArgumentSynonym(functionName, argumentName, calleeFunctionName, argumentIndex) {\r\n if (!this._isFunction(calleeFunctionName)) return;\r\n const node = this._getFunction(calleeFunctionName);\r\n if (!node.argumentSynonym) {\r\n node.argumentSynonym = {};\r\n }\r\n const calleeArgumentName = node.argumentNames[argumentIndex];\r\n if (!node.argumentSynonym[calleeArgumentName]) {\r\n node.argumentSynonym[calleeArgumentName] = {};\r\n }\r\n node.synonymIndex++;\r\n node.argumentSynonym[node.synonymIndex] = {\r\n functionName,\r\n argumentName,\r\n calleeArgumentName,\r\n calleeFunctionName,\r\n };\r\n }\r\n\r\n lookupArgumentSynonym(originFunctionName, functionName, argumentName) {\r\n if (originFunctionName === functionName) return argumentName;\r\n if (!this._isFunction(functionName)) return null;\r\n const node = this._getFunction(functionName);\r\n const argumentSynonym = node.argumentSynonym[node.synonymUseIndex];\r\n if (!argumentSynonym) return null;\r\n if (argumentSynonym.calleeArgumentName !== argumentName) return null;\r\n node.synonymUseIndex++;\r\n if (originFunctionName !== functionName) {\r\n return this.lookupArgumentSynonym(originFunctionName, argumentSynonym.functionName, argumentSynonym.argumentName);\r\n }\r\n return argumentSynonym.argumentName;\r\n }\r\n\r\n trackFunctionCall(functionName, calleeFunctionName, args) {\r\n if (!this.functionNodeDependencies[functionName]) {\r\n this.functionNodeDependencies[functionName] = new Set();\r\n this.functionCalls[functionName] = [];\r\n }\r\n this.functionNodeDependencies[functionName].add(calleeFunctionName);\r\n this.functionCalls[functionName].push(args);\r\n }\r\n\r\n getKernelResultType() {\r\n return this.rootNode.returnType || this.rootNode.getType(this.rootNode.ast);\r\n }\r\n\r\n getSubKernelResultType(index) {\r\n const subKernelNode = this.subKernelNodes[index];\r\n let called = false;\r\n for (let functionCallIndex = 0; functionCallIndex < this.rootNode.functionCalls.length; functionCallIndex++) {\r\n const functionCall = this.rootNode.functionCalls[functionCallIndex];\r\n if (functionCall.ast.callee.name === subKernelNode.name) {\r\n called = true;\r\n }\r\n }\r\n if (!called) {\r\n throw new Error(`SubKernel ${ subKernelNode.name } never called by kernel`);\r\n }\r\n return subKernelNode.returnType || subKernelNode.getType(subKernelNode.getJsAST());\r\n }\r\n\r\n getReturnTypes() {\r\n const result = {\r\n [this.rootNode.name]: this.rootNode.getType(this.rootNode.ast),\r\n };\r\n const list = this.traceFunctionCalls(this.rootNode.name);\r\n for (let i = 0; i < list.length; i++) {\r\n const functionName = list[i];\r\n const functionNode = this.functionMap[functionName];\r\n result[functionName] = functionNode.getType(functionNode.ast);\r\n }\r\n return result;\r\n }\r\n}\r\n","export class FunctionTracer {\r\n constructor(ast) {\r\n this.runningContexts = [];\r\n this.contexts = [];\r\n this.functionCalls = [];\r\n this.declarations = [];\r\n this.identifiers = [];\r\n this.functions = [];\r\n this.returnStatements = [];\r\n this.inLoopInit = false;\r\n this.scan(ast);\r\n }\r\n\r\n get currentContext() {\r\n return this.runningContexts.length > 0 ? this.runningContexts[this.runningContexts.length - 1] : null;\r\n }\r\n\r\n newContext(run) {\r\n const newContext = Object.assign({}, this.currentContext);\r\n this.contexts.push(newContext);\r\n this.runningContexts.push(newContext);\r\n run();\r\n this.runningContexts.pop();\r\n }\r\n\r\n /**\r\n * Recursively scans AST for declarations and functions, and add them to their respective context\r\n * @param ast\r\n */\r\n scan(ast) {\r\n if (Array.isArray(ast)) {\r\n for (let i = 0; i < ast.length; i++) {\r\n this.scan(ast[i]);\r\n }\r\n return;\r\n }\r\n switch (ast.type) {\r\n case 'Program':\r\n this.scan(ast.body);\r\n break;\r\n case 'BlockStatement':\r\n this.newContext(() => {\r\n this.scan(ast.body);\r\n });\r\n break;\r\n case 'AssignmentExpression':\r\n case 'LogicalExpression':\r\n this.scan(ast.left);\r\n this.scan(ast.right);\r\n break;\r\n case 'BinaryExpression':\r\n this.scan(ast.left);\r\n this.scan(ast.right);\r\n break;\r\n case 'UpdateExpression':\r\n case 'UnaryExpression':\r\n this.scan(ast.argument);\r\n break;\r\n case 'VariableDeclaration':\r\n this.scan(ast.declarations);\r\n break;\r\n case 'VariableDeclarator':\r\n const { currentContext } = this;\r\n const declaration = {\r\n ast: ast,\r\n context: currentContext,\r\n name: ast.id.name,\r\n origin: 'declaration',\r\n forceInteger: this.inLoopInit,\r\n assignable: !this.inLoopInit && !currentContext.hasOwnProperty(ast.id.name),\r\n };\r\n currentContext[ast.id.name] = declaration;\r\n this.declarations.push(declaration);\r\n this.scan(ast.id);\r\n this.scan(ast.init);\r\n break;\r\n case 'FunctionExpression':\r\n case 'FunctionDeclaration':\r\n if (this.runningContexts.length === 0) {\r\n this.scan(ast.body);\r\n } else {\r\n this.functions.push(ast);\r\n }\r\n break;\r\n case 'IfStatement':\r\n this.scan(ast.test);\r\n this.scan(ast.consequent);\r\n if (ast.alternate) this.scan(ast.alternate);\r\n break;\r\n case 'ForStatement':\r\n this.newContext(() => {\r\n this.inLoopInit = true;\r\n this.scan(ast.init);\r\n this.inLoopInit = false;\r\n this.scan(ast.test);\r\n this.scan(ast.update);\r\n this.newContext(() => {\r\n this.scan(ast.body);\r\n });\r\n });\r\n break;\r\n case 'DoWhileStatement':\r\n case 'WhileStatement':\r\n this.newContext(() => {\r\n this.scan(ast.body);\r\n this.scan(ast.test);\r\n });\r\n break;\r\n case 'Identifier':\r\n this.identifiers.push({\r\n context: this.currentContext,\r\n ast,\r\n });\r\n break;\r\n case 'ReturnStatement':\r\n this.returnStatements.push(ast);\r\n this.scan(ast.argument);\r\n break;\r\n case 'MemberExpression':\r\n this.scan(ast.object);\r\n this.scan(ast.property);\r\n break;\r\n case 'ExpressionStatement':\r\n this.scan(ast.expression);\r\n break;\r\n case 'CallExpression':\r\n this.functionCalls.push({\r\n context: this.currentContext,\r\n ast,\r\n });\r\n this.scan(ast.arguments);\r\n break;\r\n case 'ArrayExpression':\r\n this.scan(ast.elements);\r\n break;\r\n case 'ConditionalExpression':\r\n this.scan(ast.test);\r\n this.scan(ast.alternate);\r\n this.scan(ast.consequent);\r\n break;\r\n case 'SwitchStatement':\r\n this.scan(ast.discriminant);\r\n this.scan(ast.cases);\r\n break;\r\n case 'SwitchCase':\r\n this.scan(ast.test);\r\n this.scan(ast.consequent);\r\n break;\r\n case 'ThisExpression':\r\n this.scan(ast.left);\r\n this.scan(ast.right);\r\n break;\r\n case 'Literal':\r\n case 'DebuggerStatement':\r\n case 'EmptyStatement':\r\n case 'BreakStatement':\r\n case 'ContinueStatement':\r\n break;\r\n default:\r\n throw new Error(`unhandled type \"${ast.type}\"`);\r\n }\r\n }\r\n}\r\n","import { parse } from 'acorn';\r\nimport { FunctionTracer } from './function-tracer';\r\nimport {\r\n getArgumentNamesFromString,\r\n getAstString,\r\n getFunctionNameFromString,\r\n isFunctionString,\r\n} from '../common';\r\n\r\n/**\r\n *\r\n * @desc Represents a single function, inside JS, webGL, or openGL.\r\n *

This handles all the raw state, converted state, etc. Of a single function.

\r\n */\r\nexport class FunctionNode {\r\n /**\r\n *\r\n * @param {string|object} source\r\n * @param {IFunctionSettings} [settings]\r\n */\r\n constructor(source, settings) {\r\n if (!source && !settings.ast) {\r\n throw new Error('source parameter is missing');\r\n }\r\n settings = settings || {};\r\n this.source = source;\r\n this.ast = null;\r\n this.name = typeof source === 'string' ? settings.isRootKernel ?\r\n 'kernel' :\r\n (settings.name || getFunctionNameFromString(source)) : null;\r\n this.calledFunctions = [];\r\n this.constants = {};\r\n this.constantTypes = {};\r\n this.constantBitRatios = {};\r\n this.isRootKernel = false;\r\n this.isSubKernel = false;\r\n this.debug = null;\r\n this.declarations = null;\r\n this.functions = null;\r\n this.identifiers = null;\r\n this.contexts = null;\r\n this.functionCalls = null;\r\n this.states = [];\r\n this.needsArgumentType = null;\r\n this.assignArgumentType = null;\r\n this.lookupReturnType = null;\r\n this.lookupFunctionArgumentTypes = null;\r\n this.lookupFunctionArgumentBitRatio = null;\r\n this.triggerImplyArgumentType = null;\r\n this.triggerImplyArgumentBitRatio = null;\r\n this.onNestedFunction = null;\r\n this.onFunctionCall = null;\r\n this.optimizeFloatMemory = null;\r\n this.precision = null;\r\n this.loopMaxIterations = null;\r\n this.argumentNames = (typeof this.source === 'string' ? getArgumentNamesFromString(this.source) : null);\r\n this.argumentTypes = [];\r\n this.argumentSizes = [];\r\n this.argumentBitRatios = null;\r\n this.returnType = null;\r\n this.output = [];\r\n this.plugins = null;\r\n this.leadingReturnStatement = null;\r\n this.followingReturnStatement = null;\r\n this.dynamicOutput = null;\r\n this.dynamicArguments = null;\r\n this.strictTypingChecking = false;\r\n this.fixIntegerDivisionAccuracy = null;\r\n this.warnVarUsage = true;\r\n\r\n if (settings) {\r\n for (const p in settings) {\r\n if (!settings.hasOwnProperty(p)) continue;\r\n if (!this.hasOwnProperty(p)) continue;\r\n this[p] = settings[p];\r\n }\r\n }\r\n\r\n this.literalTypes = {};\r\n\r\n this.validate();\r\n this._string = null;\r\n this._internalVariableNames = {};\r\n }\r\n\r\n validate() {\r\n if (typeof this.source !== 'string' && !this.ast) {\r\n throw new Error('this.source not a string');\r\n }\r\n\r\n if (!this.ast && !isFunctionString(this.source)) {\r\n throw new Error('this.source not a function string');\r\n }\r\n\r\n if (!this.name) {\r\n throw new Error('this.name could not be set');\r\n }\r\n\r\n if (this.argumentTypes.length > 0 && this.argumentTypes.length !== this.argumentNames.length) {\r\n throw new Error(`argumentTypes count of ${ this.argumentTypes.length } exceeds ${ this.argumentNames.length }`);\r\n }\r\n\r\n if (this.output.length < 1) {\r\n throw new Error('this.output is not big enough');\r\n }\r\n }\r\n\r\n /**\r\n * @param {String} name\r\n * @returns {boolean}\r\n */\r\n isIdentifierConstant(name) {\r\n if (!this.constants) return false;\r\n return this.constants.hasOwnProperty(name);\r\n }\r\n\r\n isInput(argumentName) {\r\n return this.argumentTypes[this.argumentNames.indexOf(argumentName)] === 'Input';\r\n }\r\n\r\n pushState(state) {\r\n this.states.push(state);\r\n }\r\n\r\n popState(state) {\r\n if (this.state !== state) {\r\n throw new Error(`Cannot popState ${ state } when in ${ this.state }`);\r\n }\r\n this.states.pop();\r\n }\r\n\r\n isState(state) {\r\n return this.state === state;\r\n }\r\n\r\n get state() {\r\n return this.states[this.states.length - 1];\r\n }\r\n\r\n /**\r\n * @function\r\n * @name astMemberExpressionUnroll\r\n * @desc Parses the abstract syntax tree for binary expression.\r\n *\r\n *

Utility function for astCallExpression.

\r\n *\r\n * @param {Object} ast - the AST object to parse\r\n *\r\n * @returns {String} the function namespace call, unrolled\r\n */\r\n astMemberExpressionUnroll(ast) {\r\n if (ast.type === 'Identifier') {\r\n return ast.name;\r\n } else if (ast.type === 'ThisExpression') {\r\n return 'this';\r\n }\r\n\r\n if (ast.type === 'MemberExpression') {\r\n if (ast.object && ast.property) {\r\n //babel sniffing\r\n if (ast.object.hasOwnProperty('name') && ast.object.name[0] === '_') {\r\n return this.astMemberExpressionUnroll(ast.property);\r\n }\r\n\r\n return (\r\n this.astMemberExpressionUnroll(ast.object) +\r\n '.' +\r\n this.astMemberExpressionUnroll(ast.property)\r\n );\r\n }\r\n }\r\n\r\n //babel sniffing\r\n if (ast.hasOwnProperty('expressions')) {\r\n const firstExpression = ast.expressions[0];\r\n if (firstExpression.type === 'Literal' && firstExpression.value === 0 && ast.expressions.length === 2) {\r\n return this.astMemberExpressionUnroll(ast.expressions[1]);\r\n }\r\n }\r\n\r\n // Failure, unknown expression\r\n throw this.astErrorOutput('Unknown astMemberExpressionUnroll', ast);\r\n }\r\n\r\n /**\r\n * @desc Parses the class function JS, and returns its Abstract Syntax Tree object.\r\n * This is used internally to convert to shader code\r\n *\r\n * @param {Object} [inParser] - Parser to use, assumes in scope 'parser' if null or undefined\r\n *\r\n * @returns {Object} The function AST Object, note that result is cached under this.ast;\r\n */\r\n getJsAST(inParser) {\r\n if (this.ast) {\r\n return this.ast;\r\n }\r\n if (typeof this.source === 'object') {\r\n this.traceFunctionAST(this.source);\r\n return this.ast = this.source;\r\n }\r\n\r\n const parser = inParser && inParser.hasOwnProperty('parse') ? inParser.parse : parse\r\n if (inParser === null) {\r\n throw new Error('Missing JS to AST parser');\r\n }\r\n\r\n const ast = Object.freeze(parser(`const parser_${ this.name } = ${ this.source };`, {\r\n locations: true\r\n }));\r\n // take out the function object, outside the var declarations\r\n const functionAST = ast.body[0].declarations[0].init;\r\n this.traceFunctionAST(functionAST);\r\n\r\n if (!ast) {\r\n throw new Error('Failed to parse JS code');\r\n }\r\n\r\n return this.ast = functionAST;\r\n }\r\n\r\n traceFunctionAST(ast) {\r\n const { contexts, declarations, functions, identifiers, functionCalls } = new FunctionTracer(ast);\r\n this.contexts = contexts;\r\n this.identifiers = identifiers;\r\n this.functionCalls = functionCalls;\r\n this.declarations = [];\r\n this.functions = functions;\r\n for (let i = 0; i < declarations.length; i++) {\r\n const declaration = declarations[i];\r\n const { ast, context, name, origin, forceInteger, assignable } = declaration;\r\n const { init } = ast;\r\n const dependencies = this.getDependencies(init);\r\n let valueType = null;\r\n\r\n if (forceInteger) {\r\n valueType = 'Integer';\r\n } else {\r\n if (init) {\r\n const realType = this.getType(init);\r\n switch (realType) {\r\n case 'Integer':\r\n case 'Float':\r\n case 'Number':\r\n if (init.type === 'MemberExpression') {\r\n valueType = realType;\r\n } else {\r\n valueType = 'Number';\r\n }\r\n break;\r\n case 'LiteralInteger':\r\n valueType = 'Number';\r\n break;\r\n default:\r\n valueType = realType;\r\n }\r\n }\r\n }\r\n this.declarations.push({\r\n valueType,\r\n dependencies,\r\n isSafe: this.isSafeDependencies(dependencies),\r\n ast,\r\n name,\r\n context,\r\n origin,\r\n assignable,\r\n });\r\n }\r\n\r\n for (let i = 0; i < functions.length; i++) {\r\n this.onNestedFunction(functions[i]);\r\n }\r\n }\r\n\r\n getDeclaration(ast) {\r\n for (let i = 0; i < this.identifiers.length; i++) {\r\n const identifier = this.identifiers[i];\r\n if (ast === identifier.ast && identifier.context.hasOwnProperty(ast.name)) {\r\n for (let j = 0; j < this.declarations.length; j++) {\r\n const declaration = this.declarations[j];\r\n if (declaration.name === ast.name && declaration.context[ast.name] === identifier.context[ast.name]) {\r\n return declaration;\r\n }\r\n }\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * @desc Return the type of parameter sent to subKernel/Kernel.\r\n * @param {Object} ast - Identifier\r\n * @returns {String} Type of the parameter\r\n */\r\n getVariableType(ast) {\r\n if (ast.type !== 'Identifier') {\r\n throw new Error(`ast of ${ast.type} not \"Identifier\"`);\r\n }\r\n let type = null;\r\n const argumentIndex = this.argumentNames.indexOf(ast.name);\r\n if (argumentIndex === -1) {\r\n const declaration = this.getDeclaration(ast);\r\n if (declaration) {\r\n return declaration.valueType;\r\n }\r\n } else {\r\n const argumentType = this.argumentTypes[argumentIndex];\r\n if (argumentType) {\r\n type = argumentType;\r\n }\r\n }\r\n if (!type && this.strictTypingChecking) {\r\n throw new Error(`Declaration of ${name} not found`);\r\n }\r\n return type;\r\n }\r\n\r\n /**\r\n * Generally used to lookup the value type returned from a member expressions\r\n * @param {String} type\r\n * @return {String}\r\n */\r\n getLookupType(type) {\r\n if (!typeLookupMap.hasOwnProperty(type)) {\r\n throw new Error(`unknown typeLookupMap ${ type }`);\r\n }\r\n return typeLookupMap[type];\r\n }\r\n\r\n getConstantType(constantName) {\r\n if (this.constantTypes[constantName]) {\r\n const type = this.constantTypes[constantName];\r\n if (type === 'Float') {\r\n return 'Number';\r\n } else {\r\n return type;\r\n }\r\n }\r\n throw new Error(`Type for constant \"${ constantName }\" not declared`);\r\n }\r\n\r\n toString() {\r\n if (this._string) return this._string;\r\n return this._string = this.astGeneric(this.getJsAST(), []).join('').trim();\r\n }\r\n\r\n toJSON() {\r\n const settings = {\r\n source: this.source,\r\n name: this.name,\r\n constants: this.constants,\r\n constantTypes: this.constantTypes,\r\n isRootKernel: this.isRootKernel,\r\n isSubKernel: this.isSubKernel,\r\n debug: this.debug,\r\n output: this.output,\r\n loopMaxIterations: this.loopMaxIterations,\r\n argumentNames: this.argumentNames,\r\n argumentTypes: this.argumentTypes,\r\n argumentSizes: this.argumentSizes,\r\n returnType: this.returnType,\r\n leadingReturnStatement: this.leadingReturnStatement,\r\n followingReturnStatement: this.followingReturnStatement,\r\n };\r\n\r\n return {\r\n ast: this.ast,\r\n settings\r\n };\r\n }\r\n\r\n /**\r\n * Recursively looks up type for ast expression until it's found\r\n * @param ast\r\n * @returns {String|null}\r\n */\r\n getType(ast) {\r\n if (Array.isArray(ast)) {\r\n return this.getType(ast[ast.length - 1]);\r\n }\r\n switch (ast.type) {\r\n case 'BlockStatement':\r\n return this.getType(ast.body);\r\n case 'ArrayExpression':\r\n return `Array(${ ast.elements.length })`;\r\n case 'Literal':\r\n const literalKey = `${ast.start},${ast.end}`;\r\n if (this.literalTypes[literalKey]) {\r\n return this.literalTypes[literalKey];\r\n }\r\n if (Number.isInteger(ast.value)) {\r\n return 'LiteralInteger';\r\n } else if (ast.value === true || ast.value === false) {\r\n return 'Boolean';\r\n } else {\r\n return 'Number';\r\n }\r\n case 'AssignmentExpression':\r\n return this.getType(ast.left);\r\n case 'CallExpression':\r\n if (this.isAstMathFunction(ast)) {\r\n return 'Number';\r\n }\r\n if (!ast.callee || !ast.callee.name) {\r\n if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[ast.callee.expressions.length - 1].property.name) {\r\n const functionName = ast.callee.expressions[ast.callee.expressions.length - 1].property.name;\r\n this.inferArgumentTypesIfNeeded(functionName, ast.arguments);\r\n return this.lookupReturnType(functionName, ast, this);\r\n }\r\n throw this.astErrorOutput('Unknown call expression', ast);\r\n }\r\n if (ast.callee && ast.callee.name) {\r\n const functionName = ast.callee.name;\r\n this.inferArgumentTypesIfNeeded(functionName, ast.arguments);\r\n return this.lookupReturnType(functionName, ast, this);\r\n }\r\n throw this.astErrorOutput(`Unhandled getType Type \"${ ast.type }\"`, ast);\r\n case 'BinaryExpression':\r\n // modulos is Number\r\n switch (ast.operator) {\r\n case '%':\r\n case '/':\r\n if (this.fixIntegerDivisionAccuracy) {\r\n return 'Number';\r\n } else {\r\n break;\r\n }\r\n case '>':\r\n case '<':\r\n return 'Boolean';\r\n case '&':\r\n case '|':\r\n case '^':\r\n case '<<':\r\n case '>>':\r\n case '>>>':\r\n return 'Integer';\r\n }\r\n const type = this.getType(ast.left);\r\n if (this.isState('skip-literal-correction')) return type;\r\n if (type === 'LiteralInteger') {\r\n const rightType = this.getType(ast.right);\r\n if (rightType === 'LiteralInteger') {\r\n if (ast.left.value % 1 === 0) {\r\n return 'Integer';\r\n } else {\r\n return 'Float';\r\n }\r\n }\r\n return rightType;\r\n }\r\n return typeLookupMap[type] || type;\r\n case 'UpdateExpression':\r\n return this.getType(ast.argument);\r\n case 'UnaryExpression':\r\n if (ast.operator === '~') {\r\n return 'Integer';\r\n }\r\n return this.getType(ast.argument);\r\n case 'VariableDeclaration': {\r\n const declarations = ast.declarations;\r\n let lastType;\r\n for (let i = 0; i < declarations.length; i++) {\r\n const declaration = declarations[i];\r\n lastType = this.getType(declaration);\r\n }\r\n if (!lastType) {\r\n throw this.astErrorOutput(`Unable to find type for declaration`, ast);\r\n }\r\n return lastType;\r\n }\r\n case 'VariableDeclarator':\r\n const declaration = this.getDeclaration(ast.id);\r\n if (!declaration) {\r\n throw this.astErrorOutput(`Unable to find declarator`, ast);\r\n }\r\n\r\n if (!declaration.valueType) {\r\n throw this.astErrorOutput(`Unable to find declarator valueType`, ast);\r\n }\r\n\r\n return declaration.valueType;\r\n case 'Identifier':\r\n if (ast.name === 'Infinity') {\r\n return 'Number';\r\n }\r\n if (this.isAstVariable(ast)) {\r\n const signature = this.getVariableSignature(ast);\r\n if (signature === 'value') {\r\n const type = this.getVariableType(ast);\r\n if (!type) {\r\n throw this.astErrorOutput(`Unable to find identifier valueType`, ast);\r\n }\r\n return type;\r\n }\r\n }\r\n const origin = this.findIdentifierOrigin(ast);\r\n if (origin && origin.init) {\r\n return this.getType(origin.init);\r\n }\r\n return null;\r\n case 'ReturnStatement':\r\n return this.getType(ast.argument);\r\n case 'MemberExpression':\r\n if (this.isAstMathFunction(ast)) {\r\n switch (ast.property.name) {\r\n case 'ceil':\r\n return 'Integer';\r\n case 'floor':\r\n return 'Integer';\r\n case 'round':\r\n return 'Integer';\r\n }\r\n return 'Number';\r\n }\r\n if (this.isAstVariable(ast)) {\r\n const variableSignature = this.getVariableSignature(ast);\r\n switch (variableSignature) {\r\n case 'value[]':\r\n return this.getLookupType(this.getVariableType(ast.object));\r\n case 'value[][]':\r\n return this.getLookupType(this.getVariableType(ast.object.object));\r\n case 'value[][][]':\r\n return this.getLookupType(this.getVariableType(ast.object.object.object));\r\n case 'value[][][][]':\r\n return this.getLookupType(this.getVariableType(ast.object.object.object.object));\r\n case 'value.thread.value':\r\n case 'this.thread.value':\r\n return 'Integer';\r\n case 'this.output.value':\r\n return this.dynamicOutput ? 'Integer' : 'LiteralInteger';\r\n case 'this.constants.value':\r\n return this.getConstantType(ast.property.name);\r\n case 'this.constants.value[]':\r\n return this.getLookupType(this.getConstantType(ast.object.property.name));\r\n case 'this.constants.value[][]':\r\n return this.getLookupType(this.getConstantType(ast.object.object.property.name));\r\n case 'this.constants.value[][][]':\r\n return this.getLookupType(this.getConstantType(ast.object.object.object.property.name));\r\n case 'this.constants.value[][][][]':\r\n return this.getLookupType(this.getConstantType(ast.object.object.object.object.property.name));\r\n case 'fn()[]':\r\n return this.getLookupType(this.getType(ast.object));\r\n case 'fn()[][]':\r\n return this.getLookupType(this.getType(ast.object));\r\n case 'fn()[][][]':\r\n return this.getLookupType(this.getType(ast.object));\r\n case 'value.value':\r\n if (this.isAstMathVariable(ast)) {\r\n return 'Number';\r\n }\r\n switch (ast.property.name) {\r\n case 'r':\r\n return this.getLookupType(this.getVariableType(ast.object));\r\n case 'g':\r\n return this.getLookupType(this.getVariableType(ast.object));\r\n case 'b':\r\n return this.getLookupType(this.getVariableType(ast.object));\r\n case 'a':\r\n return this.getLookupType(this.getVariableType(ast.object));\r\n }\r\n case '[][]':\r\n return 'Number';\r\n }\r\n throw this.astErrorOutput('Unhandled getType MemberExpression', ast);\r\n }\r\n throw this.astErrorOutput('Unhandled getType MemberExpression', ast);\r\n case 'ConditionalExpression':\r\n return this.getType(ast.consequent);\r\n case 'FunctionDeclaration':\r\n case 'FunctionExpression':\r\n const lastReturn = this.findLastReturn(ast.body);\r\n if (lastReturn) {\r\n return this.getType(lastReturn);\r\n }\r\n return null;\r\n case 'IfStatement':\r\n return this.getType(ast.consequent);\r\n default:\r\n throw this.astErrorOutput(`Unhandled getType Type \"${ ast.type }\"`, ast);\r\n }\r\n }\r\n\r\n inferArgumentTypesIfNeeded(functionName, args) {\r\n // ensure arguments are filled in, so when we lookup return type, we already can infer it\r\n for (let i = 0; i < args.length; i++) {\r\n if (!this.needsArgumentType(functionName, i)) continue;\r\n const type = this.getType(args[i]);\r\n if (!type) {\r\n throw this.astErrorOutput(`Unable to infer argument ${i}`, args[i]);\r\n }\r\n this.assignArgumentType(functionName, i, type);\r\n }\r\n }\r\n\r\n isAstMathVariable(ast) {\r\n const mathProperties = [\r\n 'E',\r\n 'PI',\r\n 'SQRT2',\r\n 'SQRT1_2',\r\n 'LN2',\r\n 'LN10',\r\n 'LOG2E',\r\n 'LOG10E',\r\n ];\r\n return ast.type === 'MemberExpression' &&\r\n ast.object && ast.object.type === 'Identifier' &&\r\n ast.object.name === 'Math' &&\r\n ast.property &&\r\n ast.property.type === 'Identifier' &&\r\n mathProperties.indexOf(ast.property.name) > -1;\r\n }\r\n\r\n isAstMathFunction(ast) {\r\n const mathFunctions = [\r\n 'abs',\r\n 'acos',\r\n 'asin',\r\n 'atan',\r\n 'atan2',\r\n 'ceil',\r\n 'cos',\r\n 'exp',\r\n 'floor',\r\n 'log',\r\n 'log2',\r\n 'max',\r\n 'min',\r\n 'pow',\r\n 'random',\r\n 'round',\r\n 'sign',\r\n 'sin',\r\n 'sqrt',\r\n 'tan',\r\n ];\r\n return ast.type === 'CallExpression' &&\r\n ast.callee &&\r\n ast.callee.type === 'MemberExpression' &&\r\n ast.callee.object &&\r\n ast.callee.object.type === 'Identifier' &&\r\n ast.callee.object.name === 'Math' &&\r\n ast.callee.property &&\r\n ast.callee.property.type === 'Identifier' &&\r\n mathFunctions.indexOf(ast.callee.property.name) > -1;\r\n }\r\n\r\n isAstVariable(ast) {\r\n return ast.type === 'Identifier' || ast.type === 'MemberExpression';\r\n }\r\n\r\n isSafe(ast) {\r\n return this.isSafeDependencies(this.getDependencies(ast));\r\n }\r\n\r\n isSafeDependencies(dependencies) {\r\n return dependencies && dependencies.every ? dependencies.every(dependency => dependency.isSafe) : true;\r\n }\r\n\r\n /**\r\n *\r\n * @param ast\r\n * @param dependencies\r\n * @param isNotSafe\r\n * @return {Array}\r\n */\r\n getDependencies(ast, dependencies, isNotSafe) {\r\n if (!dependencies) {\r\n dependencies = [];\r\n }\r\n if (!ast) return null;\r\n if (Array.isArray(ast)) {\r\n for (let i = 0; i < ast.length; i++) {\r\n this.getDependencies(ast[i], dependencies, isNotSafe);\r\n }\r\n return dependencies;\r\n }\r\n switch (ast.type) {\r\n case 'AssignmentExpression':\r\n this.getDependencies(ast.left, dependencies, isNotSafe);\r\n this.getDependencies(ast.right, dependencies, isNotSafe);\r\n return dependencies;\r\n case 'ConditionalExpression':\r\n this.getDependencies(ast.test, dependencies, isNotSafe);\r\n this.getDependencies(ast.alternate, dependencies, isNotSafe);\r\n this.getDependencies(ast.consequent, dependencies, isNotSafe);\r\n return dependencies;\r\n case 'Literal':\r\n dependencies.push({\r\n origin: 'literal',\r\n value: ast.value,\r\n isSafe: isNotSafe === true ? false : ast.value > -Infinity && ast.value < Infinity && !isNaN(ast.value)\r\n });\r\n break;\r\n case 'VariableDeclarator':\r\n return this.getDependencies(ast.init, dependencies, isNotSafe);\r\n case 'Identifier':\r\n const declaration = this.getDeclaration(ast);\r\n if (declaration) {\r\n dependencies.push({\r\n name: ast.name,\r\n origin: 'declaration',\r\n isSafe: isNotSafe ? false : this.isSafeDependencies(declaration.dependencies),\r\n });\r\n } else if (this.argumentNames.indexOf(ast.name) > -1) {\r\n dependencies.push({\r\n name: ast.name,\r\n origin: 'argument',\r\n isSafe: false,\r\n });\r\n } else if (this.strictTypingChecking) {\r\n throw new Error(`Cannot find identifier origin \"${ast.name}\"`);\r\n }\r\n break;\r\n case 'FunctionDeclaration':\r\n return this.getDependencies(ast.body.body[ast.body.body.length - 1], dependencies, isNotSafe);\r\n case 'ReturnStatement':\r\n return this.getDependencies(ast.argument, dependencies);\r\n case 'BinaryExpression':\r\n isNotSafe = (ast.operator === '/' || ast.operator === '*');\r\n this.getDependencies(ast.left, dependencies, isNotSafe);\r\n this.getDependencies(ast.right, dependencies, isNotSafe);\r\n return dependencies;\r\n case 'UnaryExpression':\r\n case 'UpdateExpression':\r\n return this.getDependencies(ast.argument, dependencies, isNotSafe);\r\n case 'VariableDeclaration':\r\n return this.getDependencies(ast.declarations, dependencies, isNotSafe);\r\n case 'ArrayExpression':\r\n dependencies.push({\r\n origin: 'declaration',\r\n isSafe: true,\r\n });\r\n return dependencies;\r\n case 'CallExpression':\r\n dependencies.push({\r\n origin: 'function',\r\n isSafe: true,\r\n });\r\n return dependencies;\r\n case 'MemberExpression':\r\n const details = this.getMemberExpressionDetails(ast);\r\n switch (details.signature) {\r\n case 'value[]':\r\n this.getDependencies(ast.object, dependencies, isNotSafe);\r\n break;\r\n case 'value[][]':\r\n this.getDependencies(ast.object.object, dependencies, isNotSafe);\r\n break;\r\n case 'value[][][]':\r\n this.getDependencies(ast.object.object.object, dependencies, isNotSafe);\r\n break;\r\n case 'this.output.value':\r\n if (this.dynamicOutput) {\r\n dependencies.push({\r\n name: details.name,\r\n origin: 'output',\r\n isSafe: false,\r\n });\r\n }\r\n break;\r\n }\r\n if (details) {\r\n if (details.property) {\r\n this.getDependencies(details.property, dependencies, isNotSafe);\r\n }\r\n if (details.xProperty) {\r\n this.getDependencies(details.xProperty, dependencies, isNotSafe);\r\n }\r\n if (details.yProperty) {\r\n this.getDependencies(details.yProperty, dependencies, isNotSafe);\r\n }\r\n if (details.zProperty) {\r\n this.getDependencies(details.zProperty, dependencies, isNotSafe);\r\n }\r\n return dependencies;\r\n }\r\n default:\r\n throw this.astErrorOutput(`Unhandled type ${ ast.type } in getDependencies`, ast);\r\n }\r\n return dependencies;\r\n }\r\n\r\n getVariableSignature(ast) {\r\n if (!this.isAstVariable(ast)) {\r\n throw new Error(`ast of type \"${ ast.type }\" is not a variable signature`);\r\n }\r\n if (ast.type === 'Identifier') {\r\n return 'value';\r\n }\r\n const signature = [];\r\n while (true) {\r\n if (!ast) break;\r\n if (ast.computed) {\r\n signature.push('[]');\r\n } else if (ast.type === 'ThisExpression') {\r\n signature.unshift('this');\r\n } else if (ast.property && ast.property.name) {\r\n if (\r\n ast.property.name === 'x' ||\r\n ast.property.name === 'y' ||\r\n ast.property.name === 'z'\r\n ) {\r\n signature.unshift('.value');\r\n } else if (\r\n ast.property.name === 'constants' ||\r\n ast.property.name === 'thread' ||\r\n ast.property.name === 'output'\r\n ) {\r\n signature.unshift('.' + ast.property.name);\r\n } else {\r\n signature.unshift('.value');\r\n }\r\n } else if (ast.name) {\r\n signature.unshift('value');\r\n } else if (ast.callee && ast.callee.name) {\r\n signature.unshift('fn()');\r\n } else if (ast.elements) {\r\n signature.unshift('[]');\r\n } else {\r\n signature.unshift('unknown');\r\n }\r\n ast = ast.object;\r\n }\r\n\r\n const signatureString = signature.join('');\r\n const allowedExpressions = [\r\n 'value',\r\n 'value[]',\r\n 'value[][]',\r\n 'value[][][]',\r\n 'value[][][][]',\r\n 'value.value',\r\n 'value.thread.value',\r\n 'this.thread.value',\r\n 'this.output.value',\r\n 'this.constants.value',\r\n 'this.constants.value[]',\r\n 'this.constants.value[][]',\r\n 'this.constants.value[][][]',\r\n 'this.constants.value[][][][]',\r\n 'fn()[]',\r\n 'fn()[][]',\r\n 'fn()[][][]',\r\n '[][]',\r\n ];\r\n if (allowedExpressions.indexOf(signatureString) > -1) {\r\n return signatureString;\r\n }\r\n return null;\r\n }\r\n\r\n build() {\r\n return this.toString().length > 0;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for generically to its respective function\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed string array\r\n */\r\n astGeneric(ast, retArr) {\r\n if (ast === null) {\r\n throw this.astErrorOutput('NULL ast', ast);\r\n } else {\r\n if (Array.isArray(ast)) {\r\n for (let i = 0; i < ast.length; i++) {\r\n this.astGeneric(ast[i], retArr);\r\n }\r\n return retArr;\r\n }\r\n\r\n switch (ast.type) {\r\n case 'FunctionDeclaration':\r\n return this.astFunctionDeclaration(ast, retArr);\r\n case 'FunctionExpression':\r\n return this.astFunctionExpression(ast, retArr);\r\n case 'ReturnStatement':\r\n return this.astReturnStatement(ast, retArr);\r\n case 'Literal':\r\n return this.astLiteral(ast, retArr);\r\n case 'BinaryExpression':\r\n return this.astBinaryExpression(ast, retArr);\r\n case 'Identifier':\r\n return this.astIdentifierExpression(ast, retArr);\r\n case 'AssignmentExpression':\r\n return this.astAssignmentExpression(ast, retArr);\r\n case 'ExpressionStatement':\r\n return this.astExpressionStatement(ast, retArr);\r\n case 'EmptyStatement':\r\n return this.astEmptyStatement(ast, retArr);\r\n case 'BlockStatement':\r\n return this.astBlockStatement(ast, retArr);\r\n case 'IfStatement':\r\n return this.astIfStatement(ast, retArr);\r\n case 'SwitchStatement':\r\n return this.astSwitchStatement(ast, retArr);\r\n case 'BreakStatement':\r\n return this.astBreakStatement(ast, retArr);\r\n case 'ContinueStatement':\r\n return this.astContinueStatement(ast, retArr);\r\n case 'ForStatement':\r\n return this.astForStatement(ast, retArr);\r\n case 'WhileStatement':\r\n return this.astWhileStatement(ast, retArr);\r\n case 'DoWhileStatement':\r\n return this.astDoWhileStatement(ast, retArr);\r\n case 'VariableDeclaration':\r\n return this.astVariableDeclaration(ast, retArr);\r\n case 'VariableDeclarator':\r\n return this.astVariableDeclarator(ast, retArr);\r\n case 'ThisExpression':\r\n return this.astThisExpression(ast, retArr);\r\n case 'SequenceExpression':\r\n return this.astSequenceExpression(ast, retArr);\r\n case 'UnaryExpression':\r\n return this.astUnaryExpression(ast, retArr);\r\n case 'UpdateExpression':\r\n return this.astUpdateExpression(ast, retArr);\r\n case 'LogicalExpression':\r\n return this.astLogicalExpression(ast, retArr);\r\n case 'MemberExpression':\r\n return this.astMemberExpression(ast, retArr);\r\n case 'CallExpression':\r\n return this.astCallExpression(ast, retArr);\r\n case 'ArrayExpression':\r\n return this.astArrayExpression(ast, retArr);\r\n case 'DebuggerStatement':\r\n return this.astDebuggerStatement(ast, retArr);\r\n case 'ConditionalExpression':\r\n return this.astConditionalExpression(ast, retArr);\r\n }\r\n\r\n throw this.astErrorOutput('Unknown ast type : ' + ast.type, ast);\r\n }\r\n }\r\n /**\r\n * @desc To throw the AST error, with its location.\r\n * @param {string} error - the error message output\r\n * @param {Object} ast - the AST object where the error is\r\n */\r\n astErrorOutput(error, ast) {\r\n if (typeof this.source !== 'string') {\r\n return new Error(error);\r\n }\r\n\r\n const debugString = getAstString(this.source, ast);\r\n const leadingSource = this.source.substr(ast.start);\r\n const splitLines = leadingSource.split(/\\n/);\r\n const lineBefore = splitLines.length > 0 ? splitLines[splitLines.length - 1] : 0;\r\n return new Error(`${error} on line ${ splitLines.length }, position ${ lineBefore.length }:\\n ${ debugString }`);\r\n }\r\n\r\n astDebuggerStatement(arrNode, retArr) {\r\n return retArr;\r\n }\r\n\r\n astConditionalExpression(ast, retArr) {\r\n if (ast.type !== 'ConditionalExpression') {\r\n throw this.astErrorOutput('Not a conditional expression', ast);\r\n }\r\n retArr.push('(');\r\n this.astGeneric(ast.test, retArr);\r\n retArr.push('?');\r\n this.astGeneric(ast.consequent, retArr);\r\n retArr.push(':');\r\n this.astGeneric(ast.alternate, retArr);\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @abstract\r\n * @param {Object} ast\r\n * @param {String[]} retArr\r\n * @returns {String[]}\r\n */\r\n astFunction(ast, retArr) {\r\n throw new Error(`\"astFunction\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for to its *named function declaration*\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astFunctionDeclaration(ast, retArr) {\r\n if (this.isChildFunction(ast)) {\r\n return retArr;\r\n }\r\n return this.astFunction(ast, retArr);\r\n }\r\n astFunctionExpression(ast, retArr) {\r\n if (this.isChildFunction(ast)) {\r\n return retArr;\r\n }\r\n return this.astFunction(ast, retArr);\r\n }\r\n isChildFunction(ast) {\r\n for (let i = 0; i < this.functions.length; i++) {\r\n if (this.functions[i] === ast) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n astReturnStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n astLiteral(ast, retArr) {\r\n this.literalTypes[`${ast.start},${ast.end}`] = 'Number';\r\n return retArr;\r\n }\r\n astBinaryExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n astIdentifierExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n astAssignmentExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *generic expression* statement\r\n * @param {Object} esNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astExpressionStatement(esNode, retArr) {\r\n this.astGeneric(esNode.expression, retArr);\r\n retArr.push(';');\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for an *Empty* Statement\r\n * @param {Object} eNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astEmptyStatement(eNode, retArr) {\r\n return retArr;\r\n }\r\n astBlockStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n astIfStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n astSwitchStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Break* Statement\r\n * @param {Object} brNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astBreakStatement(brNode, retArr) {\r\n retArr.push('break;');\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Continue* Statement\r\n * @param {Object} crNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astContinueStatement(crNode, retArr) {\r\n retArr.push('continue;\\n');\r\n return retArr;\r\n }\r\n astForStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n astWhileStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n astDoWhileStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Variable Declaration*\r\n * @param {Object} varDecNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astVariableDeclaration(varDecNode, retArr) {\r\n const declarations = varDecNode.declarations;\r\n if (!declarations || !declarations[0] || !declarations[0].init) {\r\n throw this.astErrorOutput('Unexpected expression', varDecNode);\r\n }\r\n const result = [];\r\n const firstDeclaration = declarations[0];\r\n const init = firstDeclaration.init;\r\n let type = this.isState('in-for-loop-init') ? 'Integer' : this.getType(init);\r\n if (type === 'LiteralInteger') {\r\n // We had the choice to go either float or int, choosing float\r\n type = 'Number';\r\n }\r\n const markupType = typeMap[type];\r\n if (!markupType) {\r\n throw this.astErrorOutput(`Markup type ${ markupType } not handled`, varDecNode);\r\n }\r\n let dependencies = this.getDependencies(firstDeclaration.init);\r\n throw new Error('remove me');\r\n this.declarations[firstDeclaration.id.name] = Object.freeze({\r\n type,\r\n dependencies,\r\n isSafe: dependencies.every(dependency => dependency.isSafe)\r\n });\r\n const initResult = [`${type} user_${firstDeclaration.id.name}=`];\r\n this.astGeneric(init, initResult);\r\n result.push(initResult.join(''));\r\n\r\n // first declaration is done, now any added ones setup\r\n for (let i = 1; i < declarations.length; i++) {\r\n const declaration = declarations[i];\r\n dependencies = this.getDependencies(declaration);\r\n throw new Error('Remove me');\r\n this.declarations[declaration.id.name] = Object.freeze({\r\n type,\r\n dependencies,\r\n isSafe: false\r\n });\r\n this.astGeneric(declaration, result);\r\n }\r\n\r\n retArr.push(retArr, result.join(','));\r\n retArr.push(';');\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Variable Declarator*\r\n * @param {Object} iVarDecNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astVariableDeclarator(iVarDecNode, retArr) {\r\n this.astGeneric(iVarDecNode.id, retArr);\r\n if (iVarDecNode.init !== null) {\r\n retArr.push('=');\r\n this.astGeneric(iVarDecNode.init, retArr);\r\n }\r\n return retArr;\r\n }\r\n astThisExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n astSequenceExpression(sNode, retArr) {\r\n for (let i = 0; i < sNode.expressions.length; i++) {\r\n if (i > 0) {\r\n retArr.push(',');\r\n }\r\n this.astGeneric(sNode.expressions, retArr);\r\n }\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Unary* Expression\r\n * @param {Object} uNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astUnaryExpression(uNode, retArr) {\r\n const unaryResult = this.checkAndUpconvertBitwiseUnary(uNode, retArr);\r\n if (unaryResult) {\r\n return retArr;\r\n }\r\n\r\n if (uNode.prefix) {\r\n retArr.push(uNode.operator);\r\n this.astGeneric(uNode.argument, retArr);\r\n } else {\r\n this.astGeneric(uNode.argument, retArr);\r\n retArr.push(uNode.operator);\r\n }\r\n\r\n return retArr;\r\n }\r\n\r\n checkAndUpconvertBitwiseUnary(uNode, retArr) {}\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Update* Expression\r\n * @param {Object} uNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astUpdateExpression(uNode, retArr) {\r\n if (uNode.prefix) {\r\n retArr.push(uNode.operator);\r\n this.astGeneric(uNode.argument, retArr);\r\n } else {\r\n this.astGeneric(uNode.argument, retArr);\r\n retArr.push(uNode.operator);\r\n }\r\n\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Logical* Expression\r\n * @param {Object} logNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astLogicalExpression(logNode, retArr) {\r\n retArr.push('(');\r\n this.astGeneric(logNode.left, retArr);\r\n retArr.push(logNode.operator);\r\n this.astGeneric(logNode.right, retArr);\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n astMemberExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n astCallExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n astArrayExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n\r\n /**\r\n *\r\n * @param ast\r\n * @return {IFunctionNodeMemberExpressionDetails}\r\n */\r\n getMemberExpressionDetails(ast) {\r\n if (ast.type !== 'MemberExpression') {\r\n throw this.astErrorOutput(`Expression ${ ast.type } not a MemberExpression`, ast);\r\n }\r\n let name = null;\r\n let type = null;\r\n const variableSignature = this.getVariableSignature(ast);\r\n switch (variableSignature) {\r\n case 'value':\r\n return null;\r\n case 'value.thread.value':\r\n case 'this.thread.value':\r\n case 'this.output.value':\r\n return {\r\n signature: variableSignature,\r\n type: 'Integer',\r\n name: ast.property.name\r\n };\r\n case 'value[]':\r\n if (typeof ast.object.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.name;\r\n return {\r\n name,\r\n origin: 'user',\r\n signature: variableSignature,\r\n type: this.getVariableType(ast.object),\r\n xProperty: ast.property\r\n };\r\n case 'value[][]':\r\n if (typeof ast.object.object.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.object.name;\r\n return {\r\n name,\r\n origin: 'user',\r\n signature: variableSignature,\r\n type: this.getVariableType(ast.object.object),\r\n yProperty: ast.object.property,\r\n xProperty: ast.property,\r\n };\r\n case 'value[][][]':\r\n if (typeof ast.object.object.object.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.object.object.name;\r\n return {\r\n name,\r\n origin: 'user',\r\n signature: variableSignature,\r\n type: this.getVariableType(ast.object.object.object),\r\n zProperty: ast.object.object.property,\r\n yProperty: ast.object.property,\r\n xProperty: ast.property,\r\n };\r\n case 'value[][][][]':\r\n if (typeof ast.object.object.object.object.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.object.object.object.name;\r\n return {\r\n name,\r\n origin: 'user',\r\n signature: variableSignature,\r\n type: this.getVariableType(ast.object.object.object.object),\r\n zProperty: ast.object.object.property,\r\n yProperty: ast.object.property,\r\n xProperty: ast.property,\r\n };\r\n case 'value.value':\r\n if (typeof ast.property.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n if (this.isAstMathVariable(ast)) {\r\n name = ast.property.name;\r\n return {\r\n name,\r\n origin: 'Math',\r\n type: 'Number',\r\n signature: variableSignature,\r\n };\r\n }\r\n switch (ast.property.name) {\r\n case 'r':\r\n case 'g':\r\n case 'b':\r\n case 'a':\r\n name = ast.object.name;\r\n return {\r\n name,\r\n property: ast.property.name,\r\n origin: 'user',\r\n signature: variableSignature,\r\n type: 'Number'\r\n };\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n case 'this.constants.value':\r\n if (typeof ast.property.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.property.name;\r\n type = this.getConstantType(name);\r\n if (!type) {\r\n throw this.astErrorOutput('Constant has no type', ast);\r\n }\r\n return {\r\n name,\r\n type,\r\n origin: 'constants',\r\n signature: variableSignature,\r\n };\r\n case 'this.constants.value[]':\r\n if (typeof ast.object.property.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.property.name;\r\n type = this.getConstantType(name);\r\n if (!type) {\r\n throw this.astErrorOutput('Constant has no type', ast);\r\n }\r\n return {\r\n name,\r\n type,\r\n origin: 'constants',\r\n signature: variableSignature,\r\n xProperty: ast.property,\r\n };\r\n case 'this.constants.value[][]': {\r\n if (typeof ast.object.object.property.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.object.property.name;\r\n type = this.getConstantType(name);\r\n if (!type) {\r\n throw this.astErrorOutput('Constant has no type', ast);\r\n }\r\n return {\r\n name,\r\n type,\r\n origin: 'constants',\r\n signature: variableSignature,\r\n yProperty: ast.object.property,\r\n xProperty: ast.property,\r\n };\r\n }\r\n case 'this.constants.value[][][]': {\r\n if (typeof ast.object.object.object.property.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.object.object.property.name;\r\n type = this.getConstantType(name);\r\n if (!type) {\r\n throw this.astErrorOutput('Constant has no type', ast);\r\n }\r\n return {\r\n name,\r\n type,\r\n origin: 'constants',\r\n signature: variableSignature,\r\n zProperty: ast.object.object.property,\r\n yProperty: ast.object.property,\r\n xProperty: ast.property,\r\n };\r\n }\r\n case 'fn()[]':\r\n case '[][]':\r\n return {\r\n signature: variableSignature,\r\n property: ast.property,\r\n };\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n }\r\n\r\n findIdentifierOrigin(astToFind) {\r\n const stack = [this.ast];\r\n\r\n while (stack.length > 0) {\r\n const atNode = stack[0];\r\n if (atNode.type === 'VariableDeclarator' && atNode.id && atNode.id.name && atNode.id.name === astToFind.name) {\r\n return atNode;\r\n }\r\n stack.shift();\r\n if (atNode.argument) {\r\n stack.push(atNode.argument);\r\n } else if (atNode.body) {\r\n stack.push(atNode.body);\r\n } else if (atNode.declarations) {\r\n stack.push(atNode.declarations);\r\n } else if (Array.isArray(atNode)) {\r\n for (let i = 0; i < atNode.length; i++) {\r\n stack.push(atNode[i]);\r\n }\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n findLastReturn(ast) {\r\n const stack = [ast || this.ast];\r\n\r\n while (stack.length > 0) {\r\n const atNode = stack.pop();\r\n if (atNode.type === 'ReturnStatement') {\r\n return atNode;\r\n }\r\n if (atNode.type === 'FunctionDeclaration') {\r\n continue;\r\n }\r\n if (atNode.argument) {\r\n stack.push(atNode.argument);\r\n } else if (atNode.body) {\r\n stack.push(atNode.body);\r\n } else if (atNode.declarations) {\r\n stack.push(atNode.declarations);\r\n } else if (Array.isArray(atNode)) {\r\n for (let i = 0; i < atNode.length; i++) {\r\n stack.push(atNode[i]);\r\n }\r\n } else if (atNode.consequent) {\r\n stack.push(atNode.consequent);\r\n } else if (atNode.cases) {\r\n stack.push(atNode.cases);\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n getInternalVariableName(name) {\r\n if (!this._internalVariableNames.hasOwnProperty(name)) {\r\n this._internalVariableNames[name] = 0;\r\n }\r\n this._internalVariableNames[name]++;\r\n if (this._internalVariableNames[name] === 1) {\r\n return name;\r\n }\r\n return name + this._internalVariableNames[name];\r\n }\r\n\r\n varWarn() {\r\n console.warn('var declarations are deprecated, weird things happen when falling back to CPU because var scope differs in javascript than in most languages. Use const or let');\r\n }\r\n}\r\n\r\nconst typeLookupMap = {\r\n 'Number': 'Number',\r\n 'Float': 'Float',\r\n 'Integer': 'Integer',\r\n 'Array': 'Number',\r\n 'Array(2)': 'Number',\r\n 'Array(3)': 'Number',\r\n 'Array(4)': 'Number',\r\n 'Array2D': 'Number',\r\n 'Array3D': 'Number',\r\n 'Input': 'Number',\r\n 'HTMLImage': 'Array(4)',\r\n 'HTMLVideo': 'Array(4)',\r\n 'HTMLImageArray': 'Array(4)',\r\n 'NumberTexture': 'Number',\r\n 'MemoryOptimizedNumberTexture': 'Number',\r\n 'Array1D(2)': 'Array(2)',\r\n 'Array1D(3)': 'Array(3)',\r\n 'Array1D(4)': 'Array(4)',\r\n 'Array2D(2)': 'Array(2)',\r\n 'Array2D(3)': 'Array(3)',\r\n 'Array2D(4)': 'Array(4)',\r\n 'Array3D(2)': 'Array(2)',\r\n 'Array3D(3)': 'Array(3)',\r\n 'Array3D(4)': 'Array(4)',\r\n 'ArrayTexture(1)': 'Number',\r\n 'ArrayTexture(2)': 'Array(2)',\r\n 'ArrayTexture(3)': 'Array(3)',\r\n 'ArrayTexture(4)': 'Array(4)',\r\n};\r\n","import { FunctionNode } from '../function-node';\r\n\r\n/**\r\n * @desc [INTERNAL] Represents a single function, inside JS\r\n *\r\n *

This handles all the raw state, converted state, etc. Of a single function.

\r\n */\r\nexport class CPUFunctionNode extends FunctionNode {\r\n /**\r\n * @desc Parses the abstract syntax tree for to its *named function*\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astFunction(ast, retArr) {\r\n\r\n // Setup function return type and name\r\n if (!this.isRootKernel) {\r\n retArr.push('function');\r\n retArr.push(' ');\r\n retArr.push(this.name);\r\n retArr.push('(');\r\n\r\n // Arguments handling\r\n for (let i = 0; i < this.argumentNames.length; ++i) {\r\n const argumentName = this.argumentNames[i];\r\n\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n retArr.push('user_');\r\n retArr.push(argumentName);\r\n }\r\n\r\n // Function opening\r\n retArr.push(') {\\n');\r\n }\r\n\r\n // Body statement iteration\r\n for (let i = 0; i < ast.body.body.length; ++i) {\r\n this.astGeneric(ast.body.body[i], retArr);\r\n retArr.push('\\n');\r\n }\r\n\r\n if (!this.isRootKernel) {\r\n // Function closing\r\n retArr.push('}\\n');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for to *return* statement\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astReturnStatement(ast, retArr) {\r\n const type = this.returnType || this.getType(ast.argument);\r\n\r\n if (!this.returnType) {\r\n this.returnType = type;\r\n }\r\n\r\n if (this.isRootKernel) {\r\n retArr.push(this.leadingReturnStatement);\r\n this.astGeneric(ast.argument, retArr);\r\n retArr.push(';\\n');\r\n retArr.push(this.followingReturnStatement);\r\n retArr.push('continue;\\n');\r\n } else if (this.isSubKernel) {\r\n retArr.push(`subKernelResult_${ this.name } = `);\r\n this.astGeneric(ast.argument, retArr);\r\n retArr.push(';');\r\n retArr.push(`return subKernelResult_${ this.name };`);\r\n } else {\r\n retArr.push('return ');\r\n this.astGeneric(ast.argument, retArr);\r\n retArr.push(';');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *literal value*\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astLiteral(ast, retArr) {\r\n\r\n // Reject non numeric literals\r\n if (isNaN(ast.value)) {\r\n throw this.astErrorOutput(\r\n 'Non-numeric literal not supported : ' + ast.value,\r\n ast\r\n );\r\n }\r\n\r\n retArr.push(ast.value);\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *binary* expression\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astBinaryExpression(ast, retArr) {\r\n retArr.push('(');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *identifier* expression\r\n * @param {Object} idtNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astIdentifierExpression(idtNode, retArr) {\r\n if (idtNode.type !== 'Identifier') {\r\n throw this.astErrorOutput(\r\n 'IdentifierExpression - not an Identifier',\r\n idtNode\r\n );\r\n }\r\n\r\n switch (idtNode.name) {\r\n case 'Infinity':\r\n retArr.push('Infinity');\r\n break;\r\n default:\r\n if (this.constants && this.constants.hasOwnProperty(idtNode.name)) {\r\n retArr.push('constants_' + idtNode.name);\r\n } else {\r\n retArr.push('user_' + idtNode.name);\r\n }\r\n }\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *for-loop* expression\r\n * @param {Object} forNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed webgl string\r\n */\r\n astForStatement(forNode, retArr) {\r\n if (forNode.type !== 'ForStatement') {\r\n throw this.astErrorOutput('Invalid for statement', forNode);\r\n }\r\n\r\n const initArr = [];\r\n const testArr = [];\r\n const updateArr = [];\r\n const bodyArr = [];\r\n let isSafe = null;\r\n\r\n if (forNode.init) {\r\n this.pushState('in-for-loop-init');\r\n this.astGeneric(forNode.init, initArr);\r\n for (let i = 0; i < initArr.length; i++) {\r\n if (initArr[i].includes && initArr[i].includes(',')) {\r\n isSafe = false;\r\n }\r\n }\r\n this.popState('in-for-loop-init');\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.test) {\r\n this.astGeneric(forNode.test, testArr);\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.update) {\r\n this.astGeneric(forNode.update, updateArr);\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.body) {\r\n this.pushState('loop-body');\r\n this.astGeneric(forNode.body, bodyArr);\r\n this.popState('loop-body');\r\n }\r\n\r\n // have all parts, now make them safe\r\n if (isSafe === null) {\r\n isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test);\r\n }\r\n\r\n if (isSafe) {\r\n retArr.push(`for (${initArr.join('')};${testArr.join('')};${updateArr.join('')}){\\n`);\r\n retArr.push(bodyArr.join(''));\r\n retArr.push('}\\n');\r\n } else {\r\n const iVariableName = this.getInternalVariableName('safeI');\r\n if (initArr.length > 0) {\r\n retArr.push(initArr.join(''), ';\\n');\r\n }\r\n retArr.push(`for (let ${iVariableName}=0;${iVariableName} 0) {\r\n retArr.push(`if (!${testArr.join('')}) break;\\n`);\r\n }\r\n retArr.push(bodyArr.join(''));\r\n retArr.push(`\\n${updateArr.join('')};`);\r\n retArr.push('}\\n');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *while* loop\r\n * @param {Object} whileNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed javascript string\r\n */\r\n astWhileStatement(whileNode, retArr) {\r\n if (whileNode.type !== 'WhileStatement') {\r\n throw this.astErrorOutput(\r\n 'Invalid while statement',\r\n whileNode\r\n );\r\n }\r\n\r\n retArr.push('for (let i = 0; i < LOOP_MAX; i++) {');\r\n retArr.push('if (');\r\n this.astGeneric(whileNode.test, retArr);\r\n retArr.push(') {\\n');\r\n this.astGeneric(whileNode.body, retArr);\r\n retArr.push('} else {\\n');\r\n retArr.push('break;\\n');\r\n retArr.push('}\\n');\r\n retArr.push('}\\n');\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *do while* loop\r\n * @param {Object} doWhileNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed webgl string\r\n */\r\n astDoWhileStatement(doWhileNode, retArr) {\r\n if (doWhileNode.type !== 'DoWhileStatement') {\r\n throw this.astErrorOutput(\r\n 'Invalid while statement',\r\n doWhileNode\r\n );\r\n }\r\n\r\n retArr.push('for (let i = 0; i < LOOP_MAX; i++) {');\r\n this.astGeneric(doWhileNode.body, retArr);\r\n retArr.push('if (!');\r\n this.astGeneric(doWhileNode.test, retArr);\r\n retArr.push(') {\\n');\r\n retArr.push('break;\\n');\r\n retArr.push('}\\n');\r\n retArr.push('}\\n');\r\n\r\n return retArr;\r\n\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Assignment* Expression\r\n * @param {Object} assNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astAssignmentExpression(assNode, retArr) {\r\n const declaration = this.getDeclaration(assNode.left);\r\n if (declaration && !declaration.assignable) {\r\n throw new this.astErrorOutput(`Variable ${assNode.left.name} is not assignable here`, assNode);\r\n }\r\n this.astGeneric(assNode.left, retArr);\r\n retArr.push(assNode.operator);\r\n this.astGeneric(assNode.right, retArr);\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Block* statement\r\n * @param {Object} bNode - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astBlockStatement(bNode, retArr) {\r\n if (this.isState('loop-body')) {\r\n this.pushState('block-body'); // this prevents recursive removal of braces\r\n for (let i = 0; i < bNode.body.length; i++) {\r\n this.astGeneric(bNode.body[i], retArr);\r\n }\r\n this.popState('block-body');\r\n } else {\r\n retArr.push('{\\n');\r\n for (let i = 0; i < bNode.body.length; i++) {\r\n this.astGeneric(bNode.body[i], retArr);\r\n }\r\n retArr.push('}\\n');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Variable Declaration*\r\n * @param {Object} varDecNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astVariableDeclaration(varDecNode, retArr) {\r\n if (varDecNode.kind === 'var' && this.warnVarUsage) {\r\n this.varWarn();\r\n }\r\n retArr.push(`${varDecNode.kind} `);\r\n const { declarations } = varDecNode;\r\n for (let i = 0; i < declarations.length; i++) {\r\n if (i > 0) {\r\n retArr.push(',');\r\n }\r\n this.astGeneric(declarations[i], retArr);\r\n }\r\n if (!this.isState('in-for-loop-init')) {\r\n retArr.push(';');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *If* Statement\r\n * @param {Object} ifNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astIfStatement(ifNode, retArr) {\r\n retArr.push('if (');\r\n this.astGeneric(ifNode.test, retArr);\r\n retArr.push(')');\r\n if (ifNode.consequent.type === 'BlockStatement') {\r\n this.astGeneric(ifNode.consequent, retArr);\r\n } else {\r\n retArr.push(' {\\n');\r\n this.astGeneric(ifNode.consequent, retArr);\r\n retArr.push('\\n}\\n');\r\n }\r\n\r\n if (ifNode.alternate) {\r\n retArr.push('else ');\r\n if (ifNode.alternate.type === 'BlockStatement') {\r\n this.astGeneric(ifNode.alternate, retArr);\r\n } else {\r\n retArr.push(' {\\n');\r\n this.astGeneric(ifNode.alternate, retArr);\r\n retArr.push('\\n}\\n');\r\n }\r\n }\r\n return retArr;\r\n\r\n }\r\n\r\n astSwitchStatement(ast, retArr) {\r\n const { discriminant, cases } = ast;\r\n retArr.push('switch (');\r\n this.astGeneric(discriminant, retArr);\r\n retArr.push(') {\\n');\r\n for (let i = 0; i < cases.length; i++) {\r\n if (cases[i].test === null) {\r\n retArr.push('default:\\n');\r\n this.astGeneric(cases[i].consequent, retArr);\r\n if (cases[i].consequent && cases[i].consequent.length > 0) {\r\n retArr.push('break;\\n');\r\n }\r\n continue;\r\n }\r\n retArr.push('case ');\r\n this.astGeneric(cases[i].test, retArr);\r\n retArr.push(':\\n');\r\n if (cases[i].consequent && cases[i].consequent.length > 0) {\r\n this.astGeneric(cases[i].consequent, retArr);\r\n retArr.push('break;\\n');\r\n }\r\n }\r\n retArr.push('\\n}');\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *This* expression\r\n * @param {Object} tNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astThisExpression(tNode, retArr) {\r\n retArr.push('_this');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Member* Expression\r\n * @param {Object} mNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astMemberExpression(mNode, retArr) {\r\n const {\r\n signature,\r\n type,\r\n property,\r\n xProperty,\r\n yProperty,\r\n zProperty,\r\n name,\r\n origin\r\n } = this.getMemberExpressionDetails(mNode);\r\n switch (signature) {\r\n case 'this.thread.value':\r\n retArr.push(`_this.thread.${ name }`);\r\n return retArr;\r\n case 'this.output.value':\r\n switch (name) {\r\n case 'x':\r\n retArr.push('outputX');\r\n break;\r\n case 'y':\r\n retArr.push('outputY');\r\n break;\r\n case 'z':\r\n retArr.push('outputZ');\r\n break;\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n }\r\n return retArr;\r\n case 'value':\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n case 'value[]':\r\n case 'value[][]':\r\n case 'value[][][]':\r\n case 'value.value':\r\n if (origin === 'Math') {\r\n retArr.push(Math[name]);\r\n return retArr;\r\n }\r\n switch (property) {\r\n case 'r':\r\n retArr.push(`user_${ name }[0]`);\r\n return retArr;\r\n case 'g':\r\n retArr.push(`user_${ name }[1]`);\r\n return retArr;\r\n case 'b':\r\n retArr.push(`user_${ name }[2]`);\r\n return retArr;\r\n case 'a':\r\n retArr.push(`user_${ name }[3]`);\r\n return retArr;\r\n }\r\n break;\r\n case 'this.constants.value':\r\n case 'this.constants.value[]':\r\n case 'this.constants.value[][]':\r\n case 'this.constants.value[][][]':\r\n break;\r\n case 'fn()[]':\r\n this.astGeneric(mNode.object, retArr);\r\n retArr.push('[');\r\n this.astGeneric(mNode.property, retArr);\r\n retArr.push(']');\r\n return retArr;\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n }\r\n\r\n if (!mNode.computed) {\r\n // handle simple types\r\n switch (type) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n case 'Boolean':\r\n retArr.push(`${origin}_${name}`);\r\n return retArr;\r\n }\r\n }\r\n\r\n // handle more complex types\r\n // argument may have come from a parent\r\n const markupName = `${origin}_${name}`;\r\n\r\n switch (type) {\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n case 'HTMLImageArray':\r\n case 'ArrayTexture(1)':\r\n case 'ArrayTexture(2)':\r\n case 'ArrayTexture(3)':\r\n case 'ArrayTexture(4)':\r\n case 'HTMLImage':\r\n default:\r\n let size;\r\n let isInput;\r\n if (origin === 'constants') {\r\n const constant = this.constants[name];\r\n isInput = this.constantTypes[name] === 'Input';\r\n size = isInput ? constant.size : null;\r\n } else {\r\n isInput = this.isInput(name);\r\n size = isInput ? this.argumentSizes[this.argumentNames.indexOf(name)] : null;\r\n }\r\n retArr.push(`${ markupName }`);\r\n if (zProperty && yProperty) {\r\n if (isInput) {\r\n retArr.push('[(');\r\n this.astGeneric(zProperty, retArr);\r\n retArr.push(`*${ this.dynamicArguments ? '(outputY * outputX)' : size[1] * size[0] })+(`);\r\n this.astGeneric(yProperty, retArr);\r\n retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`);\r\n this.astGeneric(xProperty, retArr);\r\n retArr.push(']');\r\n } else {\r\n retArr.push('[');\r\n this.astGeneric(zProperty, retArr);\r\n retArr.push(']');\r\n retArr.push('[');\r\n this.astGeneric(yProperty, retArr);\r\n retArr.push(']');\r\n retArr.push('[');\r\n this.astGeneric(xProperty, retArr);\r\n retArr.push(']');\r\n }\r\n } else if (yProperty) {\r\n if (isInput) {\r\n retArr.push('[(');\r\n this.astGeneric(yProperty, retArr);\r\n retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`);\r\n this.astGeneric(xProperty, retArr);\r\n retArr.push(']');\r\n } else {\r\n retArr.push('[');\r\n this.astGeneric(yProperty, retArr);\r\n retArr.push(']');\r\n retArr.push('[');\r\n this.astGeneric(xProperty, retArr);\r\n retArr.push(']');\r\n }\r\n } else if (typeof xProperty !== 'undefined') {\r\n retArr.push('[');\r\n this.astGeneric(xProperty, retArr);\r\n retArr.push(']');\r\n }\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *call* expression\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astCallExpression(ast, retArr) {\r\n if (ast.type !== 'CallExpression') {\r\n // Failure, unknown expression\r\n throw this.astErrorOutput('Unknown CallExpression', ast);\r\n }\r\n // Get the full function call, unrolled\r\n let functionName = this.astMemberExpressionUnroll(ast.callee);\r\n\r\n // Register the function into the called registry\r\n if (this.calledFunctions.indexOf(functionName) < 0) {\r\n this.calledFunctions.push(functionName);\r\n }\r\n\r\n const isMathFunction = this.isAstMathFunction(ast);\r\n\r\n // track the function was called\r\n if (this.onFunctionCall) {\r\n this.onFunctionCall(this.name, functionName, ast.arguments);\r\n }\r\n\r\n // Call the function\r\n retArr.push(functionName);\r\n\r\n // Open arguments space\r\n retArr.push('(');\r\n const targetTypes = this.lookupFunctionArgumentTypes(functionName) || [];\r\n // Add the arguments\r\n for (let i = 0; i < ast.arguments.length; ++i) {\r\n const argument = ast.arguments[i];\r\n\r\n // in order to track return type, even though this is CPU\r\n let argumentType = this.getType(argument);\r\n if (!targetTypes[i]) {\r\n this.triggerImplyArgumentType(functionName, i, argumentType, this);\r\n }\r\n\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n this.astGeneric(argument, retArr);\r\n }\r\n // Close arguments space\r\n retArr.push(')');\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Array* Expression\r\n * @param {Object} arrNode - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astArrayExpression(arrNode, retArr) {\r\n const arrLen = arrNode.elements.length;\r\n\r\n retArr.push('new Float32Array([');\r\n for (let i = 0; i < arrLen; ++i) {\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n const subNode = arrNode.elements[i];\r\n this.astGeneric(subNode, retArr)\r\n }\r\n retArr.push('])');\r\n\r\n return retArr;\r\n }\r\n\r\n astDebuggerStatement(arrNode, retArr) {\r\n retArr.push('debugger;');\r\n return retArr;\r\n }\r\n}\r\n","import { utils } from '../../utils'\r\n\r\nfunction constantsToString(constants, types) {\r\n const results = [];\r\n for (const name in types) {\r\n if (!types.hasOwnProperty(name)) continue;\r\n const type = types[name];\r\n const constant = constants[name];\r\n switch (type) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n case 'Boolean':\r\n results.push(`${name}:${constant}`);\r\n break;\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n results.push(`${name}:new ${constant.constructor.name}(${JSON.stringify(Array.from(constant))})`);\r\n break;\r\n }\r\n }\r\n return `{ ${ results.join() } }`;\r\n}\r\n\r\nexport function cpuKernelString(cpuKernel, name) {\r\n const header = [];\r\n const thisProperties = [];\r\n const beforeReturn = [];\r\n\r\n const useFunctionKeyword = !/^function/.test(cpuKernel.color.toString());\r\n\r\n header.push(\r\n ' const { context, canvas, constants: incomingConstants } = settings;',\r\n ` const output = new Int32Array(${JSON.stringify(Array.from(cpuKernel.output))});`,\r\n ` const _constantTypes = ${JSON.stringify(cpuKernel.constantTypes)};`,\r\n ` const _constants = ${constantsToString(cpuKernel.constants, cpuKernel.constantTypes)};`,\r\n );\r\n\r\n thisProperties.push(\r\n ' constants: _constants,',\r\n ' context,',\r\n ' output,',\r\n ' thread: {x: 0, y: 0, z: 0},',\r\n );\r\n\r\n if (cpuKernel.graphical) {\r\n header.push(` const _imageData = context.createImageData(${cpuKernel.output[0]}, ${cpuKernel.output[1]});`);\r\n header.push(` const _colorData = new Uint8ClampedArray(${cpuKernel.output[0]} * ${cpuKernel.output[1]} * 4);`);\r\n\r\n const colorFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.color.toString(), {\r\n thisLookup: (propertyName) => {\r\n switch (propertyName) {\r\n case '_colorData':\r\n return '_colorData';\r\n case '_imageData':\r\n return '_imageData';\r\n case 'output':\r\n return 'output';\r\n case 'thread':\r\n return 'this.thread';\r\n }\r\n return JSON.stringify(cpuKernel[propertyName]);\r\n },\r\n findDependency: (object, name) => {\r\n return null;\r\n }\r\n });\r\n\r\n const getPixelsFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.getPixels.toString(), {\r\n thisLookup: (propertyName) => {\r\n switch (propertyName) {\r\n case '_colorData':\r\n return '_colorData';\r\n case '_imageData':\r\n return '_imageData';\r\n case 'output':\r\n return 'output';\r\n case 'thread':\r\n return 'this.thread';\r\n }\r\n return JSON.stringify(cpuKernel[propertyName]);\r\n },\r\n findDependency: () => {\r\n return null;\r\n }\r\n });\r\n\r\n thisProperties.push(\r\n ' _imageData,',\r\n ' _colorData,',\r\n ` color: ${colorFn},`,\r\n );\r\n\r\n beforeReturn.push(\r\n ` kernel.getPixels = ${getPixelsFn};`\r\n );\r\n }\r\n\r\n const constantTypes = [];\r\n const constantKeys = Object.keys(cpuKernel.constantTypes);\r\n for (let i = 0; i < constantKeys.length; i++) {\r\n constantTypes.push(cpuKernel.constantTypes[constantKeys]);\r\n }\r\n if (cpuKernel.argumentTypes.indexOf('HTMLImageArray') !== -1 || constantTypes.indexOf('HTMLImageArray') !== -1) {\r\n const flattenedImageTo3DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._imageTo3DArray.toString(), {\r\n doNotDefine: ['canvas'],\r\n findDependency: (object, name) => {\r\n if (object === 'this') {\r\n return (useFunctionKeyword ? 'function ' : '') + cpuKernel[name].toString();\r\n }\r\n return null;\r\n },\r\n thisLookup: (propertyName) => {\r\n switch (propertyName) {\r\n case 'canvas':\r\n return;\r\n case 'context':\r\n return 'context';\r\n }\r\n }\r\n });\r\n beforeReturn.push(flattenedImageTo3DArray);\r\n thisProperties.push(` _mediaTo2DArray,`);\r\n thisProperties.push(` _imageTo3DArray,`);\r\n } else if (cpuKernel.argumentTypes.indexOf('HTMLImage') !== -1 || constantTypes.indexOf('HTMLImage') !== -1) {\r\n const flattenedImageTo2DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._mediaTo2DArray.toString(), {\r\n findDependency: (object, name) => {\r\n return null;\r\n },\r\n thisLookup: (propertyName) => {\r\n switch (propertyName) {\r\n case 'canvas':\r\n return 'settings.canvas';\r\n case 'context':\r\n return 'settings.context';\r\n }\r\n throw new Error('unhandled thisLookup');\r\n }\r\n });\r\n beforeReturn.push(flattenedImageTo2DArray);\r\n thisProperties.push(` _mediaTo2DArray,`);\r\n }\r\n\r\n return `function(settings) {\r\n${ header.join('\\n') }\r\n for (const p in _constantTypes) {\r\n if (!_constantTypes.hasOwnProperty(p)) continue;\r\n const type = _constantTypes[p];\r\n switch (type) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n case 'Boolean':\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n if (incomingConstants.hasOwnProperty(p)) {\r\n console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned');\r\n }\r\n continue;\r\n }\r\n if (!incomingConstants.hasOwnProperty(p)) {\r\n throw new Error('constant ' + p + ' not found');\r\n }\r\n _constants[p] = incomingConstants[p];\r\n }\r\n const kernel = (function() {\r\n${cpuKernel._kernelString}\r\n })\r\n .apply({ ${thisProperties.join('\\n')} });\r\n ${ beforeReturn.join('\\n') }\r\n return kernel;\r\n}`;\r\n}\r\n","import { Kernel } from '../kernel';\r\nimport { FunctionBuilder } from '../function-builder';\r\nimport { CPUFunctionNode } from './function-node';\r\nimport { utils } from '../../utils';\r\nimport { cpuKernelString } from './kernel-string';\r\n\r\n/**\r\n * @desc Kernel Implementation for CPU.\r\n *

Instantiates properties to the CPU Kernel.

\r\n */\r\nexport class CPUKernel extends Kernel {\r\n static getFeatures() {\r\n return this.features;\r\n }\r\n static get features() {\r\n return Object.freeze({\r\n kernelMap: true,\r\n isIntegerDivisionAccurate: true\r\n });\r\n }\r\n static get isSupported() {\r\n return true;\r\n }\r\n static isContextMatch(context) {\r\n return false;\r\n }\r\n /**\r\n * @desc The current mode in which gpu.js is executing.\r\n */\r\n static get mode() {\r\n return 'cpu';\r\n }\r\n\r\n static nativeFunctionArguments() {\r\n return null;\r\n }\r\n\r\n static nativeFunctionReturnType() {\r\n return null;\r\n }\r\n\r\n static combineKernels(combinedKernel) {\r\n return combinedKernel;\r\n }\r\n\r\n constructor(source, settings) {\r\n super(source, settings);\r\n this.mergeSettings(source.settings || settings);\r\n\r\n this._imageData = null;\r\n this._colorData = null;\r\n this._kernelString = null;\r\n this.thread = {\r\n x: 0,\r\n y: 0,\r\n z: 0\r\n };\r\n this.translatedSources = null;\r\n }\r\n\r\n initCanvas() {\r\n if (typeof document !== 'undefined') {\r\n return document.createElement('canvas');\r\n } else if (typeof OffscreenCanvas !== 'undefined') {\r\n return new OffscreenCanvas(0, 0);\r\n }\r\n }\r\n\r\n initContext() {\r\n if (!this.canvas) return null;\r\n return this.canvas.getContext('2d');\r\n }\r\n\r\n initPlugins(settings) {\r\n return [];\r\n }\r\n\r\n /**\r\n * @desc Validate settings related to Kernel, such as dimensions size, and auto output support.\r\n * @param {IArguments} args\r\n */\r\n validateSettings(args) {\r\n if (!this.output || this.output.length === 0) {\r\n if (args.length !== 1) {\r\n throw new Error('Auto output only supported for kernels with only one input');\r\n }\r\n\r\n const argType = utils.getVariableType(args[0], this.strictIntegers);\r\n if (argType === 'Array') {\r\n this.output = utils.getDimensions(argType);\r\n } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') {\r\n this.output = args[0].output;\r\n } else {\r\n throw new Error('Auto output not supported for input type: ' + argType);\r\n }\r\n }\r\n\r\n if (this.graphical) {\r\n if (this.output.length !== 2) {\r\n throw new Error('Output must have 2 dimensions on graphical mode');\r\n }\r\n }\r\n\r\n this.checkOutput();\r\n }\r\n\r\n translateSource() {\r\n this.leadingReturnStatement = this.output.length > 1 ? 'resultX[x] = ' : 'result[x] = ';\r\n if (this.subKernels) {\r\n const followingReturnStatement = []\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const {\r\n name\r\n } = this.subKernels[i];\r\n followingReturnStatement.push(this.output.length > 1 ? `resultX_${ name }[x] = subKernelResult_${ name };\\n` : `result_${ name }[x] = subKernelResult_${ name };\\n`);\r\n }\r\n this.followingReturnStatement = followingReturnStatement.join('');\r\n }\r\n const functionBuilder = FunctionBuilder.fromKernel(this, CPUFunctionNode);\r\n this.translatedSources = functionBuilder.getPrototypes('kernel');\r\n if (!this.graphical && !this.returnType) {\r\n this.returnType = functionBuilder.getKernelResultType();\r\n }\r\n }\r\n\r\n /**\r\n * @desc Builds the Kernel, by generating the kernel\r\n * string using thread dimensions, and arguments\r\n * supplied to the kernel.\r\n *\r\n *

If the graphical flag is enabled, canvas is used.

\r\n */\r\n build() {\r\n this.setupConstants();\r\n this.setupArguments(arguments);\r\n this.validateSettings(arguments);\r\n this.translateSource();\r\n\r\n if (this.graphical) {\r\n const {\r\n canvas,\r\n output\r\n } = this;\r\n if (!canvas) {\r\n throw new Error('no canvas available for using graphical output');\r\n }\r\n const width = output[0];\r\n const height = output[1] || 1;\r\n canvas.width = width;\r\n canvas.height = height;\r\n this._imageData = this.context.createImageData(width, height);\r\n this._colorData = new Uint8ClampedArray(width * height * 4);\r\n }\r\n\r\n const kernelString = this.getKernelString();\r\n this.kernelString = kernelString;\r\n\r\n if (this.debug) {\r\n console.log('Function output:');\r\n console.log(kernelString);\r\n }\r\n\r\n try {\r\n this.run = new Function([], kernelString).bind(this)();\r\n } catch (e) {\r\n console.error('An error occurred compiling the javascript: ', e);\r\n }\r\n }\r\n\r\n color(r, g, b, a) {\r\n if (typeof a === 'undefined') {\r\n a = 1;\r\n }\r\n\r\n r = Math.floor(r * 255);\r\n g = Math.floor(g * 255);\r\n b = Math.floor(b * 255);\r\n a = Math.floor(a * 255);\r\n\r\n const width = this.output[0];\r\n const height = this.output[1];\r\n\r\n const x = this.thread.x;\r\n const y = height - this.thread.y - 1;\r\n\r\n const index = x + y * width;\r\n\r\n this._colorData[index * 4 + 0] = r;\r\n this._colorData[index * 4 + 1] = g;\r\n this._colorData[index * 4 + 2] = b;\r\n this._colorData[index * 4 + 3] = a;\r\n }\r\n\r\n /**\r\n * @desc Generates kernel string for this kernel program.\r\n *\r\n *

If sub-kernels are supplied, they are also factored in.\r\n * This string can be saved by calling the `toString` method\r\n * and then can be reused later.

\r\n *\r\n * @returns {String} result\r\n *\r\n */\r\n getKernelString() {\r\n if (this._kernelString !== null) return this._kernelString;\r\n\r\n let kernelThreadString = null;\r\n let {\r\n translatedSources\r\n } = this;\r\n if (translatedSources.length > 1) {\r\n translatedSources = translatedSources.filter(fn => {\r\n if (/^function/.test(fn)) return fn;\r\n kernelThreadString = fn;\r\n return false;\r\n })\r\n } else {\r\n kernelThreadString = translatedSources.shift();\r\n }\r\n return this._kernelString = ` const LOOP_MAX = ${ this._getLoopMaxString() };\r\n ${ this.injectedNative || '' }\r\n const _this = this;\r\n ${ this._processConstants() }\r\n return (${ this.argumentNames.map(argumentName => 'user_' + argumentName).join(', ') }) => {\r\n ${ this._processArguments() }\r\n ${ this.graphical ? this._graphicalKernelBody(kernelThreadString) : this._resultKernelBody(kernelThreadString) }\r\n ${ translatedSources.length > 0 ? translatedSources.join('\\n') : '' }\r\n };`;\r\n }\r\n\r\n /**\r\n * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused.\r\n */\r\n toString() {\r\n return cpuKernelString(this);\r\n }\r\n\r\n /**\r\n * @desc Get the maximum loop size String.\r\n * @returns {String} result\r\n */\r\n _getLoopMaxString() {\r\n return (\r\n this.loopMaxIterations ?\r\n ` ${ parseInt(this.loopMaxIterations) };` :\r\n ' 1000;'\r\n );\r\n }\r\n\r\n _processConstants() {\r\n if (!this.constants) return '';\r\n\r\n const result = [];\r\n for (let p in this.constants) {\r\n const type = this.constantTypes[p];\r\n switch (type) {\r\n case 'HTMLImage':\r\n case 'HTMLVideo':\r\n result.push(` const constants_${p} = this._mediaTo2DArray(this.constants.${p});\\n`);\r\n break;\r\n case 'HTMLImageArray':\r\n result.push(` const constants_${p} = this._imageTo3DArray(this.constants.${p});\\n`);\r\n break;\r\n case 'Input':\r\n result.push(` const constants_${p} = this.constants.${p}.value;\\n`);\r\n break;\r\n default:\r\n result.push(` const constants_${p} = this.constants.${p};\\n`);\r\n }\r\n }\r\n return result.join('');\r\n }\r\n\r\n _processArguments() {\r\n const result = [];\r\n for (let i = 0; i < this.argumentTypes.length; i++) {\r\n const variableName = `user_${this.argumentNames[i]}`;\r\n switch (this.argumentTypes[i]) {\r\n case 'HTMLImage':\r\n case 'HTMLVideo':\r\n result.push(` ${variableName} = this._mediaTo2DArray(${variableName});\\n`);\r\n break;\r\n case 'HTMLImageArray':\r\n result.push(` ${variableName} = this._imageTo3DArray(${variableName});\\n`);\r\n break;\r\n case 'Input':\r\n result.push(` ${variableName} = ${variableName}.value;\\n`);\r\n break;\r\n case 'ArrayTexture(1)':\r\n case 'ArrayTexture(2)':\r\n case 'ArrayTexture(3)':\r\n case 'ArrayTexture(4)':\r\n case 'NumberTexture':\r\n case 'MemoryOptimizedNumberTexture':\r\n result.push(`\r\n if (${variableName}.toArray) {\r\n if (!_this.textureCache) {\r\n _this.textureCache = [];\r\n _this.arrayCache = [];\r\n }\r\n const textureIndex = _this.textureCache.indexOf(${variableName});\r\n if (textureIndex !== -1) {\r\n ${variableName} = _this.arrayCache[textureIndex];\r\n } else {\r\n _this.textureCache.push(${variableName});\r\n ${variableName} = ${variableName}.toArray();\r\n _this.arrayCache.push(${variableName});\r\n }\r\n }`);\r\n break;\r\n }\r\n }\r\n return result.join('');\r\n }\r\n\r\n _mediaTo2DArray(media) {\r\n const canvas = this.canvas;\r\n const width = media.width > 0 ? media.width : media.videoWidth;\r\n const height = media.height > 0 ? media.height : media.videoHeight;\r\n if (canvas.width < width) {\r\n canvas.width = width;\r\n }\r\n if (canvas.height < height) {\r\n canvas.height = height;\r\n }\r\n const ctx = this.context;\r\n ctx.drawImage(media, 0, 0, width, height);\r\n const pixelsData = ctx.getImageData(0, 0, width, height).data;\r\n const imageArray = new Array(height);\r\n let index = 0;\r\n for (let y = height - 1; y >= 0; y--) {\r\n const row = imageArray[y] = new Array(width);\r\n for (let x = 0; x < width; x++) {\r\n const pixel = new Float32Array(4);\r\n pixel[0] = pixelsData[index++] / 255; // r\r\n pixel[1] = pixelsData[index++] / 255; // g\r\n pixel[2] = pixelsData[index++] / 255; // b\r\n pixel[3] = pixelsData[index++] / 255; // a\r\n row[x] = pixel;\r\n }\r\n }\r\n return imageArray;\r\n }\r\n\r\n getPixels(flip) {\r\n const [width, height] = this.output;\r\n // cpu is not flipped by default\r\n return flip ? utils.flipPixels(this._imageData.data, width, height) : this._imageData.data.slice(0);\r\n }\r\n\r\n _imageTo3DArray(images) {\r\n const imagesArray = new Array(images.length);\r\n for (let i = 0; i < images.length; i++) {\r\n imagesArray[i] = this._mediaTo2DArray(images[i]);\r\n }\r\n return imagesArray;\r\n }\r\n\r\n _resultKernelBody(kernelString) {\r\n switch (this.output.length) {\r\n case 1:\r\n return this._resultKernel1DLoop(kernelString) + this._kernelOutput();\r\n case 2:\r\n return this._resultKernel2DLoop(kernelString) + this._kernelOutput();\r\n case 3:\r\n return this._resultKernel3DLoop(kernelString) + this._kernelOutput();\r\n default:\r\n throw new Error('unsupported size kernel');\r\n }\r\n }\r\n\r\n _graphicalKernelBody(kernelThreadString) {\r\n switch (this.output.length) {\r\n case 2:\r\n return this._graphicalKernel2DLoop(kernelThreadString) + this._graphicalOutput();\r\n default:\r\n throw new Error('unsupported size kernel');\r\n }\r\n }\r\n\r\n _graphicalOutput() {\r\n return `\r\n this._imageData.data.set(this._colorData);\r\n this.context.putImageData(this._imageData, 0, 0);\r\n return;`\r\n }\r\n\r\n _getKernelResultTypeConstructorString() {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n return 'Float32Array';\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n return 'Array';\r\n default:\r\n if (this.graphical) {\r\n return 'Float32Array';\r\n }\r\n throw new Error(`unhandled returnType ${ this.returnType }`);\r\n }\r\n }\r\n\r\n _resultKernel1DLoop(kernelString) {\r\n const {\r\n output\r\n } = this;\r\n const constructorString = this._getKernelResultTypeConstructorString();\r\n return ` const outputX = _this.output[0];\r\n const result = new ${constructorString}(outputX);\r\n ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new ${constructorString}(outputX);\\n`).join(' ') }\r\n ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\\n`).join(' ') }\r\n for (let x = 0; x < outputX; x++) {\r\n this.thread.x = x;\r\n this.thread.y = 0;\r\n this.thread.z = 0;\r\n ${ kernelString }\r\n }`;\r\n }\r\n\r\n _resultKernel2DLoop(kernelString) {\r\n const {\r\n output\r\n } = this;\r\n const constructorString = this._getKernelResultTypeConstructorString();\r\n return ` const outputX = _this.output[0];\r\n const outputY = _this.output[1];\r\n const result = new Array(outputY);\r\n ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\\n`).join(' ') }\r\n ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\\n`).join(' ') }\r\n for (let y = 0; y < outputY; y++) {\r\n this.thread.z = 0;\r\n this.thread.y = y;\r\n const resultX = result[y] = new ${constructorString}(outputX);\r\n ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\\n`).join('') }\r\n for (let x = 0; x < outputX; x++) {\r\n this.thread.x = x;\r\n ${ kernelString }\r\n }\r\n }`;\r\n }\r\n\r\n _graphicalKernel2DLoop(kernelString) {\r\n const {\r\n output\r\n } = this;\r\n const constructorString = this._getKernelResultTypeConstructorString();\r\n return ` const outputX = _this.output[0];\r\n const outputY = _this.output[1];\r\n ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\\n`).join(' ') }\r\n ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\\n`).join(' ') }\r\n for (let y = 0; y < outputY; y++) {\r\n this.thread.z = 0;\r\n this.thread.y = y;\r\n ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\\n`).join('') }\r\n for (let x = 0; x < outputX; x++) {\r\n this.thread.x = x;\r\n ${ kernelString }\r\n }\r\n }`;\r\n }\r\n\r\n _resultKernel3DLoop(kernelString) {\r\n const {\r\n output\r\n } = this;\r\n const constructorString = this._getKernelResultTypeConstructorString();\r\n return ` const outputX = _this.output[0];\r\n const outputY = _this.output[1];\r\n const outputZ = _this.output[2];\r\n const result = new Array(outputZ);\r\n ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputZ);\\n`).join(' ') }\r\n ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\\n`).join(' ') }\r\n for (let z = 0; z < outputZ; z++) {\r\n this.thread.z = z;\r\n const resultY = result[z] = new Array(outputY);\r\n ${ this._mapSubKernels(subKernel => `const resultY_${ subKernel.name } = result_${subKernel.name}[z] = new Array(outputY);\\n`).join(' ') }\r\n for (let y = 0; y < outputY; y++) {\r\n this.thread.y = y;\r\n const resultX = resultY[y] = new ${constructorString}(outputX);\r\n ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = resultY_${subKernel.name}[y] = new ${constructorString}(outputX);\\n`).join(' ') }\r\n for (let x = 0; x < outputX; x++) {\r\n this.thread.x = x;\r\n ${ kernelString }\r\n }\r\n }\r\n }`;\r\n }\r\n\r\n _kernelOutput() {\r\n if (!this.subKernels) {\r\n return '\\n return result;';\r\n }\r\n return `\\n return {\r\n result: result,\r\n ${ this.subKernels.map(subKernel => `${ subKernel.property }: result_${ subKernel.name }`).join(',\\n ') }\r\n };`;\r\n }\r\n\r\n _mapSubKernels(fn) {\r\n return this.subKernels === null ? [''] :\r\n this.subKernels.map(fn);\r\n }\r\n\r\n\r\n\r\n destroy(removeCanvasReference) {\r\n if (removeCanvasReference) {\r\n delete this.canvas;\r\n }\r\n }\r\n\r\n static destroyContext(context) {}\r\n\r\n toJSON() {\r\n const json = super.toJSON();\r\n json.functionNodes = FunctionBuilder.fromKernel(this, CPUFunctionNode).toJSON();\r\n return json;\r\n }\r\n\r\n setOutput(output) {\r\n super.setOutput(output);\r\n const [width, height] = this.output;\r\n if (this.graphical) {\r\n this._imageData = this.context.createImageData(width, height);\r\n this._colorData = new Uint8ClampedArray(width * height * 4);\r\n }\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { Texture } from '../../../texture';\r\n\r\nexport class GLTextureFloat extends Texture {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(1)';\r\n }\r\n renderRawOutput() {\r\n const { context: gl } = this;\r\n const framebuffer = gl.createFramebuffer();\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\r\n gl.framebufferTexture2D(\r\n gl.FRAMEBUFFER,\r\n gl.COLOR_ATTACHMENT0,\r\n gl.TEXTURE_2D,\r\n this.texture,\r\n 0\r\n );\r\n const result = new Float32Array(this.size[0] * this.size[1] * 4);\r\n gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.FLOAT, result);\r\n return result;\r\n }\r\n renderValues() {\r\n return this.renderRawOutput();\r\n }\r\n toArray() {\r\n return utils.erectFloat(this.renderValues(), this.output[0]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray2Float extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(2)';\r\n }\r\n toArray() {\r\n return utils.erectArray2(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray2Float2D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(2)';\r\n }\r\n toArray() {\r\n return utils.erect2DArray2(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray2Float3D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(2)';\r\n }\r\n toArray() {\r\n return utils.erect3DArray2(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray3Float extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(3)';\r\n }\r\n toArray() {\r\n return utils.erectArray3(this.renderValues(), this.output[0]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray3Float2D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(3)';\r\n }\r\n toArray() {\r\n return utils.erect2DArray3(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray3Float3D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(3)';\r\n }\r\n toArray() {\r\n return utils.erect3DArray3(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray4Float extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(4)';\r\n }\r\n toArray() {\r\n return utils.erectArray4(this.renderValues(), this.output[0]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray4Float2D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(4)';\r\n }\r\n toArray() {\r\n return utils.erect2DArray4(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray4Float3D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(4)';\r\n }\r\n toArray() {\r\n return utils.erect3DArray4(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureFloat2D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(1)';\r\n }\r\n toArray() {\r\n return utils.erect2DFloat(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureFloat3D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(1)';\r\n }\r\n toArray() {\r\n return utils.erect3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureMemoryOptimized extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'MemoryOptimizedNumberTexture';\r\n }\r\n toArray() {\r\n return utils.erectMemoryOptimizedFloat(this.renderValues(), this.output[0]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureMemoryOptimized2D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'MemoryOptimizedNumberTexture';\r\n }\r\n toArray() {\r\n return utils.erectMemoryOptimized2DFloat(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureMemoryOptimized3D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'MemoryOptimizedNumberTexture';\r\n }\r\n toArray() {\r\n return utils.erectMemoryOptimized3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { Texture } from '../../../texture';\r\n\r\nexport class GLTextureUnsigned extends Texture {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'NumberTexture';\r\n }\r\n renderRawOutput() {\r\n const { context: gl } = this;\r\n const framebuffer = gl.createFramebuffer();\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\r\n gl.framebufferTexture2D(\r\n gl.FRAMEBUFFER,\r\n gl.COLOR_ATTACHMENT0,\r\n gl.TEXTURE_2D,\r\n this.texture,\r\n 0\r\n );\r\n const result = new Uint8Array(this.size[0] * this.size[1] * 4);\r\n gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.UNSIGNED_BYTE, result);\r\n return result;\r\n }\r\n renderValues() {\r\n return new Float32Array(this.renderRawOutput().buffer);\r\n }\r\n toArray() {\r\n return utils.erectPackedFloat(this.renderValues(), this.output[0]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureUnsigned } from './unsigned';\r\n\r\nexport class GLTextureUnsigned2D extends GLTextureUnsigned {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'NumberTexture';\r\n }\r\n toArray() {\r\n return utils.erect2DPackedFloat(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureUnsigned } from './unsigned';\r\n\r\nexport class GLTextureUnsigned3D extends GLTextureUnsigned {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'NumberTexture';\r\n }\r\n toArray() {\r\n return utils.erect3DPackedFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { GLTextureUnsigned } from './unsigned';\r\n\r\nexport class GLTextureGraphical extends GLTextureUnsigned {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(4)';\r\n }\r\n toArray() {\r\n return this.renderValues();\r\n }\r\n}\r\n","import { Kernel } from '../kernel';\r\nimport { utils } from '../../utils';\r\nimport { GLTextureArray2Float } from './texture/array-2-float';\r\nimport { GLTextureArray2Float2D } from './texture/array-2-float-2d';\r\nimport { GLTextureArray2Float3D } from './texture/array-2-float-3d';\r\nimport { GLTextureArray3Float } from './texture/array-3-float';\r\nimport { GLTextureArray3Float2D } from './texture/array-3-float-2d';\r\nimport { GLTextureArray3Float3D } from './texture/array-3-float-3d';\r\nimport { GLTextureArray4Float } from './texture/array-4-float';\r\nimport { GLTextureArray4Float2D } from './texture/array-4-float-2d';\r\nimport { GLTextureArray4Float3D } from './texture/array-4-float-3d';\r\nimport { GLTextureFloat } from './texture/float';\r\nimport { GLTextureFloat2D } from './texture/float-2d';\r\nimport { GLTextureFloat3D } from './texture/float-3d';\r\nimport { GLTextureMemoryOptimized } from './texture/memory-optimized';\r\nimport { GLTextureMemoryOptimized2D } from './texture/memory-optimized-2d';\r\nimport { GLTextureMemoryOptimized3D } from './texture/memory-optimized-3d';\r\nimport { GLTextureUnsigned } from './texture/unsigned';\r\nimport { GLTextureUnsigned2D } from './texture/unsigned-2d';\r\nimport { GLTextureUnsigned3D } from './texture/unsigned-3d';\r\nimport { GLTextureGraphical } from './texture/graphical';\r\n\r\n/**\r\n * @abstract\r\n * @extends Kernel\r\n */\r\nexport class GLKernel extends Kernel {\r\n static get mode() {\r\n return 'gpu';\r\n }\r\n\r\n static getIsFloatRead() {\r\n const kernelString = `function kernelFunction() {\r\n return 1;\r\n }`;\r\n const kernel = new this(kernelString, {\r\n context: this.testContext,\r\n canvas: this.testCanvas,\r\n validate: false,\r\n output: [1],\r\n precision: 'single',\r\n returnType: 'Number',\r\n tactic: 'speed',\r\n });\r\n kernel.build();\r\n kernel.run();\r\n const result = kernel.renderOutput();\r\n kernel.destroy(true);\r\n return result[0] === 1;\r\n }\r\n\r\n static getIsIntegerDivisionAccurate() {\r\n function kernelFunction(v1, v2) {\r\n return v1[this.thread.x] / v2[this.thread.x];\r\n }\r\n const kernel = new this(kernelFunction.toString(), {\r\n context: this.testContext,\r\n canvas: this.testCanvas,\r\n validate: false,\r\n output: [2],\r\n returnType: 'Number',\r\n precision: 'unsigned',\r\n tactic: 'speed',\r\n });\r\n const args = [\r\n [6, 6030401],\r\n [3, 3991]\r\n ];\r\n kernel.build.apply(kernel, args);\r\n kernel.run.apply(kernel, args);\r\n const result = kernel.renderOutput();\r\n kernel.destroy(true);\r\n // have we not got whole numbers for 6/3 or 6030401/3991\r\n // add more here if others see this problem\r\n return result[0] === 2 && result[1] === 1511;\r\n }\r\n\r\n /**\r\n * @abstract\r\n */\r\n static get testCanvas() {\r\n throw new Error(`\"testCanvas\" not defined on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @abstract\r\n */\r\n static get testContext() {\r\n throw new Error(`\"testContext\" not defined on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @type {IKernelFeatures}\r\n */\r\n static get features() {\r\n throw new Error(`\"features\" not defined on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @abstract\r\n */\r\n static setupFeatureChecks() {\r\n throw new Error(`\"setupFeatureChecks\" not defined on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @desc Fix division by factor of 3 FP accuracy bug\r\n * @param {Boolean} fix - should fix\r\n */\r\n setFixIntegerDivisionAccuracy(fix) {\r\n this.fixIntegerDivisionAccuracy = fix;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Toggle output mode\r\n * @param {String} flag - 'single' or 'unsigned'\r\n */\r\n setPrecision(flag) {\r\n this.precision = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Toggle texture output mode\r\n * @param {Boolean} flag - true to enable floatTextures\r\n * @deprecated\r\n */\r\n setFloatTextures(flag) {\r\n utils.warnDeprecated('method', 'setFloatTextures', 'setOptimizeFloatMemory');\r\n this.floatTextures = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * A highly readable very forgiving micro-parser for a glsl function that gets argument types\r\n * @param {String} source\r\n * @returns {{argumentTypes: String[], argumentNames: String[]}}\r\n */\r\n static nativeFunctionArguments(source) {\r\n const argumentTypes = [];\r\n const argumentNames = [];\r\n const states = [];\r\n const isStartingVariableName = /^[a-zA-Z_]/;\r\n const isVariableChar = /[a-zA-Z_0-9]/;\r\n let i = 0;\r\n let argumentName = null;\r\n let argumentType = null;\r\n while (i < source.length) {\r\n const char = source[i];\r\n const nextChar = source[i + 1];\r\n const state = states.length > 0 ? states[states.length - 1] : null;\r\n\r\n // begin MULTI_LINE_COMMENT handling\r\n if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '*') {\r\n states.push('MULTI_LINE_COMMENT');\r\n i += 2;\r\n continue;\r\n } else if (state === 'MULTI_LINE_COMMENT' && char === '*' && nextChar === '/') {\r\n states.pop();\r\n i += 2;\r\n continue;\r\n }\r\n // end MULTI_LINE_COMMENT handling\r\n\r\n // begin COMMENT handling\r\n else if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '/') {\r\n states.push('COMMENT');\r\n i += 2;\r\n continue;\r\n } else if (state === 'COMMENT' && char === '\\n') {\r\n states.pop();\r\n i++;\r\n continue;\r\n }\r\n // end COMMENT handling\r\n\r\n // being FUNCTION_ARGUMENTS handling\r\n else if (state === null && char === '(') {\r\n states.push('FUNCTION_ARGUMENTS');\r\n i++;\r\n continue;\r\n } else if (state === 'FUNCTION_ARGUMENTS') {\r\n if (char === ')') {\r\n states.pop();\r\n break;\r\n }\r\n if (char === 'f' && nextChar === 'l' && source[i + 2] === 'o' && source[i + 3] === 'a' && source[i + 4] === 't' && source[i + 5] === ' ') {\r\n states.push('DECLARE_VARIABLE');\r\n argumentType = 'float';\r\n argumentName = '';\r\n i += 6;\r\n continue;\r\n } else if (char === 'i' && nextChar === 'n' && source[i + 2] === 't' && source[i + 3] === ' ') {\r\n states.push('DECLARE_VARIABLE');\r\n argumentType = 'int';\r\n argumentName = '';\r\n i += 4;\r\n continue;\r\n } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '2' && source[i + 4] === ' ') {\r\n states.push('DECLARE_VARIABLE');\r\n argumentType = 'vec2';\r\n argumentName = '';\r\n i += 5;\r\n continue;\r\n } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '3' && source[i + 4] === ' ') {\r\n states.push('DECLARE_VARIABLE');\r\n argumentType = 'vec3';\r\n argumentName = '';\r\n i += 5;\r\n continue;\r\n } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '4' && source[i + 4] === ' ') {\r\n states.push('DECLARE_VARIABLE');\r\n argumentType = 'vec4';\r\n argumentName = '';\r\n i += 5;\r\n continue;\r\n }\r\n }\r\n // end FUNCTION_ARGUMENTS handling\r\n\r\n // begin DECLARE_VARIABLE handling\r\n else if (state === 'DECLARE_VARIABLE') {\r\n if (argumentName === '') {\r\n if (char === ' ') {\r\n i++;\r\n continue;\r\n }\r\n if (!isStartingVariableName.test(char)) {\r\n throw new Error('variable name is not expected string');\r\n }\r\n }\r\n argumentName += char;\r\n if (!isVariableChar.test(nextChar)) {\r\n states.pop();\r\n argumentNames.push(argumentName);\r\n argumentTypes.push(typeMap[argumentType]);\r\n }\r\n }\r\n // end DECLARE_VARIABLE handling\r\n\r\n // Progress to next character\r\n i++;\r\n }\r\n if (states.length > 0) {\r\n throw new Error('GLSL function was not parsable');\r\n }\r\n return {\r\n argumentNames,\r\n argumentTypes,\r\n };\r\n }\r\n\r\n static nativeFunctionReturnType(source) {\r\n return typeMap[source.match(/int|float|vec[2-4]/)[0]];\r\n }\r\n\r\n static combineKernels(combinedKernel, lastKernel) {\r\n combinedKernel.apply(null, arguments);\r\n const {\r\n texSize,\r\n context,\r\n threadDim\r\n } = lastKernel.texSize;\r\n let result;\r\n if (lastKernel.precision === 'single') {\r\n const w = texSize[0];\r\n const h = Math.ceil(texSize[1] / 4);\r\n result = new Float32Array(w * h * 4 * 4);\r\n context.readPixels(0, 0, w, h * 4, context.RGBA, context.FLOAT, result);\r\n } else {\r\n const bytes = new Uint8Array(texSize[0] * texSize[1] * 4);\r\n context.readPixels(0, 0, texSize[0], texSize[1], context.RGBA, context.UNSIGNED_BYTE, bytes);\r\n result = new Float32Array(bytes.buffer);\r\n }\r\n\r\n result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]);\r\n\r\n if (lastKernel.output.length === 1) {\r\n return result;\r\n } else if (lastKernel.output.length === 2) {\r\n return utils.splitArray(result, lastKernel.output[0]);\r\n } else if (lastKernel.output.length === 3) {\r\n const cube = utils.splitArray(result, lastKernel.output[0] * lastKernel.output[1]);\r\n return cube.map(function(x) {\r\n return utils.splitArray(x, lastKernel.output[0]);\r\n });\r\n }\r\n }\r\n\r\n constructor(source, settings) {\r\n super(source, settings);\r\n this.transferValues = null;\r\n this.formatValues = null;\r\n this.TextureConstructor = null;\r\n this.renderOutput = null;\r\n this.renderRawOutput = null;\r\n this.texSize = null;\r\n this.translatedSource = null;\r\n this.renderStrategy = null;\r\n this.compiledFragmentShader = null;\r\n this.compiledVertexShader = null;\r\n }\r\n\r\n checkTextureSize() {\r\n const { features } = this.constructor;\r\n if (this.texSize[0] > features.maxTextureSize || this.texSize[1] > features.maxTextureSize) {\r\n throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${features.maxTextureSize},${features.maxTextureSize}]`);\r\n }\r\n }\r\n\r\n translateSource() {\r\n throw new Error(`\"translateSource\" not defined on ${this.constructor.name}`);\r\n }\r\n\r\n /**\r\n * Picks a render strategy for the now finally parsed kernel\r\n * @param args\r\n * @return {null|KernelOutput}\r\n */\r\n pickRenderStrategy(args) {\r\n if (this.graphical) {\r\n this.renderRawOutput = this.readPackedPixelsToUint8Array;\r\n this.transferValues = (pixels) => pixels;\r\n this.TextureConstructor = GLTextureGraphical;\r\n return null;\r\n }\r\n if (this.precision === 'unsigned') {\r\n this.renderRawOutput = this.readPackedPixelsToUint8Array;\r\n this.transferValues = this.readPackedPixelsToFloat32Array;\r\n if (this.pipeline) {\r\n this.renderOutput = this.renderTexture;\r\n if (this.subKernels !== null) {\r\n this.renderKernels = this.renderKernelsToTextures;\r\n }\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureUnsigned3D;\r\n this.renderStrategy = renderStrategy.PackedPixelTo3DFloat;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureUnsigned2D;\r\n this.renderStrategy = renderStrategy.PackedPixelTo2DFloat;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureUnsigned;\r\n this.renderStrategy = renderStrategy.PackedPixelToFloat;\r\n return null;\r\n }\r\n break;\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n return this.requestFallback(args);\r\n }\r\n } else {\r\n if (this.subKernels !== null) {\r\n this.renderKernels = this.renderKernelsToArrays;\r\n }\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n this.renderOutput = this.renderValues;\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureUnsigned3D;\r\n this.renderStrategy = renderStrategy.PackedPixelTo3DFloat;\r\n this.formatValues = utils.erect3DPackedFloat;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureUnsigned2D;\r\n this.renderStrategy = renderStrategy.PackedPixelTo2DFloat;\r\n this.formatValues = utils.erect2DPackedFloat;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureUnsigned;\r\n this.renderStrategy = renderStrategy.PackedPixelToFloat;\r\n this.formatValues = utils.erectPackedFloat;\r\n return null;\r\n }\r\n\r\n break;\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n return this.requestFallback(args);\r\n }\r\n }\r\n } else if (this.precision === 'single') {\r\n this.renderRawOutput = this.readFloatPixelsToFloat32Array;\r\n this.transferValues = this.readFloatPixelsToFloat32Array;\r\n if (this.pipeline) {\r\n this.renderStrategy = renderStrategy.FloatTexture;\r\n this.renderOutput = this.renderTexture;\r\n if (this.subKernels !== null) {\r\n this.renderKernels = this.renderKernelsToTextures;\r\n }\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n if (this.optimizeFloatMemory) {\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureMemoryOptimized3D;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureMemoryOptimized2D;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureMemoryOptimized;\r\n return null;\r\n }\r\n } else {\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureFloat3D;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureFloat2D;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureFloat;\r\n return null;\r\n }\r\n }\r\n break;\r\n case 'Array(2)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float3D;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float2D;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray2Float;\r\n return null;\r\n }\r\n break;\r\n case 'Array(3)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float3D;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float2D;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray3Float;\r\n return null;\r\n }\r\n break;\r\n case 'Array(4)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float3D;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float2D;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray4Float;\r\n return null;\r\n }\r\n }\r\n }\r\n this.renderOutput = this.renderValues;\r\n if (this.subKernels !== null) {\r\n this.renderKernels = this.renderKernelsToArrays;\r\n }\r\n if (this.optimizeFloatMemory) {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureMemoryOptimized3D;\r\n this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized3DFloat;\r\n this.formatValues = utils.erectMemoryOptimized3DFloat;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureMemoryOptimized2D;\r\n this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized2DFloat;\r\n this.formatValues = utils.erectMemoryOptimized2DFloat;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureMemoryOptimized;\r\n this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimizedFloat;\r\n this.formatValues = utils.erectMemoryOptimizedFloat;\r\n return null;\r\n }\r\n break;\r\n case 'Array(2)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray2;\r\n this.formatValues = utils.erect3DArray2;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray2;\r\n this.formatValues = utils.erect2DArray2;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray2Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray2;\r\n this.formatValues = utils.erectArray2;\r\n return null;\r\n }\r\n break;\r\n case 'Array(3)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray3;\r\n this.formatValues = utils.erect3DArray3;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray3;\r\n this.formatValues = utils.erect2DArray3;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray3Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray3;\r\n this.formatValues = utils.erectArray3;\r\n return null;\r\n }\r\n break;\r\n case 'Array(4)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray4;\r\n this.formatValues = utils.erect3DArray4;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray4;\r\n this.formatValues = utils.erect2DArray4;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray4Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray4;\r\n this.formatValues = utils.erectArray4;\r\n return null;\r\n }\r\n }\r\n } else {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureFloat3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DFloat;\r\n this.formatValues = utils.erect3DFloat;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureFloat2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DFloat;\r\n this.formatValues = utils.erect2DFloat;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureFloat;\r\n this.renderStrategy = renderStrategy.FloatPixelToFloat;\r\n this.formatValues = utils.erectFloat;\r\n return null;\r\n }\r\n break;\r\n case 'Array(2)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray2;\r\n this.formatValues = utils.erect3DArray2;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray2;\r\n this.formatValues = utils.erect2DArray2;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray2Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray2;\r\n this.formatValues = utils.erectArray2;\r\n return null;\r\n }\r\n break;\r\n case 'Array(3)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray3;\r\n this.formatValues = utils.erect3DArray3;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray3;\r\n this.formatValues = utils.erect2DArray3;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray3Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray3;\r\n this.formatValues = utils.erectArray3;\r\n return null;\r\n }\r\n break;\r\n case 'Array(4)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray4;\r\n this.formatValues = utils.erect3DArray4;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray4;\r\n this.formatValues = utils.erect2DArray4;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray4Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray4;\r\n this.formatValues = utils.erectArray4;\r\n return null;\r\n }\r\n }\r\n }\r\n } else {\r\n throw new Error(`unhandled precision of \"${this.precision}\"`);\r\n }\r\n\r\n throw new Error(`unhandled return type \"${this.returnType}\"`);\r\n }\r\n\r\n /**\r\n * @abstract\r\n * @returns String\r\n */\r\n getKernelString() {\r\n throw new Error(`abstract method call`);\r\n }\r\n\r\n getMainResultTexture() {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Integer':\r\n case 'Number':\r\n return this.getMainResultNumberTexture();\r\n case 'Array(2)':\r\n return this.getMainResultArray2Texture();\r\n case 'Array(3)':\r\n return this.getMainResultArray3Texture();\r\n case 'Array(4)':\r\n return this.getMainResultArray4Texture();\r\n default:\r\n throw new Error(`unhandled returnType type ${ this.returnType }`);\r\n }\r\n }\r\n\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultKernelNumberTexture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultSubKernelNumberTexture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultKernelArray2Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultSubKernelArray2Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultKernelArray3Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultSubKernelArray3Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultKernelArray4Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultSubKernelArray4Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultGraphical() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultMemoryOptimizedFloats() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultPackedPixels() {\r\n throw new Error(`abstract method call`);\r\n }\r\n\r\n getMainResultString() {\r\n if (this.graphical) {\r\n return this.getMainResultGraphical();\r\n } else if (this.precision === 'single') {\r\n if (this.optimizeFloatMemory) {\r\n return this.getMainResultMemoryOptimizedFloats();\r\n }\r\n return this.getMainResultTexture();\r\n } else {\r\n return this.getMainResultPackedPixels();\r\n }\r\n }\r\n\r\n getMainResultNumberTexture() {\r\n return utils.linesToString(this.getMainResultKernelNumberTexture()) +\r\n utils.linesToString(this.getMainResultSubKernelNumberTexture());\r\n }\r\n\r\n getMainResultArray2Texture() {\r\n return utils.linesToString(this.getMainResultKernelArray2Texture()) +\r\n utils.linesToString(this.getMainResultSubKernelArray2Texture());\r\n }\r\n\r\n getMainResultArray3Texture() {\r\n return utils.linesToString(this.getMainResultKernelArray3Texture()) +\r\n utils.linesToString(this.getMainResultSubKernelArray3Texture());\r\n }\r\n\r\n getMainResultArray4Texture() {\r\n return utils.linesToString(this.getMainResultKernelArray4Texture()) +\r\n utils.linesToString(this.getMainResultSubKernelArray4Texture());\r\n }\r\n\r\n /**\r\n *\r\n * @return {string}\r\n */\r\n getFloatTacticDeclaration() {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'precision lowp float;\\n';\r\n case 'performance':\r\n return 'precision highp float;\\n';\r\n case 'balanced':\r\n default:\r\n return 'precision mediump float;\\n';\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @return {string}\r\n */\r\n getIntTacticDeclaration() {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'precision lowp int;\\n';\r\n case 'performance':\r\n return 'precision highp int;\\n';\r\n case 'balanced':\r\n default:\r\n return 'precision mediump int;\\n';\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @return {string}\r\n */\r\n getSampler2DTacticDeclaration() {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'precision lowp sampler2D;\\n';\r\n case 'performance':\r\n return 'precision highp sampler2D;\\n';\r\n case 'balanced':\r\n default:\r\n return 'precision mediump sampler2D;\\n';\r\n }\r\n }\r\n\r\n getSampler2DArrayTacticDeclaration() {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'precision lowp sampler2DArray;\\n';\r\n case 'performance':\r\n return 'precision highp sampler2DArray;\\n';\r\n case 'balanced':\r\n default:\r\n return 'precision mediump sampler2DArray;\\n';\r\n }\r\n }\r\n\r\n renderTexture() {\r\n return new this.TextureConstructor({\r\n texture: this.outputTexture,\r\n size: this.texSize,\r\n dimensions: this.threadDim,\r\n output: this.output,\r\n context: this.context,\r\n });\r\n }\r\n readPackedPixelsToUint8Array() {\r\n if (this.precision !== 'unsigned') throw new Error('Requires this.precision to be \"unsigned\"');\r\n const {\r\n texSize,\r\n context: gl\r\n } = this;\r\n const result = new Uint8Array(texSize[0] * texSize[1] * 4);\r\n gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, result);\r\n return result;\r\n }\r\n\r\n readPackedPixelsToFloat32Array() {\r\n return new Float32Array(this.readPackedPixelsToUint8Array().buffer);\r\n }\r\n\r\n readFloatPixelsToFloat32Array() {\r\n if (this.precision !== 'single') throw new Error('Requires this.precision to be \"single\"');\r\n const {\r\n texSize,\r\n context: gl\r\n } = this;\r\n const w = texSize[0];\r\n const h = texSize[1];\r\n const result = new Float32Array(w * h * 4);\r\n gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result);\r\n return result;\r\n }\r\n\r\n readMemoryOptimizedFloatPixelsToFloat32Array() {\r\n if (this.precision !== 'single') throw new Error('Requires this.precision to be \"single\"');\r\n const {\r\n texSize,\r\n context: gl\r\n } = this;\r\n const w = texSize[0];\r\n const h = texSize[1];\r\n const result = new Float32Array(w * h * 4);\r\n gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result);\r\n return result;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Boolean} [flip]\r\n * @return {Uint8Array}\r\n */\r\n getPixels(flip) {\r\n const {\r\n context: gl,\r\n output\r\n } = this;\r\n const [width, height] = output;\r\n const pixels = new Uint8Array(width * height * 4);\r\n gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);\r\n // flipped by default, so invert\r\n return new Uint8ClampedArray((flip ? pixels : utils.flipPixels(pixels, width, height)).buffer);\r\n }\r\n\r\n renderKernelsToArrays() {\r\n const result = {\r\n result: this.renderOutput(),\r\n };\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n result[this.subKernels[i].property] = new this.TextureConstructor({\r\n texture: this.subKernelOutputTextures[i],\r\n size: this.texSize,\r\n dimensions: this.threadDim,\r\n output: this.output,\r\n context: this.context,\r\n }).toArray();\r\n }\r\n return result;\r\n }\r\n\r\n renderKernelsToTextures() {\r\n const result = {\r\n result: this.renderOutput(),\r\n };\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n result[this.subKernels[i].property] = new this.TextureConstructor({\r\n texture: this.subKernelOutputTextures[i],\r\n size: this.texSize,\r\n dimensions: this.threadDim,\r\n output: this.output,\r\n context: this.context,\r\n });\r\n }\r\n return result;\r\n }\r\n\r\n setOutput(output) {\r\n super.setOutput(output);\r\n if (this.program) {\r\n this.threadDim = [this.output[0], this.output[1] || 1, this.output[2] || 1];\r\n this.texSize = utils.getKernelTextureSize({\r\n optimizeFloatMemory: this.optimizeFloatMemory,\r\n precision: this.precision,\r\n }, this.output);\r\n const { context: gl } = this;\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n this.updateMaxTexSize();\r\n this.framebuffer.width = this.texSize[0];\r\n this.framebuffer.height = this.texSize[1];\r\n this.context.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);\r\n this.canvas.width = this.maxTexSize[0];\r\n this.canvas.height = this.maxTexSize[1];\r\n this._setupOutputTexture();\r\n if (this.subKernels && this.subKernels.length > 0) {\r\n this._setupSubOutputTextures();\r\n }\r\n }\r\n return this;\r\n }\r\n renderValues() {\r\n return this.formatValues(\r\n this.transferValues(),\r\n this.output[0],\r\n this.output[1],\r\n this.output[2]\r\n );\r\n }\r\n}\r\n\r\nexport const renderStrategy = Object.freeze({\r\n PackedPixelToUint8Array: Symbol('PackedPixelToUint8Array'),\r\n PackedPixelToFloat: Symbol('PackedPixelToFloat'),\r\n PackedPixelTo2DFloat: Symbol('PackedPixelTo2DFloat'),\r\n PackedPixelTo3DFloat: Symbol('PackedPixelTo3DFloat'),\r\n PackedTexture: Symbol('PackedTexture'),\r\n FloatPixelToFloat32Array: Symbol('FloatPixelToFloat32Array'),\r\n FloatPixelToFloat: Symbol('FloatPixelToFloat'),\r\n FloatPixelTo2DFloat: Symbol('FloatPixelTo2DFloat'),\r\n FloatPixelTo3DFloat: Symbol('FloatPixelTo3DFloat'),\r\n FloatPixelToArray2: Symbol('FloatPixelToArray2'),\r\n FloatPixelTo2DArray2: Symbol('FloatPixelTo2DArray2'),\r\n FloatPixelTo3DArray2: Symbol('FloatPixelTo3DArray2'),\r\n FloatPixelToArray3: Symbol('FloatPixelToArray3'),\r\n FloatPixelTo2DArray3: Symbol('FloatPixelTo2DArray3'),\r\n FloatPixelTo3DArray3: Symbol('FloatPixelTo3DArray3'),\r\n FloatPixelToArray4: Symbol('FloatPixelToArray4'),\r\n FloatPixelTo2DArray4: Symbol('FloatPixelTo2DArray4'),\r\n FloatPixelTo3DArray4: Symbol('FloatPixelTo3DArray4'),\r\n FloatTexture: Symbol('FloatTexture'),\r\n MemoryOptimizedFloatPixelToMemoryOptimizedFloat: Symbol('MemoryOptimizedFloatPixelToFloat'),\r\n MemoryOptimizedFloatPixelToMemoryOptimized2DFloat: Symbol('MemoryOptimizedFloatPixelTo2DFloat'),\r\n MemoryOptimizedFloatPixelToMemoryOptimized3DFloat: Symbol('MemoryOptimizedFloatPixelTo3DFloat'),\r\n});\r\n\r\nconst typeMap = {\r\n int: 'Integer',\r\n float: 'Number',\r\n vec2: 'Array(2)',\r\n vec3: 'Array(3)',\r\n vec4: 'Array(4)',\r\n};\r\n","import { utils } from '../../utils';\r\nimport { FunctionNode } from '../function-node';\r\n// Closure capture for the ast function, prevent collision with existing AST functions\r\n// The prefixes to use\r\nconst jsMathPrefix = 'Math.';\r\nconst localPrefix = 'this.';\r\n\r\n/**\r\n * @desc [INTERNAL] Takes in a function node, and does all the AST voodoo required to toString its respective WebGL code\r\n * @extends FunctionNode\r\n * @returns the converted WebGL function string\r\n */\r\nexport class WebGLFunctionNode extends FunctionNode {\r\n constructor(source, settings) {\r\n super(source, settings);\r\n if (settings && settings.hasOwnProperty('fixIntegerDivisionAccuracy')) {\r\n this.fixIntegerDivisionAccuracy = settings.fixIntegerDivisionAccuracy;\r\n }\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for to its *named function*\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astFunction(ast, retArr) {\r\n // Setup function return type and name\r\n if (this.isRootKernel) {\r\n retArr.push('void');\r\n } else {\r\n // looking up return type, this is a little expensive, and can be avoided if returnType is set\r\n let lastReturn = null;\r\n if (!this.returnType) {\r\n const lastReturn = this.findLastReturn();\r\n if (lastReturn) {\r\n this.returnType = this.getType(ast.body);\r\n if (this.returnType === 'LiteralInteger') {\r\n this.returnType = 'Number';\r\n }\r\n }\r\n }\r\n\r\n const { returnType } = this;\r\n if (!returnType) {\r\n retArr.push('void');\r\n } else {\r\n const type = typeMap[returnType];\r\n if (!type) {\r\n throw new Error(`unknown type ${returnType}`);\r\n }\r\n retArr.push(type);\r\n }\r\n }\r\n retArr.push(' ');\r\n retArr.push(this.name);\r\n retArr.push('(');\r\n\r\n if (!this.isRootKernel) {\r\n // Arguments handling\r\n for (let i = 0; i < this.argumentNames.length; ++i) {\r\n const argumentName = this.argumentNames[i];\r\n\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n let argumentType = this.argumentTypes[this.argumentNames.indexOf(argumentName)];\r\n // The type is too loose ended, here we descide to solidify a type, lets go with float\r\n if (!argumentType) {\r\n throw this.astErrorOutput(`Unknown argument ${argumentName} type`, ast);\r\n }\r\n if (argumentType === 'LiteralInteger') {\r\n this.argumentTypes[i] = argumentType = 'Number';\r\n }\r\n const type = typeMap[argumentType];\r\n if (!type) {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n retArr.push(type);\r\n retArr.push(' ');\r\n retArr.push('user_');\r\n retArr.push(argumentName);\r\n }\r\n }\r\n\r\n // Function opening\r\n retArr.push(') {\\n');\r\n\r\n // Body statement iteration\r\n for (let i = 0; i < ast.body.body.length; ++i) {\r\n this.astGeneric(ast.body.body[i], retArr);\r\n retArr.push('\\n');\r\n }\r\n\r\n // Function closing\r\n retArr.push('}\\n');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for to *return* statement\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astReturnStatement(ast, retArr) {\r\n if (!ast.argument) throw this.astErrorOutput('Unexpected return statement', ast);\r\n this.pushState('skip-literal-correction');\r\n const type = this.getType(ast.argument);\r\n this.popState('skip-literal-correction');\r\n\r\n const result = [];\r\n\r\n if (!this.returnType) {\r\n if (type === 'LiteralInteger' || type === 'Integer') {\r\n this.returnType = 'Number';\r\n } else {\r\n this.returnType = type;\r\n }\r\n }\r\n\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Number':\r\n case 'Float':\r\n switch (type) {\r\n case 'Integer':\r\n result.push('float(');\r\n this.astGeneric(ast.argument, result);\r\n result.push(')');\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(ast.argument, result);\r\n\r\n // Running astGeneric forces the LiteralInteger to pick a type, and here, if we are returning a float, yet\r\n // the LiteralInteger has picked to be an integer because of constraints on it we cast it to float.\r\n if (this.getType(ast) === 'Integer') {\r\n result.unshift('float(');\r\n result.push(')');\r\n }\r\n break;\r\n default:\r\n this.astGeneric(ast.argument, result);\r\n }\r\n break;\r\n case 'Integer':\r\n switch (type) {\r\n case 'Float':\r\n case 'Number':\r\n this.castValueToInteger(ast.argument, result);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(ast.argument, result);\r\n break;\r\n default:\r\n this.astGeneric(ast.argument, result);\r\n }\r\n break;\r\n case 'Array(4)':\r\n case 'Array(3)':\r\n case 'Array(2)':\r\n case 'Input':\r\n this.astGeneric(ast.argument, result);\r\n break;\r\n default:\r\n throw this.astErrorOutput(`unhandled return type ${this.returnType}`, ast);\r\n }\r\n\r\n if (this.isRootKernel) {\r\n retArr.push(`kernelResult = ${ result.join('') };`);\r\n retArr.push('return;');\r\n } else if (this.isSubKernel) {\r\n retArr.push(`subKernelResult_${ this.name } = ${ result.join('') };`);\r\n retArr.push(`return subKernelResult_${ this.name };`);\r\n } else {\r\n retArr.push(`return ${ result.join('') };`);\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *literal value*\r\n *\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n *\r\n * @returns {Array} the append retArr\r\n */\r\n astLiteral(ast, retArr) {\r\n // Reject non numeric literals\r\n if (isNaN(ast.value)) {\r\n throw this.astErrorOutput(\r\n 'Non-numeric literal not supported : ' + ast.value,\r\n ast\r\n );\r\n }\r\n\r\n const key = `${ast.start},${ast.end}`;\r\n if (Number.isInteger(ast.value)) {\r\n if (this.isState('in-for-loop-init') || this.isState('casting-to-integer') || this.isState('building-integer')) {\r\n this.literalTypes[key] = 'Integer';\r\n retArr.push(`${ast.value}`);\r\n } else if (this.isState('casting-to-float') || this.isState('building-float')) {\r\n this.literalTypes[key] = 'Number';\r\n retArr.push(`${ast.value}.0`);\r\n } else {\r\n this.literalTypes[key] = 'Number';\r\n retArr.push(`${ast.value}.0`);\r\n }\r\n } else if (this.isState('casting-to-integer') || this.isState('building-integer')) {\r\n this.literalTypes[key] = 'Integer';\r\n retArr.push(Math.round(ast.value));\r\n } else {\r\n this.literalTypes[key] = 'Number';\r\n retArr.push(`${ast.value}`);\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *binary* expression\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astBinaryExpression(ast, retArr) {\r\n if (this.checkAndUpconvertOperator(ast, retArr)) {\r\n return retArr;\r\n }\r\n\r\n if (this.fixIntegerDivisionAccuracy && ast.operator === '/') {\r\n retArr.push('div_with_int_check(');\r\n this.pushState('building-float');\r\n switch (this.getType(ast.left)) {\r\n case 'Integer':\r\n this.castValueToFloat(ast.left, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(ast.left, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.left, retArr);\r\n }\r\n retArr.push(', ');\r\n switch (this.getType(ast.right)) {\r\n case 'Integer':\r\n this.castValueToFloat(ast.right, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(ast.right, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.right, retArr);\r\n }\r\n this.popState('building-float');\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n retArr.push('(');\r\n const leftType = this.getType(ast.left) || 'Number';\r\n const rightType = this.getType(ast.right) || 'Number';\r\n if (!leftType || !rightType) {\r\n throw this.astErrorOutput(`Unhandled binary expression`, ast);\r\n }\r\n const key = leftType + ' & ' + rightType;\r\n switch (key) {\r\n case 'Integer & Integer':\r\n this.pushState('building-integer');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-integer');\r\n break;\r\n case 'Number & Float':\r\n case 'Float & Number':\r\n case 'Float & Float':\r\n case 'Number & Number':\r\n this.pushState('building-float');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-float');\r\n break;\r\n case 'LiteralInteger & LiteralInteger':\r\n if (this.isState('casting-to-integer') || this.isState('building-integer')) {\r\n this.pushState('building-integer');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-integer');\r\n } else {\r\n this.pushState('building-float');\r\n this.castLiteralToFloat(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castLiteralToFloat(ast.right, retArr);\r\n this.popState('building-float');\r\n }\r\n break;\r\n\r\n case 'Integer & Float':\r\n case 'Integer & Number':\r\n if (ast.operator === '>' || ast.operator === '<' && ast.right.type === 'Literal') {\r\n // if right value is actually a float, don't loose that information, cast left to right rather than the usual right to left\r\n if (!Number.isInteger(ast.right.value)) {\r\n this.pushState('building-float');\r\n this.castValueToFloat(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-float');\r\n break;\r\n }\r\n }\r\n this.pushState('building-integer');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.pushState('casting-to-integer');\r\n if (ast.right.type === 'Literal') {\r\n const literalResult = [];\r\n this.astGeneric(ast.right, literalResult);\r\n const literalType = this.getType(ast.right);\r\n if (literalType === 'Integer') {\r\n retArr.push(literalResult.join(''));\r\n } else {\r\n throw this.astErrorOutput(`Unhandled binary expression with literal`, ast);\r\n }\r\n } else {\r\n retArr.push('int(');\r\n this.astGeneric(ast.right, retArr);\r\n retArr.push(')');\r\n }\r\n this.popState('casting-to-integer');\r\n this.popState('building-integer');\r\n break;\r\n case 'Integer & LiteralInteger':\r\n this.pushState('building-integer');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castLiteralToInteger(ast.right, retArr);\r\n this.popState('building-integer');\r\n break;\r\n\r\n case 'Number & Integer':\r\n this.pushState('building-float');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castValueToFloat(ast.right, retArr);\r\n this.popState('building-float');\r\n break;\r\n case 'Float & LiteralInteger':\r\n case 'Number & LiteralInteger':\r\n if (this.isState('in-for-loop-test')) {\r\n this.pushState('building-integer');\r\n retArr.push('int(');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(')');\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castLiteralToInteger(ast.right, retArr);\r\n this.popState('building-integer');\r\n } else {\r\n this.pushState('building-float');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castLiteralToFloat(ast.right, retArr);\r\n this.popState('building-float');\r\n }\r\n break;\r\n case 'LiteralInteger & Float':\r\n case 'LiteralInteger & Number':\r\n if (this.isState('in-for-loop-test') || this.isState('in-for-loop-init') || this.isState('casting-to-integer')) {\r\n this.pushState('building-integer');\r\n this.castLiteralToInteger(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castValueToInteger(ast.right, retArr);\r\n this.popState('building-integer');\r\n } else {\r\n this.pushState('building-float');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.pushState('casting-to-float');\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('casting-to-float');\r\n this.popState('building-float');\r\n }\r\n break;\r\n case 'LiteralInteger & Integer':\r\n this.pushState('building-integer');\r\n this.castLiteralToInteger(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-integer');\r\n break;\r\n\r\n case 'Boolean & Boolean':\r\n this.pushState('building-boolean');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-boolean');\r\n break;\r\n\r\n case 'Float & Integer':\r\n this.pushState('building-float');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castValueToFloat(ast.right, retArr);\r\n this.popState('building-float');\r\n break;\r\n\r\n default:\r\n throw this.astErrorOutput(`Unhandled binary expression between ${key}`, ast);\r\n }\r\n retArr.push(')');\r\n\r\n return retArr;\r\n }\r\n\r\n checkAndUpconvertOperator(ast, retArr) {\r\n const bitwiseResult = this.checkAndUpconvertBitwiseOperators(ast, retArr);\r\n if (bitwiseResult) {\r\n return bitwiseResult;\r\n }\r\n const upconvertableOperators = {\r\n '%': 'mod',\r\n '**': 'pow',\r\n };\r\n const foundOperator = upconvertableOperators[ast.operator];\r\n if (!foundOperator) return null;\r\n retArr.push(foundOperator);\r\n retArr.push('(');\r\n switch (this.getType(ast.left)) {\r\n case 'Integer':\r\n this.castValueToFloat(ast.left, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(ast.left, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.left, retArr);\r\n }\r\n retArr.push(',');\r\n switch (this.getType(ast.right)) {\r\n case 'Integer':\r\n this.castValueToFloat(ast.right, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(ast.right, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.right, retArr);\r\n }\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n checkAndUpconvertBitwiseOperators(ast, retArr) {\r\n const upconvertableOperators = {\r\n '&': 'bitwiseAnd',\r\n '|': 'bitwiseOr',\r\n '^': 'bitwiseXOR',\r\n '<<': 'bitwiseZeroFillLeftShift',\r\n '>>': 'bitwiseSignedRightShift',\r\n '>>>': 'bitwiseZeroFillRightShift',\r\n };\r\n const foundOperator = upconvertableOperators[ast.operator];\r\n if (!foundOperator) return null;\r\n retArr.push(foundOperator);\r\n retArr.push('(');\r\n const leftType = this.getType(ast.left);\r\n switch (leftType) {\r\n case 'Number':\r\n case 'Float':\r\n this.castValueToInteger(ast.left, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(ast.left, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.left, retArr);\r\n }\r\n retArr.push(',');\r\n const rightType = this.getType(ast.right);\r\n switch (rightType) {\r\n case 'Number':\r\n case 'Float':\r\n this.castValueToInteger(ast.right, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(ast.right, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.right, retArr);\r\n }\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n checkAndUpconvertBitwiseUnary(ast, retArr) {\r\n const upconvertableOperators = {\r\n '~': 'bitwiseNot',\r\n };\r\n const foundOperator = upconvertableOperators[ast.operator];\r\n if (!foundOperator) return null;\r\n retArr.push(foundOperator);\r\n retArr.push('(');\r\n switch (this.getType(ast.argument)) {\r\n case 'Number':\r\n case 'Float':\r\n this.castValueToInteger(ast.argument, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(ast.argument, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.argument, retArr);\r\n }\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Object} ast\r\n * @param {Array} retArr\r\n * @return {String[]}\r\n */\r\n castLiteralToInteger(ast, retArr) {\r\n this.pushState('casting-to-integer');\r\n this.astGeneric(ast, retArr);\r\n this.popState('casting-to-integer');\r\n return retArr;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Object} ast\r\n * @param {Array} retArr\r\n * @return {String[]}\r\n */\r\n castLiteralToFloat(ast, retArr) {\r\n this.pushState('casting-to-float');\r\n this.astGeneric(ast, retArr);\r\n this.popState('casting-to-float');\r\n return retArr;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Object} ast\r\n * @param {Array} retArr\r\n * @return {String[]}\r\n */\r\n castValueToInteger(ast, retArr) {\r\n this.pushState('casting-to-integer');\r\n retArr.push('int(');\r\n this.astGeneric(ast, retArr);\r\n retArr.push(')');\r\n this.popState('casting-to-integer');\r\n return retArr;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Object} ast\r\n * @param {Array} retArr\r\n * @return {String[]}\r\n */\r\n castValueToFloat(ast, retArr) {\r\n this.pushState('casting-to-float');\r\n retArr.push('float(');\r\n this.astGeneric(ast, retArr);\r\n retArr.push(')');\r\n this.popState('casting-to-float');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *identifier* expression\r\n * @param {Object} idtNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astIdentifierExpression(idtNode, retArr) {\r\n if (idtNode.type !== 'Identifier') {\r\n throw this.astErrorOutput('IdentifierExpression - not an Identifier', idtNode);\r\n }\r\n\r\n const type = this.getType(idtNode);\r\n\r\n if (idtNode.name === 'Infinity') {\r\n // https://stackoverflow.com/a/47543127/1324039\r\n retArr.push('3.402823466e+38');\r\n } else if (type === 'Boolean') {\r\n if (this.argumentNames.indexOf(idtNode.name) > -1) {\r\n retArr.push(`bool(user_${idtNode.name})`);\r\n } else {\r\n retArr.push(`user_${idtNode.name}`);\r\n }\r\n } else {\r\n retArr.push(`user_${idtNode.name}`);\r\n }\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *for-loop* expression\r\n * @param {Object} forNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed webgl string\r\n */\r\n astForStatement(forNode, retArr) {\r\n if (forNode.type !== 'ForStatement') {\r\n throw this.astErrorOutput('Invalid for statement', forNode);\r\n }\r\n\r\n const initArr = [];\r\n const testArr = [];\r\n const updateArr = [];\r\n const bodyArr = [];\r\n let isSafe = null;\r\n\r\n if (forNode.init) {\r\n this.pushState('in-for-loop-init');\r\n this.astGeneric(forNode.init, initArr);\r\n const { declarations } = forNode.init;\r\n for (let i = 0; i < declarations.length; i++) {\r\n if (declarations[i].init && declarations[i].init.type !== 'Literal') {\r\n isSafe = false;\r\n }\r\n }\r\n if (isSafe) {\r\n for (let i = 0; i < initArr.length; i++) {\r\n if (initArr[i].includes && initArr[i].includes(',')) {\r\n isSafe = false;\r\n }\r\n }\r\n }\r\n this.popState('in-for-loop-init');\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.test) {\r\n this.pushState('in-for-loop-test');\r\n this.astGeneric(forNode.test, testArr);\r\n this.popState('in-for-loop-test');\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.update) {\r\n this.astGeneric(forNode.update, updateArr);\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.body) {\r\n this.pushState('loop-body');\r\n this.astGeneric(forNode.body, bodyArr);\r\n this.popState('loop-body');\r\n }\r\n\r\n // have all parts, now make them safe\r\n if (isSafe === null) {\r\n isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test);\r\n }\r\n\r\n if (isSafe) {\r\n retArr.push(`for (${initArr.join('')};${testArr.join('')};${updateArr.join('')}){\\n`);\r\n retArr.push(bodyArr.join(''));\r\n retArr.push('}\\n');\r\n } else {\r\n const iVariableName = this.getInternalVariableName('safeI');\r\n if (initArr.length > 0) {\r\n retArr.push(initArr.join(''), ';\\n');\r\n }\r\n retArr.push(`for (int ${iVariableName}=0;${iVariableName} 0) {\r\n retArr.push(`if (!${testArr.join('')}) break;\\n`);\r\n }\r\n retArr.push(bodyArr.join(''));\r\n retArr.push(`\\n${updateArr.join('')};`);\r\n retArr.push('}\\n');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *while* loop\r\n * @param {Object} whileNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed webgl string\r\n */\r\n astWhileStatement(whileNode, retArr) {\r\n if (whileNode.type !== 'WhileStatement') {\r\n throw this.astErrorOutput('Invalid while statement', whileNode);\r\n }\r\n\r\n const iVariableName = this.getInternalVariableName('safeI');\r\n retArr.push(`for (int ${iVariableName}=0;${iVariableName} i + 1) {\r\n movingDefaultToEnd = true;\r\n this.astGeneric(cases[i].consequent, defaultResult);\r\n continue;\r\n } else {\r\n retArr.push(' else {\\n');\r\n }\r\n } else {\r\n // all others\r\n if (i === 0 || !pastFirstIf) {\r\n pastFirstIf = true;\r\n retArr.push(`if (${varName} == `);\r\n } else {\r\n if (fallingThrough) {\r\n retArr.push(`${varName} == `);\r\n fallingThrough = false;\r\n } else {\r\n retArr.push(` else if (${varName} == `);\r\n }\r\n }\r\n if (type === 'Integer') {\r\n const testType = this.getType(cases[i].test);\r\n switch (testType) {\r\n case 'Number':\r\n case 'Float':\r\n this.castValueToInteger(cases[i].test, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(cases[i].test, retArr);\r\n break;\r\n }\r\n } else if (type === 'Float') {\r\n const testType = this.getType(cases[i].test);\r\n switch (testType) {\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(cases[i].test, retArr);\r\n break;\r\n case 'Integer':\r\n this.castValueToFloat(cases[i].test, retArr);\r\n break;\r\n }\r\n } else {\r\n throw new Error('unhanlded');\r\n }\r\n if (!cases[i].consequent || cases[i].consequent.length === 0) {\r\n fallingThrough = true;\r\n retArr.push(' || ');\r\n continue;\r\n }\r\n retArr.push(`) {\\n`);\r\n }\r\n this.astGeneric(cases[i].consequent, retArr);\r\n retArr.push('\\n}');\r\n }\r\n if (movingDefaultToEnd) {\r\n retArr.push(' else {');\r\n retArr.push(defaultResult.join(''));\r\n retArr.push('}');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *This* expression\r\n * @param {Object} tNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astThisExpression(tNode, retArr) {\r\n retArr.push('this');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Member* Expression\r\n * @param {Object} mNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astMemberExpression(mNode, retArr) {\r\n const {\r\n property,\r\n name,\r\n signature,\r\n origin,\r\n type,\r\n xProperty,\r\n yProperty,\r\n zProperty\r\n } = this.getMemberExpressionDetails(mNode);\r\n switch (signature) {\r\n case 'value.thread.value':\r\n case 'this.thread.value':\r\n if (name !== 'x' && name !== 'y' && name !== 'z') {\r\n throw this.astErrorOutput('Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`', mNode);\r\n }\r\n retArr.push(`threadId.${name}`);\r\n return retArr;\r\n case 'this.output.value':\r\n if (this.dynamicOutput) {\r\n switch (name) {\r\n case 'x':\r\n if (this.isState('casting-to-float')) {\r\n retArr.push('float(uOutputDim.x)');\r\n } else {\r\n retArr.push('uOutputDim.x');\r\n }\r\n break;\r\n case 'y':\r\n if (this.isState('casting-to-float')) {\r\n retArr.push('float(uOutputDim.y)');\r\n } else {\r\n retArr.push('uOutputDim.y');\r\n }\r\n break;\r\n case 'z':\r\n if (this.isState('casting-to-float')) {\r\n retArr.push('float(uOutputDim.z)');\r\n } else {\r\n retArr.push('uOutputDim.z');\r\n }\r\n break;\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n }\r\n } else {\r\n switch (name) {\r\n case 'x':\r\n if (this.isState('casting-to-integer')) {\r\n retArr.push(this.output[0]);\r\n } else {\r\n retArr.push(this.output[0], '.0');\r\n }\r\n break;\r\n case 'y':\r\n if (this.isState('casting-to-integer')) {\r\n retArr.push(this.output[1]);\r\n } else {\r\n retArr.push(this.output[1], '.0');\r\n }\r\n break;\r\n case 'z':\r\n if (this.isState('casting-to-integer')) {\r\n retArr.push(this.output[2]);\r\n } else {\r\n retArr.push(this.output[2], '.0');\r\n }\r\n break;\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n }\r\n }\r\n return retArr;\r\n case 'value':\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n case 'value[]':\r\n case 'value[][]':\r\n case 'value[][][]':\r\n case 'value[][][][]':\r\n case 'value.value':\r\n if (origin === 'Math') {\r\n retArr.push(Math[name]);\r\n return retArr;\r\n }\r\n switch (property) {\r\n case 'r':\r\n retArr.push(`user_${ name }.r`);\r\n return retArr;\r\n case 'g':\r\n retArr.push(`user_${ name }.g`);\r\n return retArr;\r\n case 'b':\r\n retArr.push(`user_${ name }.b`);\r\n return retArr;\r\n case 'a':\r\n retArr.push(`user_${ name }.a`);\r\n return retArr;\r\n }\r\n break;\r\n case 'this.constants.value':\r\n if (typeof xProperty === 'undefined') {\r\n switch (type) {\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n retArr.push(`constants_${ name }`);\r\n return retArr;\r\n }\r\n }\r\n case 'this.constants.value[]':\r\n case 'this.constants.value[][]':\r\n case 'this.constants.value[][][]':\r\n case 'this.constants.value[][][][]':\r\n break;\r\n case 'fn()[]':\r\n this.astCallExpression(mNode.object, retArr);\r\n retArr.push('[');\r\n retArr.push(this.memberExpressionPropertyMarkup(property));\r\n retArr.push(']');\r\n return retArr;\r\n case '[][]':\r\n this.astArrayExpression(mNode.object, retArr);\r\n retArr.push('[');\r\n retArr.push(this.memberExpressionPropertyMarkup(property));\r\n retArr.push(']');\r\n return retArr;\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n }\r\n\r\n if (mNode.computed === false) {\r\n // handle simple types\r\n switch (type) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n case 'Boolean':\r\n retArr.push(`${origin}_${name}`);\r\n return retArr;\r\n }\r\n }\r\n\r\n // handle more complex types\r\n // argument may have come from a parent\r\n const markupName = `${origin}_${name}`;\r\n\r\n switch (type) {\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n // Get from local vec4\r\n this.astGeneric(mNode.object, retArr);\r\n retArr.push('[');\r\n retArr.push(this.memberExpressionPropertyMarkup(xProperty));\r\n retArr.push(']');\r\n break;\r\n case 'HTMLImageArray':\r\n retArr.push(`getImage3D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'ArrayTexture(1)':\r\n retArr.push(`getFloatFromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'Array1D(2)':\r\n case 'Array2D(2)':\r\n case 'Array3D(2)':\r\n retArr.push(`getMemoryOptimizedVec2(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'ArrayTexture(2)':\r\n retArr.push(`getVec2FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'Array1D(3)':\r\n case 'Array2D(3)':\r\n case 'Array3D(3)':\r\n retArr.push(`getMemoryOptimizedVec3(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'ArrayTexture(3)':\r\n retArr.push(`getVec3FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'Array1D(4)':\r\n case 'Array2D(4)':\r\n case 'Array3D(4)':\r\n retArr.push(`getMemoryOptimizedVec4(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'ArrayTexture(4)':\r\n case 'HTMLImage':\r\n case 'HTMLVideo':\r\n retArr.push(`getVec4FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'NumberTexture':\r\n case 'Array':\r\n case 'Array2D':\r\n case 'Array3D':\r\n case 'Array4D':\r\n case 'Input':\r\n case 'Number':\r\n case 'Float':\r\n case 'Integer':\r\n if (this.precision === 'single') {\r\n // bitRatio is always 4 here, javascript doesn't yet have 8 or 16 bit support\r\n // TODO: make 8 or 16 bit work anyway!\r\n retArr.push(`getMemoryOptimized32(${markupName}, ${markupName}Size, ${markupName}Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n } else {\r\n const bitRatio = (origin === 'user' ?\r\n this.lookupFunctionArgumentBitRatio(this.name, name) :\r\n this.constantBitRatios[name]\r\n );\r\n switch (bitRatio) {\r\n case 1:\r\n retArr.push(`get8(${markupName}, ${markupName}Size, ${markupName}Dim, `);\r\n break;\r\n case 2:\r\n retArr.push(`get16(${markupName}, ${markupName}Size, ${markupName}Dim, `);\r\n break;\r\n case 4:\r\n case 0:\r\n retArr.push(`get32(${markupName}, ${markupName}Size, ${markupName}Dim, `);\r\n break;\r\n default:\r\n throw new Error(`unhandled bit ratio of ${bitRatio}`);\r\n }\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n }\r\n break;\r\n case 'MemoryOptimizedNumberTexture':\r\n retArr.push(`getMemoryOptimized32(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n default:\r\n throw new Error(`unhandled member expression \"${ type }\"`);\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *call* expression\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astCallExpression(ast, retArr) {\r\n if (!ast.callee) {\r\n throw this.astErrorOutput('Unknown CallExpression', ast);\r\n }\r\n\r\n let functionName = null;\r\n const isMathFunction = this.isAstMathFunction(ast);\r\n\r\n // Its a math operator or this.something(), remove the prefix\r\n if (isMathFunction || (ast.callee.object && ast.callee.object.type === 'ThisExpression')) {\r\n functionName = ast.callee.property.name;\r\n }\r\n // Issue #212, BABEL!\r\n else if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[0].type === 'Literal' && !isNaN(ast.callee.expressions[0].raw)) {\r\n functionName = ast.callee.expressions[1].property.name;\r\n } else {\r\n functionName = ast.callee.name;\r\n }\r\n\r\n if (!functionName) {\r\n throw this.astErrorOutput(`Unhandled function, couldn't find name`, ast);\r\n }\r\n\r\n // if this if grows to more than one, lets use a switch\r\n if (functionName === 'atan2') {\r\n functionName = 'atan';\r\n }\r\n\r\n // Register the function into the called registry\r\n if (this.calledFunctions.indexOf(functionName) < 0) {\r\n this.calledFunctions.push(functionName);\r\n }\r\n\r\n if (functionName === 'random' && this.plugins && this.plugins.length > 0) {\r\n for (let i = 0; i < this.plugins.length; i++) {\r\n const plugin = this.plugins[i];\r\n if (plugin.functionMatch === 'Math.random()' && plugin.functionReplace) {\r\n retArr.push(plugin.functionReplace);\r\n return retArr;\r\n }\r\n }\r\n }\r\n\r\n // track the function was called\r\n if (this.onFunctionCall) {\r\n this.onFunctionCall(this.name, functionName, ast.arguments);\r\n }\r\n\r\n // Call the function\r\n retArr.push(functionName);\r\n\r\n // Open arguments space\r\n retArr.push('(');\r\n\r\n // Add the arguments\r\n if (isMathFunction) {\r\n for (let i = 0; i < ast.arguments.length; ++i) {\r\n const argument = ast.arguments[i];\r\n const argumentType = this.getType(argument);\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n\r\n switch (argumentType) {\r\n case 'Integer':\r\n this.castValueToFloat(argument, retArr);\r\n break;\r\n default:\r\n this.astGeneric(argument, retArr);\r\n break;\r\n }\r\n }\r\n } else {\r\n const targetTypes = this.lookupFunctionArgumentTypes(functionName) || [];\r\n for (let i = 0; i < ast.arguments.length; ++i) {\r\n const argument = ast.arguments[i];\r\n let targetType = targetTypes[i];\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n const argumentType = this.getType(argument);\r\n if (!targetType) {\r\n this.triggerImplyArgumentType(functionName, i, argumentType, this);\r\n targetType = argumentType;\r\n }\r\n switch (argumentType) {\r\n case 'Number':\r\n case 'Float':\r\n if (targetType === 'Integer') {\r\n retArr.push('int(');\r\n this.astGeneric(argument, retArr);\r\n retArr.push(')');\r\n continue;\r\n } else if (targetType === 'Number' || targetType === 'Float') {\r\n this.astGeneric(argument, retArr);\r\n continue;\r\n } else if (targetType === 'LiteralInteger') {\r\n this.castLiteralToFloat(argument, retArr);\r\n continue;\r\n }\r\n break;\r\n case 'Integer':\r\n if (targetType === 'Number' || targetType === 'Float') {\r\n retArr.push('float(');\r\n this.astGeneric(argument, retArr);\r\n retArr.push(')');\r\n continue;\r\n } else if (targetType === 'Integer') {\r\n this.astGeneric(argument, retArr);\r\n continue;\r\n }\r\n break;\r\n case 'LiteralInteger':\r\n if (targetType === 'Integer') {\r\n this.castLiteralToInteger(argument, retArr);\r\n continue;\r\n } else if (targetType === 'Number' || targetType === 'Float') {\r\n this.castLiteralToFloat(argument, retArr);\r\n continue;\r\n } else if (targetType === 'LiteralInteger') {\r\n this.astGeneric(argument, retArr);\r\n continue;\r\n }\r\n break;\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n if (targetType === argumentType) {\r\n if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast);\r\n this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i);\r\n retArr.push(`user_${argument.name}`);\r\n continue;\r\n }\r\n break;\r\n case 'HTMLImage':\r\n case 'HTMLImageArray':\r\n case 'HTMLVideo':\r\n case 'ArrayTexture(1)':\r\n case 'ArrayTexture(2)':\r\n case 'ArrayTexture(3)':\r\n case 'ArrayTexture(4)':\r\n case 'Array':\r\n case 'Input':\r\n if (targetType === argumentType) {\r\n if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast);\r\n this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i);\r\n retArr.push(`user_${argument.name},user_${argument.name}Size,user_${argument.name}Dim`);\r\n continue;\r\n }\r\n break;\r\n }\r\n throw this.astErrorOutput(`Unhandled argument combination of ${ argumentType } and ${ targetType } for argument named \"${ argument.name }\"`, ast);\r\n }\r\n }\r\n // Close arguments space\r\n retArr.push(')');\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Array* Expression\r\n * @param {Object} arrNode - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astArrayExpression(arrNode, retArr) {\r\n const arrLen = arrNode.elements.length;\r\n\r\n retArr.push('vec' + arrLen + '(');\r\n for (let i = 0; i < arrLen; ++i) {\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n const subNode = arrNode.elements[i];\r\n this.astGeneric(subNode, retArr)\r\n }\r\n retArr.push(')');\r\n\r\n return retArr;\r\n }\r\n\r\n memberExpressionXYZ(x, y, z, retArr) {\r\n if (z) {\r\n retArr.push(this.memberExpressionPropertyMarkup(z), ', ');\r\n } else {\r\n retArr.push('0, ');\r\n }\r\n if (y) {\r\n retArr.push(this.memberExpressionPropertyMarkup(y), ', ');\r\n } else {\r\n retArr.push('0, ');\r\n }\r\n retArr.push(this.memberExpressionPropertyMarkup(x));\r\n return retArr;\r\n }\r\n\r\n memberExpressionPropertyMarkup(property) {\r\n if (!property) {\r\n throw new Error('Property not set');\r\n }\r\n const type = this.getType(property);\r\n const result = [];\r\n switch (type) {\r\n case 'Number':\r\n case 'Float':\r\n this.castValueToInteger(property, result);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(property, result);\r\n break;\r\n default:\r\n this.astGeneric(property, result);\r\n }\r\n return result.join('');\r\n }\r\n}\r\n\r\nconst typeMap = {\r\n 'Array': 'sampler2D',\r\n 'Array(2)': 'vec2',\r\n 'Array(3)': 'vec3',\r\n 'Array(4)': 'vec4',\r\n 'Array2D': 'sampler2D',\r\n 'Array3D': 'sampler2D',\r\n 'Boolean': 'bool',\r\n 'Float': 'float',\r\n 'Input': 'sampler2D',\r\n 'Integer': 'int',\r\n 'Number': 'float',\r\n 'LiteralInteger': 'float',\r\n 'NumberTexture': 'sampler2D',\r\n 'MemoryOptimizedNumberTexture': 'sampler2D',\r\n 'ArrayTexture(1)': 'sampler2D',\r\n 'ArrayTexture(2)': 'sampler2D',\r\n 'ArrayTexture(3)': 'sampler2D',\r\n 'ArrayTexture(4)': 'sampler2D',\r\n 'HTMLVideo': 'sampler2D',\r\n 'HTMLImage': 'sampler2D',\r\n 'HTMLImageArray': 'sampler2DArray',\r\n};\r\n\r\nconst operatorMap = {\r\n '===': '==',\r\n '!==': '!='\r\n};\r\n","const source = `\r\n\r\nuniform highp float triangle_noise_seed;\r\nhighp float triangle_noise_shift = 0.000001;\r\n\r\n//https://www.shadertoy.com/view/4t2SDh\r\n//note: uniformly distributed, normalized rand, [0;1[\r\nfloat nrand( vec2 n )\r\n{\r\n return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453);\r\n}\r\n//note: remaps v to [0;1] in interval [a;b]\r\nfloat remap( float a, float b, float v )\r\n{\r\n return clamp( (v-a) / (b-a), 0.0, 1.0 );\r\n}\r\n\r\nfloat n4rand( vec2 n )\r\n{\r\n float t = fract( triangle_noise_seed + triangle_noise_shift );\r\n float nrnd0 = nrand( n + 0.07*t );\r\n float nrnd1 = nrand( n + 0.11*t );\r\n float nrnd2 = nrand( n + 0.13*t );\r\n float nrnd3 = nrand( n + 0.17*t );\r\n float result = (nrnd0+nrnd1+nrnd2+nrnd3) / 4.0;\r\n triangle_noise_shift = result + 0.000001;\r\n return result;\r\n}`;\r\n\r\nconst name = 'triangle-noise-noise';\r\n\r\nconst functionMatch = 'Math.random()';\r\n\r\nconst functionReplace = 'n4rand(vTexCoord)';\r\n\r\nconst functionReturnType = 'Number';\r\n\r\nconst onBeforeRun = (kernel) => {\r\n kernel.setUniform1f('triangle_noise_seed', Math.random());\r\n};\r\n\r\n/**\r\n * @type IPlugin\r\n */\r\nexport default {\r\n name,\r\n onBeforeRun,\r\n functionMatch,\r\n functionReplace,\r\n functionReturnType,\r\n source\r\n};\r\n","// language=GLSL\r\nexport const fragmentShader = `__HEADER__;\r\n__FLOAT_TACTIC_DECLARATION__;\r\n__INT_TACTIC_DECLARATION__;\r\n__SAMPLER_2D_TACTIC_DECLARATION__;\r\n\r\nconst int LOOP_MAX = __LOOP_MAX__;\r\n\r\n__PLUGINS__;\r\n__CONSTANTS__;\r\n\r\nvarying vec2 vTexCoord;\r\n\r\nvec4 round(vec4 x) {\r\n return floor(x + 0.5);\r\n}\r\n\r\nfloat round(float x) {\r\n return floor(x + 0.5);\r\n}\r\n\r\nconst int BIT_COUNT = 32;\r\nint modi(int x, int y) {\r\n return x - y * (x / y);\r\n}\r\n\r\nint bitwiseOr(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 || b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseXOR(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 || b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseAnd(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 && b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseNot(int a) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (modi(a, 2) == 0) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n n = n * 2;\r\n }\r\n return result;\r\n}\r\nint bitwiseZeroFillLeftShift(int n, int shift) {\r\n int maxBytes = BIT_COUNT;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (maxBytes >= n) {\r\n break;\r\n }\r\n maxBytes *= 2;\r\n }\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= shift) {\r\n break;\r\n }\r\n n *= 2;\r\n }\r\n\r\n int result = 0;\r\n int byteVal = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= maxBytes) break;\r\n if (modi(n, 2) > 0) { result += byteVal; }\r\n n = int(n / 2);\r\n byteVal *= 2;\r\n }\r\n return result;\r\n}\r\n\r\nint bitwiseSignedRightShift(int num, int shifts) {\r\n return int(floor(float(num) / pow(2.0, float(shifts))));\r\n}\r\n\r\nint bitwiseZeroFillRightShift(int n, int shift) {\r\n int maxBytes = BIT_COUNT;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (maxBytes >= n) {\r\n break;\r\n }\r\n maxBytes *= 2;\r\n }\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= shift) {\r\n break;\r\n }\r\n n /= 2;\r\n }\r\n int result = 0;\r\n int byteVal = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= maxBytes) break;\r\n if (modi(n, 2) > 0) { result += byteVal; }\r\n n = int(n / 2);\r\n byteVal *= 2;\r\n }\r\n return result;\r\n}\r\n\r\nvec2 integerMod(vec2 x, float y) {\r\n vec2 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nvec3 integerMod(vec3 x, float y) {\r\n vec3 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nvec4 integerMod(vec4 x, vec4 y) {\r\n vec4 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nfloat integerMod(float x, float y) {\r\n float res = floor(mod(x, y));\r\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\r\n}\r\n\r\nint integerMod(int x, int y) {\r\n return x - (y * int(x / y));\r\n}\r\n\r\n__DIVIDE_WITH_INTEGER_CHECK__;\r\n\r\n// Here be dragons!\r\n// DO NOT OPTIMIZE THIS CODE\r\n// YOU WILL BREAK SOMETHING ON SOMEBODY\\'S MACHINE\r\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\r\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\r\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\r\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\r\nfloat decode32(vec4 texel) {\r\n __DECODE32_ENDIANNESS__;\r\n texel *= 255.0;\r\n vec2 gte128;\r\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\r\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\r\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\r\n float res = exp2(round(exponent));\r\n texel.b = texel.b - 128.0 * gte128.x;\r\n res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;\r\n res *= gte128.y * -2.0 + 1.0;\r\n return res;\r\n}\r\n\r\nfloat decode16(vec4 texel, int index) {\r\n int channel = integerMod(index, 2);\r\n if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0;\r\n if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0;\r\n return 0.0;\r\n}\r\n\r\nfloat decode8(vec4 texel, int index) {\r\n int channel = integerMod(index, 4);\r\n if (channel == 0) return texel.r * 255.0;\r\n if (channel == 1) return texel.g * 255.0;\r\n if (channel == 2) return texel.b * 255.0;\r\n if (channel == 3) return texel.a * 255.0;\r\n return 0.0;\r\n}\r\n\r\nvec4 legacyEncode32(float f) {\r\n float F = abs(f);\r\n float sign = f < 0.0 ? 1.0 : 0.0;\r\n float exponent = floor(log2(F));\r\n float mantissa = (exp2(-exponent) * F);\r\n // exponent += floor(log2(mantissa));\r\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\r\n texel.rg = integerMod(texel.rg, 256.0);\r\n texel.b = integerMod(texel.b, 128.0);\r\n texel.a = exponent*0.5 + 63.5;\r\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\r\n texel = floor(texel);\r\n texel *= 0.003921569; // 1/255\r\n __ENCODE32_ENDIANNESS__;\r\n return texel;\r\n}\r\n\r\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\r\nvec4 encode32(float value) {\r\n if (value == 0.0) return vec4(0, 0, 0, 0);\r\n\r\n float exponent;\r\n float mantissa;\r\n vec4 result;\r\n float sgn;\r\n\r\n sgn = step(0.0, -value);\r\n value = abs(value);\r\n\r\n exponent = floor(log2(value));\r\n\r\n mantissa = value*pow(2.0, -exponent)-1.0;\r\n exponent = exponent+127.0;\r\n result = vec4(0,0,0,0);\r\n\r\n result.a = floor(exponent/2.0);\r\n exponent = exponent - result.a*2.0;\r\n result.a = result.a + 128.0*sgn;\r\n\r\n result.b = floor(mantissa * 128.0);\r\n mantissa = mantissa - result.b / 128.0;\r\n result.b = result.b + exponent*128.0;\r\n\r\n result.g = floor(mantissa*32768.0);\r\n mantissa = mantissa - result.g/32768.0;\r\n\r\n result.r = floor(mantissa*8388608.0);\r\n return result/255.0;\r\n}\r\n// Dragons end here\r\n\r\nint index;\r\nivec3 threadId;\r\n\r\nivec3 indexTo3D(int idx, ivec3 texDim) {\r\n int z = int(idx / (texDim.x * texDim.y));\r\n idx -= z * int(texDim.x * texDim.y);\r\n int y = int(idx / texDim.x);\r\n int x = int(integerMod(idx, texDim.x));\r\n return ivec3(x, y, z);\r\n}\r\n\r\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize));\r\n return decode32(texel);\r\n}\r\n\r\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x * 2;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y));\r\n return decode16(texel, index);\r\n}\r\n\r\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x * 4;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y));\r\n return decode8(texel, index);\r\n}\r\n\r\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int channel = integerMod(index, 4);\r\n index = index / 4;\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize));\r\n if (channel == 0) return texel.r;\r\n if (channel == 1) return texel.g;\r\n if (channel == 2) return texel.b;\r\n if (channel == 3) return texel.a;\r\n return 0.0;\r\n}\r\n\r\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n return texture2D(tex, st / vec2(texSize));\r\n}\r\n\r\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return result[0];\r\n}\r\n\r\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return vec2(result[0], result[1]);\r\n}\r\n\r\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + (texDim.x * (y + (texDim.y * z)));\r\n int channel = integerMod(index, 2);\r\n index = index / 2;\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize));\r\n if (channel == 0) return vec2(texel.r, texel.g);\r\n if (channel == 1) return vec2(texel.b, texel.a);\r\n return vec2(0.0, 0.0);\r\n}\r\n\r\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return vec3(result[0], result[1], result[2]);\r\n}\r\n\r\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\r\n int vectorIndex = fieldIndex / 4;\r\n int vectorOffset = fieldIndex - vectorIndex * 4;\r\n int readY = vectorIndex / texSize.x;\r\n int readX = vectorIndex - readY * texSize.x;\r\n vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\r\n\r\n if (vectorOffset == 0) {\r\n return tex1.xyz;\r\n } else if (vectorOffset == 1) {\r\n return tex1.yzw;\r\n } else {\r\n readX++;\r\n if (readX >= texSize.x) {\r\n readX = 0;\r\n readY++;\r\n }\r\n vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize));\r\n if (vectorOffset == 2) {\r\n return vec3(tex1.z, tex1.w, tex2.x);\r\n } else {\r\n return vec3(tex1.w, tex2.x, tex2.y);\r\n }\r\n }\r\n}\r\n\r\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n return getImage2D(tex, texSize, texDim, z, y, x);\r\n}\r\n\r\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int channel = integerMod(index, 2);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize));\r\n return vec4(texel.r, texel.g, texel.b, texel.a);\r\n}\r\n\r\nvec4 actualColor;\r\nvoid color(float r, float g, float b, float a) {\r\n actualColor = vec4(r,g,b,a);\r\n}\r\n\r\nvoid color(float r, float g, float b) {\r\n color(r,g,b,1.0);\r\n}\r\n\r\nvoid color(sampler2D image) {\r\n actualColor = texture2D(image, vTexCoord);\r\n}\r\n\r\n__INJECTED_NATIVE__;\r\n__MAIN_CONSTANTS__;\r\n__MAIN_ARGUMENTS__;\r\n__KERNEL__;\r\n\r\nvoid main(void) {\r\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\r\n __MAIN_RESULT__;\r\n}`;\r\n","// language=GLSL\r\nexport const vertexShader = `__FLOAT_TACTIC_DECLARATION__;\r\n__INT_TACTIC_DECLARATION__;\r\n__SAMPLER_2D_TACTIC_DECLARATION__;\r\n\r\nattribute vec2 aPos;\r\nattribute vec2 aTexCoord;\r\n\r\nvarying vec2 vTexCoord;\r\nuniform vec2 ratio;\r\n\r\nvoid main(void) {\r\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\r\n vTexCoord = aTexCoord;\r\n}`;\r\n","/**\n *\n * @param {WebGLRenderingContext} gl\n * @param {IGLWiretapOptions} [options]\n * @returns {GLWiretapProxy}\n */\nfunction glWiretap(gl, options = {}) {\n const {\n contextName = 'gl',\n throwGetError,\n useTrackablePrimitives,\n readPixelsFile,\n recording = [],\n variables = {},\n onReadPixels,\n onUnrecognizedArgumentLookup,\n } = options;\n const proxy = new Proxy(gl, { get: listen });\n const contextVariables = [];\n const entityNames = {};\n let imageCount = 0;\n let indent = '';\n let readPixelsVariableName;\n return proxy;\n function listen(obj, property) {\n switch (property) {\n case 'addComment': return addComment;\n case 'checkThrowError': return checkThrowError;\n case 'getReadPixelsVariableName': return readPixelsVariableName;\n case 'insertVariable': return insertVariable;\n case 'reset': return reset;\n case 'setIndent': return setIndent;\n case 'toString': return toString;\n case 'getContextVariableName': return getContextVariableName;\n }\n if (typeof gl[property] === 'function') {\n return function() { // need arguments from this, fyi\n switch (property) {\n case 'getError':\n if (throwGetError) {\n recording.push(`${indent}if (${contextName}.getError() !== ${contextName}.NONE) throw new Error('error');`);\n } else {\n recording.push(`${indent}${contextName}.getError();`); // flush out errors\n }\n return gl.getError();\n case 'getExtension': {\n const variableName = `${contextName}Variables${contextVariables.length}`;\n recording.push(`${indent}const ${variableName} = ${contextName}.getExtension('${arguments[0]}');`);\n const extension = gl.getExtension(arguments[0]);\n if (extension && typeof extension === 'object') {\n const tappedExtension = glExtensionWiretap(extension, {\n getEntity,\n useTrackablePrimitives,\n recording,\n contextName: variableName,\n contextVariables,\n variables,\n indent,\n onUnrecognizedArgumentLookup,\n });\n contextVariables.push(tappedExtension);\n return tappedExtension;\n } else {\n contextVariables.push(null);\n }\n return extension;\n }\n case 'readPixels':\n const i = contextVariables.indexOf(arguments[6]);\n let targetVariableName;\n if (i === -1) {\n const variableName = getVariableName(arguments[6]);\n if (variableName) {\n targetVariableName = variableName;\n recording.push(`${indent}${variableName}`);\n } else {\n targetVariableName = `${contextName}Variable${contextVariables.length}`;\n contextVariables.push(arguments[6]);\n recording.push(`${indent}const ${targetVariableName} = new ${arguments[6].constructor.name}(${arguments[6].length});`);\n }\n } else {\n targetVariableName = `${contextName}Variable${i}`;\n }\n readPixelsVariableName = targetVariableName;\n const argumentAsStrings = [\n arguments[0],\n arguments[1],\n arguments[2],\n arguments[3],\n getEntity(arguments[4]),\n getEntity(arguments[5]),\n targetVariableName\n ];\n recording.push(`${indent}${contextName}.readPixels(${argumentAsStrings.join(', ')});`);\n if (readPixelsFile) {\n writePPM(arguments[2], arguments[3]);\n }\n if (onReadPixels) {\n onReadPixels(targetVariableName, argumentAsStrings);\n }\n return gl.readPixels.apply(gl, arguments);\n case 'drawBuffers':\n recording.push(`${indent}${contextName}.drawBuffers([${argumentsToString(arguments[0], { contextName, contextVariables, getEntity, addVariable, variables, onUnrecognizedArgumentLookup } )}]);`);\n return gl.drawBuffers(arguments[0]);\n }\n let result = gl[property].apply(gl, arguments);\n switch (typeof result) {\n case 'undefined':\n recording.push(`${indent}${methodCallToString(property, arguments)};`);\n return;\n case 'number':\n case 'boolean':\n if (useTrackablePrimitives && contextVariables.indexOf(trackablePrimitive(result)) === -1) {\n recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);\n contextVariables.push(result = trackablePrimitive(result));\n break;\n }\n default:\n if (result === null) {\n recording.push(`${methodCallToString(property, arguments)};`);\n } else {\n recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);\n }\n\n contextVariables.push(result);\n }\n return result;\n }\n }\n entityNames[gl[property]] = property;\n return gl[property];\n }\n function toString() {\n return recording.join('\\n');\n }\n function reset() {\n while (recording.length > 0) {\n recording.pop();\n }\n }\n function insertVariable(name, value) {\n variables[name] = value;\n }\n function getEntity(value) {\n const name = entityNames[value];\n if (name) {\n return contextName + '.' + name;\n }\n return value;\n }\n function setIndent(spaces) {\n indent = ' '.repeat(spaces);\n }\n function addVariable(value, source) {\n const variableName = `${contextName}Variable${contextVariables.length}`;\n recording.push(`${indent}const ${variableName} = ${source};`);\n contextVariables.push(value);\n return variableName;\n }\n function writePPM(width, height) {\n const sourceVariable = `${contextName}Variable${contextVariables.length}`;\n const imageVariable = `imageDatum${imageCount}`;\n recording.push(`${indent}let ${imageVariable} = [\"P3\\\\n# ${readPixelsFile}.ppm\\\\n\", ${width}, ' ', ${height}, \"\\\\n255\\\\n\"].join(\"\");`);\n recording.push(`${indent}for (let i = 0; i < ${imageVariable}.length; i += 4) {`);\n recording.push(`${indent} ${imageVariable} += ${sourceVariable}[i] + ' ' + ${sourceVariable}[i + 1] + ' ' + ${sourceVariable}[i + 2] + ' ';`);\n recording.push(`${indent}}`);\n recording.push(`${indent}if (typeof require !== \"undefined\") {`);\n recording.push(`${indent} require('fs').writeFileSync('./${readPixelsFile}.ppm', ${imageVariable});`);\n recording.push(`${indent}}`);\n imageCount++;\n }\n function addComment(value) {\n recording.push(`${indent}// ${value}`);\n }\n function checkThrowError() {\n recording.push(`${indent}(() => {\n${indent}const error = ${contextName}.getError();\n${indent}if (error !== ${contextName}.NONE) {\n${indent} const names = Object.getOwnPropertyNames(gl);\n${indent} for (let i = 0; i < names.length; i++) {\n${indent} const name = names[i];\n${indent} if (${contextName}[name] === error) {\n${indent} throw new Error('${contextName} threw ' + name);\n${indent} }\n${indent} }\n${indent}}\n${indent}})();`);\n }\n function methodCallToString(method, args) {\n return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`;\n }\n\n function getVariableName(value) {\n if (variables) {\n for (const name in variables) {\n if (variables[name] === value) {\n return name;\n }\n }\n }\n return null;\n }\n\n function getContextVariableName(value) {\n const i = contextVariables.indexOf(value);\n if (i !== -1) {\n return `${contextName}Variable${i}`;\n }\n return null;\n }\n}\n\n/**\n *\n * @param extension\n * @param {IGLExtensionWiretapOptions} options\n * @returns {*}\n */\nfunction glExtensionWiretap(extension, options) {\n const proxy = new Proxy(extension, { get: listen });\n const extensionEntityNames = {};\n const {\n contextName,\n contextVariables,\n getEntity,\n useTrackablePrimitives,\n recording,\n variables,\n indent,\n onUnrecognizedArgumentLookup,\n } = options;\n return proxy;\n function listen(obj, property) {\n if (typeof obj[property] === 'function') {\n return function() {\n switch (property) {\n case 'drawBuffersWEBGL':\n recording.push(`${indent}${contextName}.drawBuffersWEBGL([${argumentsToString(arguments[0], { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })}]);`);\n return extension.drawBuffersWEBGL(arguments[0]);\n }\n let result = extension[property].apply(extension, arguments);\n switch (typeof result) {\n case 'undefined':\n recording.push(`${indent}${methodCallToString(property, arguments)};`);\n return;\n case 'number':\n case 'boolean':\n if (useTrackablePrimitives && contextVariables.indexOf(trackablePrimitive(result)) === -1) {\n recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);\n contextVariables.push(result = trackablePrimitive(result));\n } else {\n recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);\n contextVariables.push(result);\n }\n break;\n default:\n if (result === null) {\n recording.push(`${methodCallToString(property, arguments)};`);\n } else {\n recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);\n }\n contextVariables.push(result);\n }\n return result;\n };\n }\n extensionEntityNames[extension[property]] = property;\n return extension[property];\n }\n\n function getExtensionEntity(value) {\n if (extensionEntityNames.hasOwnProperty(value)) {\n return `${contextName}.${extensionEntityNames[value]}`;\n }\n return getEntity(value);\n }\n\n function methodCallToString(method, args) {\n return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`;\n }\n\n function addVariable(value, source) {\n const variableName = `${contextName}Variable${contextVariables.length}`;\n contextVariables.push(value);\n recording.push(`${indent}const ${variableName} = ${source};`);\n return variableName;\n }\n}\n\nfunction argumentsToString(args, options) {\n const { variables, onUnrecognizedArgumentLookup } = options;\n return (Array.from(args).map((arg) => {\n const variableName = getVariableName(arg);\n if (variableName) {\n return variableName;\n }\n return argumentToString(arg, options);\n }).join(', '));\n\n function getVariableName(value) {\n if (variables) {\n for (const name in variables) {\n if (!variables.hasOwnProperty(name)) continue;\n if (variables[name] === value) {\n return name;\n }\n }\n }\n if (onUnrecognizedArgumentLookup) {\n return onUnrecognizedArgumentLookup(value);\n }\n return null;\n }\n}\n\nfunction argumentToString(arg, options) {\n const { contextName, contextVariables, getEntity, addVariable, onUnrecognizedArgumentLookup } = options;\n if (typeof arg === 'undefined') {\n return 'undefined';\n }\n if (arg === null) {\n return 'null';\n }\n const i = contextVariables.indexOf(arg);\n if (i > -1) {\n return `${contextName}Variable${i}`;\n }\n switch (arg.constructor.name) {\n case 'String':\n const hasLines = /\\n/.test(arg);\n const hasSingleQuotes = /'/.test(arg);\n const hasDoubleQuotes = /\"/.test(arg);\n if (hasLines) {\n return '`' + arg + '`';\n } else if (hasSingleQuotes && !hasDoubleQuotes) {\n return '\"' + arg + '\"';\n } else if (!hasSingleQuotes && hasDoubleQuotes) {\n return \"'\" + arg + \"'\";\n } else {\n return '\\'' + arg + '\\'';\n }\n case 'Number': return getEntity(arg);\n case 'Boolean': return getEntity(arg);\n case 'Array':\n return addVariable(arg, `new ${arg.constructor.name}([${Array.from(arg).join(',')}])`);\n case 'Float32Array':\n case 'Uint8Array':\n case 'Uint16Array':\n case 'Int32Array':\n return addVariable(arg, `new ${arg.constructor.name}(${JSON.stringify(Array.from(arg))})`);\n default:\n if (onUnrecognizedArgumentLookup) {\n const instantiationString = onUnrecognizedArgumentLookup(arg);\n if (instantiationString) {\n return instantiationString;\n }\n }\n throw new Error(`unrecognized argument type ${arg.constructor.name}`);\n }\n}\n\nfunction trackablePrimitive(value) {\n // wrapped in object, so track-able\n return new value.constructor(value);\n}\n\nif (typeof module !== 'undefined') {\n module.exports = { glWiretap, glExtensionWiretap };\n}\n\nif (typeof window !== 'undefined') {\n glWiretap.glExtensionWiretap = glExtensionWiretap;\n window.glWiretap = glWiretap;\n}\n","import { glWiretap } from 'gl-wiretap';\r\nimport { utils } from '../../utils';\r\n\r\nfunction toStringWithoutUtils(fn) {\r\n return fn.toString()\r\n .replace('=>', '')\r\n .replace(/^function /, '')\r\n .replace(/utils[.]/g, '/*utils.*/');\r\n}\r\n\r\n/**\r\n *\r\n * @param {Kernel} Kernel\r\n * @param {KernelVariable[]} args\r\n * @param {Kernel} originKernel\r\n * @param {string} [setupContextString]\r\n * @param {string} [destroyContextString]\r\n * @returns {string}\r\n */\r\nexport function glKernelString(Kernel, args, originKernel, setupContextString, destroyContextString) {\r\n args = args ? Array.from(args).map(arg => {\r\n switch (typeof arg) {\r\n case 'boolean':\r\n return new Boolean(arg);\r\n case 'number':\r\n return new Number(arg);\r\n default:\r\n return arg;\r\n }\r\n }) : null;\r\n const uploadedValues = [];\r\n const postResult = [];\r\n const context = glWiretap(originKernel.context, {\r\n useTrackablePrimitives: true,\r\n onReadPixels: (targetName) => {\r\n if (kernel.subKernels) {\r\n if (!subKernelsResultVariableSetup) {\r\n postResult.push(` const result = { result: ${getRenderString(targetName, kernel)} };`);\r\n subKernelsResultVariableSetup = true;\r\n } else {\r\n const property = kernel.subKernels[subKernelsResultIndex++].property;\r\n postResult.push(` result${isNaN(property) ? '.' + property : `[${property}]`} = ${getRenderString(targetName, kernel)};`);\r\n }\r\n if (subKernelsResultIndex === kernel.subKernels.length) {\r\n postResult.push(' return result;');\r\n }\r\n return;\r\n }\r\n if (targetName) {\r\n postResult.push(` return ${getRenderString(targetName, kernel)};`);\r\n } else {\r\n postResult.push(` return null;`);\r\n }\r\n },\r\n onUnrecognizedArgumentLookup: (argument) => {\r\n const argumentName = findKernelValue(argument, kernel.kernelArguments, [], context, uploadedValues);\r\n if (argumentName) {\r\n return argumentName;\r\n }\r\n const constantName = findKernelValue(argument, kernel.kernelConstants, constants ? Object.keys(constants).map(key => constants[key]) : [], context, uploadedValues);\r\n if (constantName) {\r\n return constantName;\r\n }\r\n return null;\r\n }\r\n });\r\n let subKernelsResultVariableSetup = false;\r\n let subKernelsResultIndex = 0;\r\n const {\r\n source,\r\n canvas,\r\n output,\r\n pipeline,\r\n graphical,\r\n loopMaxIterations,\r\n constants,\r\n optimizeFloatMemory,\r\n precision,\r\n fixIntegerDivisionAccuracy,\r\n functions,\r\n nativeFunctions,\r\n subKernels,\r\n immutable,\r\n argumentTypes,\r\n constantTypes,\r\n kernelArguments,\r\n kernelConstants,\r\n } = originKernel;\r\n const kernel = new Kernel(source, {\r\n canvas,\r\n context,\r\n checkContext: false,\r\n output,\r\n pipeline,\r\n graphical,\r\n loopMaxIterations,\r\n constants,\r\n optimizeFloatMemory,\r\n precision,\r\n fixIntegerDivisionAccuracy,\r\n functions,\r\n nativeFunctions,\r\n subKernels,\r\n immutable,\r\n argumentTypes,\r\n constantTypes,\r\n });\r\n let result = [];\r\n context.setIndent(2);\r\n kernel.build.apply(kernel, args);\r\n result.push(context.toString());\r\n context.reset();\r\n\r\n kernel.kernelArguments.forEach((kernelArgument, i) => {\r\n switch (kernelArgument.type) {\r\n // primitives\r\n case 'Integer':\r\n case 'Boolean':\r\n case 'Number':\r\n case 'Float':\r\n // non-primitives\r\n case 'Array':\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n case 'HTMLImage':\r\n case 'HTMLVideo':\r\n context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue);\r\n break;\r\n case 'HTMLImageArray':\r\n for (let imageIndex = 0; imageIndex < args[i].length; imageIndex++) {\r\n const arg = args[i];\r\n context.insertVariable(`uploadValue_${kernelArgument.name}[${imageIndex}]`, arg[imageIndex]);\r\n }\r\n break;\r\n case 'Input':\r\n context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue);\r\n break;\r\n case 'MemoryOptimizedNumberTexture':\r\n case 'NumberTexture':\r\n case 'Array1D(2)':\r\n case 'Array1D(3)':\r\n case 'Array1D(4)':\r\n case 'Array2D(2)':\r\n case 'Array2D(3)':\r\n case 'Array2D(4)':\r\n case 'Array3D(2)':\r\n case 'Array3D(3)':\r\n case 'Array3D(4)':\r\n case 'ArrayTexture(1)':\r\n case 'ArrayTexture(2)':\r\n case 'ArrayTexture(3)':\r\n case 'ArrayTexture(4)':\r\n context.insertVariable(`uploadValue_${kernelArgument.name}`, args[i].texture);\r\n break;\r\n default:\r\n throw new Error(`unhandled kernelArgumentType insertion for glWiretap of type ${kernelArgument.type}`);\r\n }\r\n });\r\n result.push('/** start of injected functions **/');\r\n result.push(`function ${toStringWithoutUtils(utils.flattenTo)}`);\r\n result.push(`function ${toStringWithoutUtils(utils.flatten2dArrayTo)}`);\r\n result.push(`function ${toStringWithoutUtils(utils.flatten3dArrayTo)}`);\r\n result.push(`function ${toStringWithoutUtils(utils.flatten4dArrayTo)}`);\r\n result.push(`function ${toStringWithoutUtils(utils.isArray)}`);\r\n if (kernel.renderOutput !== kernel.renderTexture && kernel.formatValues) {\r\n result.push(\r\n ` const renderOutput = function ${toStringWithoutUtils(kernel.formatValues)};`\r\n );\r\n }\r\n result.push('/** end of injected functions **/');\r\n result.push(` const innerKernel = function (${kernel.kernelArguments.map(kernelArgument => kernelArgument.varName).join(', ')}) {`);\r\n context.setIndent(4);\r\n kernel.run.apply(kernel, args);\r\n if (kernel.renderKernels) {\r\n kernel.renderKernels();\r\n } else if (kernel.renderOutput) {\r\n kernel.renderOutput();\r\n }\r\n result.push(' /** start setup uploads for kernel values **/');\r\n kernel.kernelArguments.forEach(kernelArgument => {\r\n result.push(' ' + kernelArgument.getStringValueHandler().split('\\n').join('\\n '));\r\n });\r\n result.push(' /** end setup uploads for kernel values **/');\r\n result.push(context.toString());\r\n if (kernel.renderOutput === kernel.renderTexture) {\r\n context.reset();\r\n const results = kernel.renderKernels();\r\n const textureName = context.getContextVariableName(kernel.outputTexture);\r\n result.push(` return {\r\n result: {\r\n texture: ${ textureName },\r\n type: '${ results.result.type }',\r\n toArray: ${ getToArrayString(results.result, textureName) }\r\n },`);\r\n const { subKernels, subKernelOutputTextures } = kernel;\r\n for (let i = 0; i < subKernels.length; i++) {\r\n const texture = subKernelOutputTextures[i];\r\n const subKernel = subKernels[i];\r\n const subKernelResult = results[subKernel.property];\r\n const subKernelTextureName = context.getContextVariableName(texture);\r\n result.push(`\r\n ${subKernel.property}: {\r\n texture: ${ subKernelTextureName },\r\n type: '${ subKernelResult.type }',\r\n toArray: ${ getToArrayString(subKernelResult, subKernelTextureName) }\r\n },`);\r\n }\r\n result.push(` };`);\r\n }\r\n result.push(` ${destroyContextString ? '\\n' + destroyContextString + ' ': ''}`);\r\n result.push(postResult.join('\\n'));\r\n result.push(' };');\r\n if (kernel.graphical) {\r\n result.push(getGetPixelsString(kernel));\r\n result.push(` innerKernel.getPixels = getPixels;`);\r\n }\r\n result.push(' return innerKernel;');\r\n\r\n let constantsUpload = [];\r\n kernelConstants.forEach((kernelConstant) => {\r\n constantsUpload.push(`${ kernelConstant.getStringValueHandler()}`);\r\n });\r\n return `function kernel(settings) {\r\n const { context, constants } = settings;\r\n ${constantsUpload.join('')}\r\n ${setupContextString ? setupContextString : ''}\r\n${result.join('\\n')}\r\n}`;\r\n}\r\n\r\nfunction getRenderString(targetName, kernel) {\r\n const readBackValue = kernel.precision === 'single' ? targetName : `new Float32Array(${targetName}.buffer)`;\r\n if (kernel.output[2]) {\r\n return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]}, ${kernel.output[2]})`;\r\n }\r\n if (kernel.output[1]) {\r\n return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]})`;\r\n }\r\n\r\n return `renderOutput(${readBackValue}, ${kernel.output[0]})`;\r\n}\r\n\r\nfunction getGetPixelsString(kernel) {\r\n const getPixels = kernel.getPixels.toString();\r\n const useFunctionKeyword = !/^function/.test(getPixels);\r\n return utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ getPixels }`, {\r\n findDependency: (object, name) => {\r\n if (object === 'utils') {\r\n return `const ${name} = ${utils[name].toString()};`;\r\n }\r\n return null;\r\n },\r\n thisLookup: (property) => {\r\n if (property === 'context') {\r\n return null;\r\n }\r\n if (kernel.hasOwnProperty(property)) {\r\n return JSON.stringify(kernel[property]);\r\n }\r\n throw new Error(`unhandled thisLookup ${ property }`);\r\n }\r\n });\r\n}\r\n\r\nfunction getToArrayString(kernelResult, textureName) {\r\n const toArray = kernelResult.toArray.toString();\r\n const useFunctionKeyword = !/^function/.test(toArray);\r\n const flattenedFunctions = utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ toArray }`, {\r\n findDependency: (object, name) => {\r\n if (object === 'utils') {\r\n return `const ${name} = ${utils[name].toString()};`;\r\n } else if (object === 'this') {\r\n return `${useFunctionKeyword ? 'function ' : ''}${kernelResult[name].toString()}`;\r\n } else {\r\n throw new Error('unhandled fromObject');\r\n }\r\n },\r\n thisLookup: (property) => {\r\n if (property === 'texture') {\r\n return textureName;\r\n }\r\n if (kernelResult.hasOwnProperty(property)) {\r\n return JSON.stringify(kernelResult[property]);\r\n }\r\n throw new Error(`unhandled thisLookup ${ property }`);\r\n }\r\n });\r\n return `() => {\r\n ${flattenedFunctions}\r\n return toArray();\r\n }`;\r\n}\r\n\r\n/**\r\n *\r\n * @param {KernelVariable} argument\r\n * @param {KernelValue[]} kernelValues\r\n * @param {KernelVariable[]} values\r\n * @param context\r\n * @param {KernelVariable[]} uploadedValues\r\n * @return {string|null}\r\n */\r\nfunction findKernelValue(argument, kernelValues, values, context, uploadedValues) {\r\n if (argument === null) return null;\r\n switch (typeof argument) {\r\n case 'boolean':\r\n case 'number':\r\n return null;\r\n }\r\n if (\r\n typeof HTMLImageElement !== 'undefined' &&\r\n argument instanceof HTMLImageElement\r\n ) {\r\n for (let i = 0; i < kernelValues.length; i++) {\r\n const kernelValue = kernelValues[i];\r\n if (kernelValue.type !== 'HTMLImageArray') continue;\r\n if (kernelValue.uploadValue !== argument) continue;\r\n // TODO: if we send two of the same image, the parser could get confused, and short circuit to the first, handle that here\r\n const variableIndex = values[i].indexOf(argument);\r\n if (variableIndex === -1) continue;\r\n const variableName = `uploadValue_${kernelValue.name}[${variableIndex}]`;\r\n context.insertVariable(variableName, argument);\r\n return variableName;\r\n }\r\n return null;\r\n }\r\n\r\n for (let i = 0; i < kernelValues.length; i++) {\r\n const kernelValue = kernelValues[i];\r\n if (argument !== kernelValue.uploadValue) continue;\r\n const variable = `uploadValue_${kernelValue.name}`;\r\n context.insertVariable(variable, kernelValue);\r\n return variable;\r\n }\r\n return null;\r\n}\r\n","/**\r\n * @class KernelValue\r\n */\r\nexport class KernelValue {\r\n /**\r\n *\r\n * @param {KernelVariable} value\r\n * @param {IKernelValueSettings} settings\r\n */\r\n constructor(value, settings) {\r\n const {\r\n name,\r\n kernel,\r\n context,\r\n checkContext,\r\n onRequestContextHandle,\r\n onUpdateValueMismatch,\r\n origin,\r\n strictIntegers,\r\n type,\r\n tactic,\r\n } = settings;\r\n if (!name) {\r\n throw new Error('name not set');\r\n }\r\n if (!type) {\r\n throw new Error('type not set');\r\n }\r\n if (!origin) {\r\n throw new Error('origin not set');\r\n }\r\n if (!tactic) {\r\n throw new Error('tactic not set');\r\n }\r\n if (origin !== 'user' && origin !== 'constants') {\r\n throw new Error(`origin must be \"user\" or \"constants\" value is \"${ origin }\"`);\r\n }\r\n if (!onRequestContextHandle) {\r\n throw new Error('onRequestContextHandle is not set');\r\n }\r\n this.name = name;\r\n this.origin = origin;\r\n this.tactic = tactic;\r\n this.id = `${this.origin}_${name}`;\r\n this.varName = origin === 'constants' ? `constants.${name}` : name;\r\n this.kernel = kernel;\r\n this.strictIntegers = strictIntegers;\r\n // handle textures\r\n this.type = value.type || type;\r\n this.size = value.size || null;\r\n this.index = null;\r\n this.context = context;\r\n this.checkContext = checkContext !== null && checkContext !== undefined ? checkContext : true;\r\n this.contextHandle = null;\r\n this.onRequestContextHandle = onRequestContextHandle;\r\n this.onUpdateValueMismatch = onUpdateValueMismatch;\r\n this.forceUploadEachRun = null;\r\n }\r\n\r\n getSource() {\r\n throw new Error(`\"getSource\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n updateValue(value) {\r\n throw new Error(`\"updateValue\" not defined on ${ this.constructor.name }`);\r\n }\r\n}\r\n","import { Input } from '../../../input';\r\nimport { KernelValue } from '../../kernel-value';\r\nimport { utils } from '../../../utils';\r\n\r\nexport class WebGLKernelValue extends KernelValue {\r\n /**\r\n * @param {KernelVariable} value\r\n * @param {IWebGLKernelValueSettings} settings\r\n */\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.dimensionsId = null;\r\n this.sizeId = null;\r\n this.initialValueConstructor = value.constructor;\r\n this.onRequestTexture = settings.onRequestTexture;\r\n this.onRequestIndex = settings.onRequestIndex;\r\n this.uploadValue = null;\r\n this.textureSize = null;\r\n this.bitRatio = null;\r\n }\r\n\r\n /**\r\n *\r\n * @param {number} width\r\n * @param {number} height\r\n */\r\n checkSize(width, height) {\r\n if (!this.kernel.validate) return;\r\n const { maxTextureSize } = this.kernel.constructor.features;\r\n if (width > maxTextureSize || height > maxTextureSize) {\r\n if (width > height) {\r\n throw new Error(`Argument width of ${width} larger than maximum size of ${maxTextureSize} for your GPU`);\r\n } else {\r\n throw new Error(`Argument height of ${height} larger than maximum size of ${maxTextureSize} for your GPU`);\r\n }\r\n }\r\n }\r\n\r\n requestTexture() {\r\n this.texture = this.onRequestTexture();\r\n this.setupTexture();\r\n }\r\n\r\n setupTexture() {\r\n this.contextHandle = this.onRequestContextHandle();\r\n this.index = this.onRequestIndex();\r\n this.dimensionsId = this.id + 'Dim';\r\n this.sizeId = this.id + 'Size';\r\n }\r\n\r\n getTransferArrayType(value) {\r\n if (Array.isArray(value[0])) {\r\n return this.getTransferArrayType(value[0]);\r\n }\r\n switch (value.constructor) {\r\n case Array:\r\n case Int32Array:\r\n case Int16Array:\r\n case Int8Array:\r\n return Float32Array;\r\n case Uint8ClampedArray:\r\n case Uint8Array:\r\n case Uint16Array:\r\n case Uint32Array:\r\n case Float32Array:\r\n case Float64Array:\r\n return value.constructor;\r\n }\r\n console.warn('Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros');\r\n return value.constructor;\r\n }\r\n /**\r\n * @desc Adds kernel parameters to the Value Texture,\r\n * binding it to the context, etc.\r\n *\r\n * @param {Array|Float32Array|Uint16Array} value - The actual Value supplied to the kernel\r\n * @param {Number} length - the expected total length of the output array\r\n * @param {Object} [Type]\r\n * @returns {Float32Array|Uint16Array|Uint8Array} flattened array to transfer\r\n */\r\n formatArrayTransfer(value, length, Type) {\r\n if (utils.isArray(value[0]) || this.optimizeFloatMemory) {\r\n // not already flat\r\n const valuesFlat = new Float32Array(length);\r\n utils.flattenTo(value, valuesFlat);\r\n return valuesFlat;\r\n } else {\r\n switch (value.constructor) {\r\n case Uint8ClampedArray:\r\n case Uint8Array:\r\n case Int8Array:\r\n case Uint16Array:\r\n case Int16Array:\r\n case Float32Array:\r\n case Int32Array: {\r\n const valuesFlat = new(Type || value.constructor)(length);\r\n utils.flattenTo(value, valuesFlat);\r\n return valuesFlat;\r\n }\r\n default: {\r\n const valuesFlat = new Float32Array(length);\r\n utils.flattenTo(value, valuesFlat);\r\n return valuesFlat;\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * bit storage ratio of source to target 'buffer', i.e. if 8bit array -> 32bit tex = 4\r\n * @param value\r\n * @returns {number}\r\n */\r\n getBitRatio(value) {\r\n if (Array.isArray(value[0])) {\r\n return this.getBitRatio(value[0]);\r\n } else if (value.constructor === Input) {\r\n return this.getBitRatio(value.value);\r\n }\r\n switch (value.constructor) {\r\n case Uint8ClampedArray:\r\n case Uint8Array:\r\n case Int8Array:\r\n return 1;\r\n case Uint16Array:\r\n case Int16Array:\r\n return 2;\r\n case Float32Array:\r\n case Int32Array:\r\n default:\r\n return 4;\r\n }\r\n }\r\n\r\n /**\r\n * Used for when we want a string output of our kernel, so we can still input values to the kernel\r\n */\r\n getStringValueHandler() {\r\n throw new Error(`\"getStringValueHandler\" not implemented on ${this.constructor.name}`);\r\n }\r\n\r\n getVariablePrecisionString() {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'lowp';\r\n case 'performance':\r\n return 'highp';\r\n case 'balanced':\r\n default:\r\n return 'mediump';\r\n }\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueBoolean extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n return `const bool ${this.id} = ${value};\\n`;\r\n }\r\n return `uniform bool ${this.id};\\n`;\r\n }\r\n\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform1i(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueFloat extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n if (Number.isInteger(value)) {\r\n return `const float ${this.id} = ${value}.0;\\n`;\r\n }\r\n return `const float ${this.id} = ${value};\\n`;\r\n }\r\n return `uniform float ${this.id};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform1f(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueInteger extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n return `const int ${this.id} = ${ parseInt(value) };\\n`;\r\n }\r\n return `uniform int ${this.id};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform1i(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueHTMLImage extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n const { width, height } = value;\r\n this.checkSize(width, height);\r\n this.dimensions = [width, height, 1];\r\n this.requestTexture();\r\n this.textureSize = [width, height];\r\n this.uploadValue = value;\r\n }\r\n\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(inputImage) {\r\n if (inputImage.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue = inputImage);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueHTMLImage } from './html-image';\r\n\r\nexport class WebGLKernelValueDynamicHTMLImage extends WebGLKernelValueHTMLImage {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n const { width, height } = value;\r\n this.checkSize(width, height);\r\n this.dimensions = [width, height, 1];\r\n this.textureSize = [width, height];\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { WebGLKernelValueHTMLImage } from './html-image';\r\n\r\nexport class WebGLKernelValueHTMLVideo extends WebGLKernelValueHTMLImage {}\r\n","import { WebGLKernelValueDynamicHTMLImage } from './dynamic-html-image';\r\n\r\nexport class WebGLKernelValueDynamicHTMLVideo extends WebGLKernelValueDynamicHTMLImage {}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleInput extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = 4;\r\n let [w, h, d] = value.size;\r\n this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,\r\n `flattenTo(${this.varName}.value, uploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(input) {\r\n if (input.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(input.value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleInput } from './single-input';\r\n\r\nexport class WebGLKernelValueDynamicSingleInput extends WebGLKernelValueSingleInput {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n let [w, h, d] = value.size;\r\n this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueUnsignedInput extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = this.getBitRatio(value);\r\n const [w, h, d] = value.size;\r\n this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);\r\n this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio);\r\n this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio));\r\n this.TranserArrayType = this.getTransferArrayType(value.value);\r\n this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength);\r\n this.uploadValue = new Uint8Array(this.preUploadValue.buffer);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,\r\n `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,\r\n `flattenTo(${this.varName}.value, preUploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(input) {\r\n if (input.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(input.value, this.preUploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueUnsignedInput } from './unsigned-input';\r\n\r\nexport class WebGLKernelValueDynamicUnsignedInput extends WebGLKernelValueUnsignedInput {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n let [w, h, d] = value.size;\r\n this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);\r\n this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio);\r\n this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio));\r\n const Type = this.getTransferArrayType(value.value);\r\n this.preUploadValue = new Type(this.uploadArrayLength);\r\n this.uploadValue = new Uint8Array(this.preUploadValue.buffer);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueMemoryOptimizedNumberTexture extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n const [width, height] = value.size;\r\n this.checkSize(width, height);\r\n this.setupTexture();\r\n this.dimensions = value.dimensions;\r\n this.textureSize = value.size;\r\n this.uploadValue = value.texture;\r\n this.forceUploadEachRun = true;\r\n }\r\n\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName}.texture;\\n`;\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(inputTexture) {\r\n if (inputTexture.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n if (this.checkContext && inputTexture.context !== this.context) {\r\n throw new Error(`Value ${this.name} (${this.type }) must be from same context`);\r\n }\r\n const { context: gl } = this;\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueMemoryOptimizedNumberTexture } from './memory-optimized-number-texture';\r\n\r\nexport class WebGLKernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(inputTexture) {\r\n this.checkSize(inputTexture.size[0], inputTexture.size[1]);\r\n this.dimensions = inputTexture.dimensions;\r\n this.textureSize = inputTexture.size;\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(inputTexture);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueNumberTexture extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n const [width, height] = value.size;\r\n this.checkSize(width, height);\r\n this.setupTexture();\r\n const { size: textureSize, dimensions } = value;\r\n this.bitRatio = this.getBitRatio(value);\r\n this.dimensions = dimensions;\r\n this.textureSize = textureSize;\r\n this.uploadValue = value.texture;\r\n this.forceUploadEachRun = true;\r\n }\r\n\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName}.texture;\\n`;\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(inputTexture) {\r\n if (inputTexture.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n if (this.checkContext && inputTexture.context !== this.context) {\r\n throw new Error(`Value ${this.name} (${this.type}) must be from same context`);\r\n }\r\n const { context: gl } = this;\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueNumberTexture } from './number-texture';\r\n\r\nexport class WebGLKernelValueDynamicNumberTexture extends WebGLKernelValueNumberTexture {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.dimensions = value.dimensions;\r\n this.checkSize(value.size[0], value.size[1]);\r\n this.textureSize = value.size;\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = 4;\r\n this.dimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,\r\n `flattenTo(${this.varName}, uploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray } from './single-array';\r\n\r\nexport class WebGLKernelValueDynamicSingleArray extends WebGLKernelValueSingleArray {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.dimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray1DI extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = 4;\r\n this.setShape(value);\r\n }\r\n\r\n setShape(value) {\r\n const valueDimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio);\r\n this.dimensions = new Int32Array([valueDimensions[1], 1, 1]);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,\r\n `flattenTo(${this.varName}, uploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flatten2dArrayTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray1DI } from './single-array1d-i';\r\n\r\nexport class WebGLKernelValueDynamicSingleArray1DI extends WebGLKernelValueSingleArray1DI {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray2DI extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = 4;\r\n this.setShape(value);\r\n }\r\n\r\n setShape(value) {\r\n const valueDimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio);\r\n this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], 1]);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,\r\n `flattenTo(${this.varName}, uploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flatten3dArrayTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray2DI } from './single-array2d-i';\r\n\r\nexport class WebGLKernelValueDynamicSingleArray2DI extends WebGLKernelValueSingleArray2DI {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray3DI extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = 4;\r\n this.setShape(value);\r\n }\r\n\r\n setShape(value) {\r\n const valueDimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio);\r\n this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], valueDimensions[3]]);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,\r\n `flattenTo(${this.varName}, uploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flatten4dArrayTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray3DI } from './single-array3d-i';\r\n\r\nexport class WebGLKernelValueDynamicSingleArray3DI extends WebGLKernelValueSingleArray3DI {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray2 extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n return `const vec2 ${this.id} = vec2(${value[0]},${value[1]});\\n`;\r\n }\r\n return `uniform vec2 ${this.id};\\n`;\r\n }\r\n\r\n getStringValueHandler() {\r\n // resetting isn't supported for Array(2)\r\n if (this.origin === 'constants') return '';\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform2fv(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray3 extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n return `const vec3 ${this.id} = vec3(${value[0]},${value[1]},${value[2]});\\n`;\r\n }\r\n return `uniform vec3 ${this.id};\\n`;\r\n }\r\n\r\n getStringValueHandler() {\r\n // resetting isn't supported for Array(3)\r\n if (this.origin === 'constants') return '';\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform3fv(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray4 extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n return `const vec4 ${this.id} = vec4(${value[0]},${value[1]},${value[2]},${value[3]});\\n`;\r\n }\r\n return `uniform vec4 ${this.id};\\n`;\r\n }\r\n\r\n getStringValueHandler() {\r\n // resetting isn't supported for Array(4)\r\n if (this.origin === 'constants') return '';\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform4fv(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueUnsignedArray extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = this.getBitRatio(value);\r\n this.dimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio);\r\n this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio));\r\n this.TranserArrayType = this.getTransferArrayType(value);\r\n this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength);\r\n this.uploadValue = new Uint8Array(this.preUploadValue.buffer);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,\r\n `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,\r\n `flattenTo(${this.varName}, preUploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.preUploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueUnsignedArray } from './unsigned-array';\r\n\r\nexport class WebGLKernelValueDynamicUnsignedArray extends WebGLKernelValueUnsignedArray {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.dimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio);\r\n this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio));\r\n const Type = this.getTransferArrayType(value);\r\n this.preUploadValue = new Type(this.uploadArrayLength);\r\n this.uploadValue = new Uint8Array(this.preUploadValue.buffer);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { WebGLKernelValueBoolean } from './kernel-value/boolean';\r\nimport { WebGLKernelValueFloat } from './kernel-value/float';\r\nimport { WebGLKernelValueInteger } from './kernel-value/integer';\r\n\r\nimport { WebGLKernelValueHTMLImage } from './kernel-value/html-image';\r\nimport { WebGLKernelValueDynamicHTMLImage } from './kernel-value/dynamic-html-image';\r\n\r\nimport { WebGLKernelValueHTMLVideo } from './kernel-value/html-video';\r\nimport { WebGLKernelValueDynamicHTMLVideo } from './kernel-value/dynamic-html-video';\r\n\r\nimport { WebGLKernelValueSingleInput } from './kernel-value/single-input';\r\nimport { WebGLKernelValueDynamicSingleInput } from './kernel-value/dynamic-single-input';\r\n\r\nimport { WebGLKernelValueUnsignedInput } from './kernel-value/unsigned-input';\r\nimport { WebGLKernelValueDynamicUnsignedInput } from './kernel-value/dynamic-unsigned-input';\r\n\r\nimport { WebGLKernelValueMemoryOptimizedNumberTexture } from './kernel-value/memory-optimized-number-texture';\r\nimport { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } from './kernel-value/dynamic-memory-optimized-number-texture';\r\n\r\nimport { WebGLKernelValueNumberTexture } from './kernel-value/number-texture';\r\nimport { WebGLKernelValueDynamicNumberTexture } from './kernel-value/dynamic-number-texture';\r\n\r\nimport { WebGLKernelValueSingleArray } from './kernel-value/single-array';\r\nimport { WebGLKernelValueDynamicSingleArray } from './kernel-value/dynamic-single-array';\r\n\r\nimport { WebGLKernelValueSingleArray1DI } from './kernel-value/single-array1d-i';\r\nimport { WebGLKernelValueDynamicSingleArray1DI } from './kernel-value/dynamic-single-array1d-i';\r\n\r\nimport { WebGLKernelValueSingleArray2DI } from './kernel-value/single-array2d-i';\r\nimport { WebGLKernelValueDynamicSingleArray2DI } from './kernel-value/dynamic-single-array2d-i';\r\n\r\nimport { WebGLKernelValueSingleArray3DI } from './kernel-value/single-array3d-i';\r\nimport { WebGLKernelValueDynamicSingleArray3DI } from './kernel-value/dynamic-single-array3d-i';\r\n\r\nimport { WebGLKernelValueSingleArray2 } from './kernel-value/single-array2';\r\nimport { WebGLKernelValueSingleArray3 } from './kernel-value/single-array3';\r\nimport { WebGLKernelValueSingleArray4 } from './kernel-value/single-array4';\r\n\r\nimport { WebGLKernelValueUnsignedArray } from './kernel-value/unsigned-array';\r\nimport { WebGLKernelValueDynamicUnsignedArray } from './kernel-value/dynamic-unsigned-array';\r\n\r\nexport const kernelValueMaps = {\r\n unsigned: {\r\n dynamic: {\r\n 'Boolean': WebGLKernelValueBoolean,\r\n 'Integer': WebGLKernelValueInteger,\r\n 'Float': WebGLKernelValueFloat,\r\n 'Array': WebGLKernelValueDynamicUnsignedArray,\r\n 'Array(2)': false,\r\n 'Array(3)': false,\r\n 'Array(4)': false,\r\n 'Array1D(2)': false,\r\n 'Array1D(3)': false,\r\n 'Array1D(4)': false,\r\n 'Array2D(2)': false,\r\n 'Array2D(3)': false,\r\n 'Array2D(4)': false,\r\n 'Array3D(2)': false,\r\n 'Array3D(3)': false,\r\n 'Array3D(4)': false,\r\n 'Input': WebGLKernelValueDynamicUnsignedInput,\r\n 'NumberTexture': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGLKernelValueDynamicHTMLImage,\r\n 'HTMLImageArray': false,\r\n 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo,\r\n },\r\n static: {\r\n 'Boolean': WebGLKernelValueBoolean,\r\n 'Float': WebGLKernelValueFloat,\r\n 'Integer': WebGLKernelValueInteger,\r\n 'Array': WebGLKernelValueUnsignedArray,\r\n 'Array(2)': false,\r\n 'Array(3)': false,\r\n 'Array(4)': false,\r\n 'Array1D(2)': false,\r\n 'Array1D(3)': false,\r\n 'Array1D(4)': false,\r\n 'Array2D(2)': false,\r\n 'Array2D(3)': false,\r\n 'Array2D(4)': false,\r\n 'Array3D(2)': false,\r\n 'Array3D(3)': false,\r\n 'Array3D(4)': false,\r\n 'Input': WebGLKernelValueUnsignedInput,\r\n 'NumberTexture': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(1)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(2)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(3)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(4)': WebGLKernelValueNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGLKernelValueHTMLImage,\r\n 'HTMLImageArray': false,\r\n 'HTMLVideo': WebGLKernelValueHTMLVideo,\r\n }\r\n },\r\n single: {\r\n dynamic: {\r\n 'Boolean': WebGLKernelValueBoolean,\r\n 'Integer': WebGLKernelValueInteger,\r\n 'Float': WebGLKernelValueFloat,\r\n 'Array': WebGLKernelValueDynamicSingleArray,\r\n 'Array(2)': WebGLKernelValueSingleArray2,\r\n 'Array(3)': WebGLKernelValueSingleArray3,\r\n 'Array(4)': WebGLKernelValueSingleArray4,\r\n 'Array1D(2)': WebGLKernelValueDynamicSingleArray1DI,\r\n 'Array1D(3)': WebGLKernelValueDynamicSingleArray1DI,\r\n 'Array1D(4)': WebGLKernelValueDynamicSingleArray1DI,\r\n 'Array2D(2)': WebGLKernelValueDynamicSingleArray2DI,\r\n 'Array2D(3)': WebGLKernelValueDynamicSingleArray2DI,\r\n 'Array2D(4)': WebGLKernelValueDynamicSingleArray2DI,\r\n 'Array3D(2)': WebGLKernelValueDynamicSingleArray3DI,\r\n 'Array3D(3)': WebGLKernelValueDynamicSingleArray3DI,\r\n 'Array3D(4)': WebGLKernelValueDynamicSingleArray3DI,\r\n 'Input': WebGLKernelValueDynamicSingleInput,\r\n 'NumberTexture': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGLKernelValueDynamicHTMLImage,\r\n 'HTMLImageArray': false,\r\n 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo,\r\n },\r\n static: {\r\n 'Boolean': WebGLKernelValueBoolean,\r\n 'Float': WebGLKernelValueFloat,\r\n 'Integer': WebGLKernelValueInteger,\r\n 'Array': WebGLKernelValueSingleArray,\r\n 'Array(2)': WebGLKernelValueSingleArray2,\r\n 'Array(3)': WebGLKernelValueSingleArray3,\r\n 'Array(4)': WebGLKernelValueSingleArray4,\r\n 'Array1D(2)': WebGLKernelValueSingleArray1DI,\r\n 'Array1D(3)': WebGLKernelValueSingleArray1DI,\r\n 'Array1D(4)': WebGLKernelValueSingleArray1DI,\r\n 'Array2D(2)': WebGLKernelValueSingleArray2DI,\r\n 'Array2D(3)': WebGLKernelValueSingleArray2DI,\r\n 'Array2D(4)': WebGLKernelValueSingleArray2DI,\r\n 'Array3D(2)': WebGLKernelValueSingleArray3DI,\r\n 'Array3D(3)': WebGLKernelValueSingleArray3DI,\r\n 'Array3D(4)': WebGLKernelValueSingleArray3DI,\r\n 'Input': WebGLKernelValueSingleInput,\r\n 'NumberTexture': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(1)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(2)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(3)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(4)': WebGLKernelValueNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGLKernelValueHTMLImage,\r\n 'HTMLImageArray': false,\r\n 'HTMLVideo': WebGLKernelValueHTMLVideo,\r\n }\r\n },\r\n};\r\n\r\nexport function lookupKernelValueType(type, dynamic, precision, value) {\r\n if (!type) {\r\n throw new Error('type missing');\r\n }\r\n if (!dynamic) {\r\n throw new Error('dynamic missing');\r\n }\r\n if (!precision) {\r\n throw new Error('precision missing');\r\n }\r\n if (value.type) {\r\n type = value.type;\r\n }\r\n const types = kernelValueMaps[precision][dynamic];\r\n if (types[type] === false) {\r\n return null;\r\n } else if (types[type] === undefined) {\r\n throw new Error(`Could not find a KernelValue for ${ type }`);\r\n }\r\n return types[type];\r\n}\r\n","import { GLKernel } from '../gl/kernel';\r\nimport { FunctionBuilder } from '../function-builder';\r\nimport { WebGLFunctionNode } from './function-node';\r\nimport { utils } from '../../utils';\r\nimport triangleNoise from '../../plugins/triangle-noise';\r\nimport { fragmentShader } from './fragment-shader';\r\nimport { vertexShader } from './vertex-shader';\r\nimport { glKernelString } from '../gl/kernel-string';\r\nimport { lookupKernelValueType } from './kernel-value-maps';\r\n\r\nlet isSupported = null;\r\nlet testCanvas = null;\r\nlet testContext = null;\r\nlet testExtensions = null;\r\nlet features = null;\r\n\r\nconst plugins = [triangleNoise];\r\nconst canvases = [];\r\nconst maxTexSizes = {};\r\n\r\n/**\r\n * @desc Kernel Implementation for WebGL.\r\n *\r\n * This builds the shaders and runs them on the GPU, then outputs the result\r\n * back as float (enabled by default) and Texture.\r\n *\r\n * @prop {Object} textureCache - webGl Texture cache\r\n * @prop {Object} programUniformLocationCache - Location of program variables in memory\r\n * @prop {Object} framebuffer - Webgl frameBuffer\r\n * @prop {Object} buffer - WebGL buffer\r\n * @prop {Object} program - The webGl Program\r\n * @prop {Object} functionBuilder - Function Builder instance bound to this Kernel\r\n * @prop {Boolean} pipeline - Set output type to FAST mode (GPU to GPU via Textures), instead of float\r\n * @prop {String} endianness - Endian information like Little-endian, Big-endian.\r\n * @prop {Array} argumentTypes - Types of parameters sent to the Kernel\r\n * @prop {String} compiledFragmentShader - Compiled fragment shader string\r\n * @prop {String} compiledVertexShader - Compiled Vertical shader string\r\n * @extends GLKernel\r\n */\r\nexport class WebGLKernel extends GLKernel {\r\n static get isSupported() {\r\n if (isSupported !== null) {\r\n return isSupported;\r\n }\r\n this.setupFeatureChecks();\r\n isSupported = this.isContextMatch(testContext);\r\n return isSupported;\r\n }\r\n\r\n static setupFeatureChecks() {\r\n if (typeof document !== 'undefined') {\r\n testCanvas = document.createElement('canvas');\r\n } else if (typeof OffscreenCanvas !== 'undefined') {\r\n testCanvas = new OffscreenCanvas(0, 0);\r\n }\r\n if (!testCanvas) return;\r\n testContext = testCanvas.getContext('webgl') || testCanvas.getContext('experimental-webgl');\r\n if (!testContext || !testContext.getExtension) return;\r\n testExtensions = {\r\n OES_texture_float: testContext.getExtension('OES_texture_float'),\r\n OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'),\r\n OES_element_index_uint: testContext.getExtension('OES_element_index_uint'),\r\n WEBGL_draw_buffers: testContext.getExtension('WEBGL_draw_buffers'),\r\n };\r\n features = this.getFeatures();\r\n }\r\n\r\n static isContextMatch(context) {\r\n if (typeof WebGLRenderingContext !== 'undefined') {\r\n return context instanceof WebGLRenderingContext;\r\n }\r\n return false;\r\n }\r\n\r\n static getFeatures() {\r\n const isDrawBuffers = this.getIsDrawBuffers();\r\n return Object.freeze({\r\n isFloatRead: this.getIsFloatRead(),\r\n isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(),\r\n isTextureFloat: this.getIsTextureFloat(),\r\n isDrawBuffers,\r\n kernelMap: isDrawBuffers,\r\n channelCount: this.getChannelCount(),\r\n });\r\n }\r\n\r\n static getIsTextureFloat() {\r\n return Boolean(testExtensions.OES_texture_float);\r\n }\r\n\r\n static getIsDrawBuffers() {\r\n return Boolean(testExtensions.WEBGL_draw_buffers);\r\n }\r\n\r\n static getChannelCount() {\r\n return testExtensions.WEBGL_draw_buffers ?\r\n testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) :\r\n 1;\r\n }\r\n\r\n static lookupKernelValueType(type, dynamic, precision, value) {\r\n return lookupKernelValueType(type, dynamic, precision, value);\r\n }\r\n\r\n static get testCanvas() {\r\n return testCanvas;\r\n }\r\n\r\n static get testContext() {\r\n return testContext;\r\n }\r\n\r\n static get features() {\r\n return features;\r\n }\r\n\r\n static get fragmentShader() {\r\n return fragmentShader;\r\n }\r\n\r\n static get vertexShader() {\r\n return vertexShader;\r\n }\r\n\r\n /**\r\n *\r\n * @param {String} source\r\n * @param {IKernelSettings} settings\r\n */\r\n constructor(source, settings) {\r\n super(source, settings);\r\n this.program = null;\r\n this.pipeline = settings.pipeline;\r\n this.endianness = utils.systemEndianness();\r\n this.extensions = {};\r\n this.subKernelOutputTextures = null;\r\n this.kernelArguments = null;\r\n this.argumentTextureCount = 0;\r\n this.constantTextureCount = 0;\r\n this.compiledFragmentShader = null;\r\n this.compiledVertexShader = null;\r\n this.fragShader = null;\r\n this.vertShader = null;\r\n this.drawBuffersMap = null;\r\n this.outputTexture = null;\r\n\r\n /**\r\n *\r\n * @type {Int32Array|null}\r\n */\r\n this.maxTexSize = null;\r\n this.switchingKernels = false;\r\n this.onRequestSwitchKernel = null;\r\n\r\n this.mergeSettings(source.settings || settings);\r\n\r\n /**\r\n * The thread dimensions, x, y and z\r\n * @type {Array|null}\r\n */\r\n this.threadDim = null;\r\n this.framebuffer = null;\r\n this.buffer = null;\r\n this.textureCache = {};\r\n this.programUniformLocationCache = {};\r\n this.uniform1fCache = {};\r\n this.uniform1iCache = {};\r\n this.uniform2fCache = {};\r\n this.uniform2fvCache = {};\r\n this.uniform2ivCache = {};\r\n this.uniform3fvCache = {};\r\n this.uniform3ivCache = {};\r\n this.uniform4fvCache = {};\r\n this.uniform4ivCache = {};\r\n }\r\n\r\n initCanvas() {\r\n if (typeof document !== 'undefined') {\r\n const canvas = document.createElement('canvas');\r\n // Default width and height, to fix webgl issue in safari\r\n canvas.width = 2;\r\n canvas.height = 2;\r\n return canvas;\r\n } else if (typeof OffscreenCanvas !== 'undefined') {\r\n return new OffscreenCanvas(0, 0);\r\n }\r\n }\r\n\r\n initContext() {\r\n const settings = {\r\n alpha: false,\r\n depth: false,\r\n antialias: false\r\n };\r\n return this.canvas.getContext('webgl', settings) || this.canvas.getContext('experimental-webgl', settings);\r\n }\r\n\r\n initPlugins(settings) {\r\n // default plugins\r\n const pluginsToUse = [];\r\n const { source } = this;\r\n if (typeof source === 'string') {\r\n for (let i = 0; i < plugins.length; i++) {\r\n const plugin = plugins[i];\r\n if (source.match(plugin.functionMatch)) {\r\n pluginsToUse.push(plugin);\r\n }\r\n }\r\n } else if (typeof source === 'object') {\r\n // `source` is from object, json\r\n if (settings.pluginNames) { //TODO: in context of JSON support, pluginNames may not exist here\r\n for (let i = 0; i < plugins.length; i++) {\r\n const plugin = plugins[i];\r\n const usePlugin = settings.pluginNames.some(pluginName => pluginName === plugin.name);\r\n if (usePlugin) {\r\n pluginsToUse.push(plugin);\r\n }\r\n }\r\n }\r\n }\r\n return pluginsToUse;\r\n }\r\n\r\n initExtensions() {\r\n this.extensions = {\r\n OES_texture_float: this.context.getExtension('OES_texture_float'),\r\n OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'),\r\n OES_element_index_uint: this.context.getExtension('OES_element_index_uint'),\r\n WEBGL_draw_buffers: this.context.getExtension('WEBGL_draw_buffers'),\r\n WEBGL_color_buffer_float: this.context.getExtension('WEBGL_color_buffer_float'),\r\n };\r\n }\r\n\r\n /**\r\n * @desc Validate settings related to Kernel, such as dimensions size, and auto output support.\r\n * @param {IArguments} args\r\n */\r\n validateSettings(args) {\r\n if (!this.validate) {\r\n this.texSize = utils.getKernelTextureSize({\r\n optimizeFloatMemory: this.optimizeFloatMemory,\r\n precision: this.precision,\r\n }, this.output);\r\n return;\r\n }\r\n\r\n const { features } = this.constructor;\r\n if (this.optimizeFloatMemory === true && !features.isTextureFloat) {\r\n throw new Error('Float textures are not supported');\r\n } else if (this.precision === 'single' && !features.isFloatRead) {\r\n throw new Error('Single precision not supported');\r\n } else if (!this.graphical && this.precision === null && features.isTextureFloat) {\r\n this.precision = features.isFloatRead ? 'single' : 'unsigned';\r\n }\r\n\r\n if (this.subKernels && this.subKernels.length > 0 && !this.extensions.WEBGL_draw_buffers) {\r\n throw new Error('could not instantiate draw buffers extension');\r\n }\r\n\r\n if (this.fixIntegerDivisionAccuracy === null) {\r\n this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate;\r\n } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) {\r\n this.fixIntegerDivisionAccuracy = false;\r\n }\r\n\r\n this.checkOutput();\r\n\r\n if (!this.output || this.output.length === 0) {\r\n if (args.length !== 1) {\r\n throw new Error('Auto output only supported for kernels with only one input');\r\n }\r\n\r\n const argType = utils.getVariableType(args[0], this.strictIntegers);\r\n if (argType === 'Array') {\r\n this.output = utils.getDimensions(argType);\r\n } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') {\r\n this.output = args[0].output;\r\n } else {\r\n throw new Error('Auto output not supported for input type: ' + argType);\r\n }\r\n }\r\n\r\n if (this.graphical) {\r\n if (this.output.length !== 2) {\r\n throw new Error('Output must have 2 dimensions on graphical mode');\r\n }\r\n\r\n if (this.precision === 'precision') {\r\n this.precision = 'unsigned';\r\n console.warn('Cannot use graphical mode and single precision at the same time');\r\n }\r\n\r\n this.texSize = utils.clone(this.output);\r\n return;\r\n } else if (this.precision === null && features.isTextureFloat) {\r\n this.precision = 'single';\r\n }\r\n\r\n this.texSize = utils.getKernelTextureSize({\r\n optimizeFloatMemory: this.optimizeFloatMemory,\r\n precision: this.precision,\r\n }, this.output);\r\n\r\n this.checkTextureSize();\r\n }\r\n\r\n updateMaxTexSize() {\r\n const { texSize, canvas } = this;\r\n if (this.maxTexSize === null) {\r\n let canvasIndex = canvases.indexOf(canvas);\r\n if (canvasIndex === -1) {\r\n canvasIndex = canvases.length;\r\n canvases.push(canvas);\r\n maxTexSizes[canvasIndex] = [texSize[0], texSize[1]];\r\n }\r\n this.maxTexSize = maxTexSizes[canvasIndex];\r\n }\r\n if (this.maxTexSize[0] < texSize[0]) {\r\n this.maxTexSize[0] = texSize[0];\r\n }\r\n if (this.maxTexSize[1] < texSize[1]) {\r\n this.maxTexSize[1] = texSize[1];\r\n }\r\n }\r\n\r\n // TODO: move channel checks to new place\r\n _oldtranslateSource() {\r\n const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, {\r\n fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy\r\n });\r\n\r\n // need this line to automatically get returnType\r\n const translatedSource = functionBuilder.getPrototypeString('kernel');\r\n\r\n if (!this.returnType) {\r\n this.returnType = functionBuilder.getKernelResultType();\r\n }\r\n\r\n let requiredChannels = 0;\r\n const returnTypes = functionBuilder.getReturnTypes();\r\n for (let i = 0; i < returnTypes.length; i++) {\r\n switch (returnTypes[i]) {\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n requiredChannels++;\r\n break;\r\n case 'Array(2)':\r\n requiredChannels += 2;\r\n break;\r\n case 'Array(3)':\r\n requiredChannels += 3;\r\n break;\r\n case 'Array(4)':\r\n requiredChannels += 4;\r\n break;\r\n }\r\n }\r\n\r\n if (features && requiredChannels > features.channelCount) {\r\n throw new Error('Too many channels!');\r\n }\r\n\r\n return this.translatedSource = translatedSource;\r\n }\r\n\r\n setupArguments(args) {\r\n this.kernelArguments = [];\r\n this.argumentTextureCount = 0;\r\n const needsArgumentTypes = this.argumentTypes === null;\r\n // TODO: remove\r\n if (needsArgumentTypes) {\r\n this.argumentTypes = [];\r\n }\r\n this.argumentSizes = [];\r\n this.argumentBitRatios = [];\r\n // TODO: end remove\r\n\r\n if (args.length < this.argumentNames.length) {\r\n throw new Error('not enough arguments for kernel');\r\n } else if (args.length > this.argumentNames.length) {\r\n throw new Error('too many arguments for kernel');\r\n }\r\n\r\n const { context: gl } = this;\r\n let textureIndexes = 0;\r\n for (let index = 0; index < args.length; index++) {\r\n const value = args[index];\r\n const name = this.argumentNames[index];\r\n let type;\r\n if (needsArgumentTypes) {\r\n type = utils.getVariableType(value, this.strictIntegers);\r\n this.argumentTypes.push(type);\r\n } else {\r\n type = this.argumentTypes[index];\r\n }\r\n const KernelValue = this.constructor.lookupKernelValueType(type, this.dynamicArguments ? 'dynamic' : 'static', this.precision, args[index]);\r\n if (KernelValue === null) {\r\n return this.requestFallback(args);\r\n }\r\n const kernelArgument = new KernelValue(value, {\r\n name,\r\n type,\r\n tactic: this.tactic,\r\n origin: 'user',\r\n context: gl,\r\n checkContext: this.checkContext,\r\n kernel: this,\r\n strictIntegers: this.strictIntegers,\r\n onRequestTexture: () => {\r\n return this.context.createTexture();\r\n },\r\n onRequestIndex: () => {\r\n return textureIndexes++;\r\n },\r\n onUpdateValueMismatch: () => {\r\n this.switchingKernels = true;\r\n },\r\n onRequestContextHandle: () => {\r\n return gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount++;\r\n }\r\n });\r\n this.kernelArguments.push(kernelArgument);\r\n this.argumentSizes.push(kernelArgument.textureSize);\r\n this.argumentBitRatios[index] = kernelArgument.bitRatio;\r\n }\r\n }\r\n\r\n setupConstants(args) {\r\n const { context: gl } = this;\r\n this.kernelConstants = [];\r\n this.forceUploadKernelConstants = [];\r\n let needsConstantTypes = this.constantTypes === null;\r\n if (needsConstantTypes) {\r\n this.constantTypes = {};\r\n }\r\n this.constantBitRatios = {};\r\n let textureIndexes = 0;\r\n for (const name in this.constants) {\r\n const value = this.constants[name];\r\n let type;\r\n if (needsConstantTypes) {\r\n type = utils.getVariableType(value, this.strictIntegers);\r\n this.constantTypes[name] = type;\r\n } else {\r\n type = this.constantTypes[name];\r\n }\r\n const KernelValue = this.constructor.lookupKernelValueType(type, 'static', this.precision, value);\r\n if (KernelValue === null) {\r\n return this.requestFallback(args);\r\n }\r\n const kernelValue = new KernelValue(value, {\r\n name,\r\n type,\r\n tactic: this.tactic,\r\n origin: 'constants',\r\n context: this.context,\r\n checkContext: this.checkContext,\r\n kernel: this,\r\n strictIntegers: this.strictIntegers,\r\n onRequestTexture: () => {\r\n return this.context.createTexture();\r\n },\r\n onRequestIndex: () => {\r\n return textureIndexes++;\r\n },\r\n onRequestContextHandle: () => {\r\n return gl.TEXTURE0 + this.constantTextureCount++;\r\n }\r\n });\r\n this.constantBitRatios[name] = kernelValue.bitRatio;\r\n this.kernelConstants.push(kernelValue);\r\n if (kernelValue.forceUploadEachRun) {\r\n this.forceUploadKernelConstants.push(kernelValue);\r\n }\r\n }\r\n }\r\n\r\n build() {\r\n this.initExtensions();\r\n this.validateSettings(arguments);\r\n this.setupConstants(arguments);\r\n if (this.fallbackRequested) return;\r\n this.setupArguments(arguments);\r\n if (this.fallbackRequested) return;\r\n this.updateMaxTexSize();\r\n this.translateSource();\r\n const failureResult = this.pickRenderStrategy(arguments);\r\n if (failureResult) {\r\n return failureResult;\r\n }\r\n const { texSize, context: gl, canvas } = this;\r\n gl.enable(gl.SCISSOR_TEST);\r\n if (this.pipeline && this.precision === 'single') {\r\n gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);\r\n canvas.width = this.maxTexSize[0];\r\n canvas.height = this.maxTexSize[1];\r\n } else {\r\n gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);\r\n canvas.width = this.maxTexSize[0];\r\n canvas.height = this.maxTexSize[1];\r\n }\r\n const threadDim = this.threadDim = Array.from(this.output);\r\n while (threadDim.length < 3) {\r\n threadDim.push(1);\r\n }\r\n\r\n const compiledVertexShader = this.getVertexShader(arguments);\r\n const vertShader = gl.createShader(gl.VERTEX_SHADER);\r\n gl.shaderSource(vertShader, compiledVertexShader);\r\n gl.compileShader(vertShader);\r\n this.vertShader = vertShader;\r\n\r\n const compiledFragmentShader = this.getFragmentShader(arguments);\r\n const fragShader = gl.createShader(gl.FRAGMENT_SHADER);\r\n gl.shaderSource(fragShader, compiledFragmentShader);\r\n gl.compileShader(fragShader);\r\n this.fragShader = fragShader;\r\n\r\n if (this.debug) {\r\n console.log('GLSL Shader Output:');\r\n console.log(compiledFragmentShader);\r\n }\r\n\r\n if (!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) {\r\n throw new Error('Error compiling vertex shader: ' + gl.getShaderInfoLog(vertShader));\r\n }\r\n if (!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) {\r\n throw new Error('Error compiling fragment shader: ' + gl.getShaderInfoLog(fragShader));\r\n }\r\n\r\n const program = this.program = gl.createProgram();\r\n gl.attachShader(program, vertShader);\r\n gl.attachShader(program, fragShader);\r\n gl.linkProgram(program);\r\n this.framebuffer = gl.createFramebuffer();\r\n this.framebuffer.width = texSize[0];\r\n this.framebuffer.height = texSize[1];\r\n\r\n const vertices = new Float32Array([-1, -1,\r\n 1, -1, -1, 1,\r\n 1, 1\r\n ]);\r\n const texCoords = new Float32Array([\r\n 0, 0,\r\n 1, 0,\r\n 0, 1,\r\n 1, 1\r\n ]);\r\n\r\n const texCoordOffset = vertices.byteLength;\r\n\r\n let buffer = this.buffer;\r\n if (!buffer) {\r\n buffer = this.buffer = gl.createBuffer();\r\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\r\n gl.bufferData(gl.ARRAY_BUFFER, vertices.byteLength + texCoords.byteLength, gl.STATIC_DRAW);\r\n } else {\r\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\r\n }\r\n\r\n gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices);\r\n gl.bufferSubData(gl.ARRAY_BUFFER, texCoordOffset, texCoords);\r\n\r\n const aPosLoc = gl.getAttribLocation(this.program, 'aPos');\r\n gl.enableVertexAttribArray(aPosLoc);\r\n gl.vertexAttribPointer(aPosLoc, 2, gl.FLOAT, false, 0, 0);\r\n const aTexCoordLoc = gl.getAttribLocation(this.program, 'aTexCoord');\r\n gl.enableVertexAttribArray(aTexCoordLoc);\r\n gl.vertexAttribPointer(aTexCoordLoc, 2, gl.FLOAT, false, 0, texCoordOffset);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n\r\n let i = 0;\r\n gl.useProgram(this.program);\r\n for (let p in this.constants) {\r\n this.kernelConstants[i++].updateValue(this.constants[p]);\r\n }\r\n\r\n if (!this.immutable) {\r\n this._setupOutputTexture();\r\n if (\r\n this.subKernels !== null &&\r\n this.subKernels.length > 0\r\n ) {\r\n this._setupSubOutputTextures();\r\n }\r\n }\r\n }\r\n\r\n translateSource() {\r\n const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, {\r\n fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy\r\n });\r\n this.translatedSource = functionBuilder.getPrototypeString('kernel');\r\n if (!this.graphical && !this.returnType) {\r\n this.returnType = functionBuilder.getKernelResultType();\r\n }\r\n\r\n if (this.subKernels && this.subKernels.length > 0) {\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (!subKernel.returnType) {\r\n subKernel.returnType = functionBuilder.getSubKernelResultType(i);\r\n }\r\n }\r\n }\r\n }\r\n\r\n run() {\r\n const { kernelArguments, forceUploadKernelConstants } = this;\r\n const texSize = this.texSize;\r\n const gl = this.context;\r\n\r\n gl.useProgram(this.program);\r\n gl.scissor(0, 0, texSize[0], texSize[1]);\r\n\r\n if (this.dynamicOutput) {\r\n this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim));\r\n this.setUniform2iv('uTexSize', texSize);\r\n }\r\n\r\n this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]);\r\n\r\n this.switchingKernels = false;\r\n for (let i = 0; i < forceUploadKernelConstants.length; i++) {\r\n const constant = forceUploadKernelConstants[i];\r\n constant.updateValue(this.constants[constant.name]);\r\n if (this.switchingKernels) return;\r\n }\r\n for (let i = 0; i < kernelArguments.length; i++) {\r\n kernelArguments[i].updateValue(arguments[i]);\r\n if (this.switchingKernels) return;\r\n }\r\n\r\n if (this.plugins) {\r\n for (let i = 0; i < this.plugins.length; i++) {\r\n const plugin = this.plugins[i];\r\n if (plugin.onBeforeRun) {\r\n plugin.onBeforeRun(this);\r\n }\r\n }\r\n }\r\n\r\n if (this.graphical) {\r\n if (this.pipeline) {\r\n gl.bindRenderbuffer(gl.RENDERBUFFER, null);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n if (!this.outputTexture || this.immutable) {\r\n this._setupOutputTexture();\r\n }\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n return new this.TextureConstructor({\r\n texture: this.outputTexture,\r\n size: texSize,\r\n dimensions: this.threadDim,\r\n output: this.output,\r\n context: this.context,\r\n });\r\n }\r\n gl.bindRenderbuffer(gl.RENDERBUFFER, null);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n return;\r\n }\r\n\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n if (this.immutable) {\r\n this._setupOutputTexture();\r\n }\r\n\r\n if (this.subKernels !== null) {\r\n if (this.immutable) {\r\n this._setupSubOutputTextures();\r\n }\r\n this.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(this.drawBuffersMap);\r\n }\r\n\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n }\r\n\r\n /**\r\n * @desc This return defined outputTexture, which is setup in .build(), or if immutable, is defined in .run()\r\n * @returns {Object} Output Texture Cache\r\n */\r\n getOutputTexture() {\r\n return this.outputTexture;\r\n }\r\n\r\n /**\r\n * @desc Setup and replace output texture\r\n */\r\n _setupOutputTexture() {\r\n const gl = this.context;\r\n const texSize = this.texSize;\r\n const texture = this.outputTexture = this.context.createTexture();\r\n gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n // if (this.precision === 'single') {\r\n // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n // } else {\r\n // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n // }\r\n if (this.precision === 'single') {\r\n if (this.pipeline) {\r\n // TODO: investigate if webgl1 can handle gl.RED usage in gl.texImage2D, otherwise, simplify the below\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Float':\r\n case 'Integer':\r\n if (this.optimizeFloatMemory) {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n }\r\n break;\r\n case 'Array(2)':\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n break;\r\n case 'Array(3)':\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n break;\r\n case 'Array(4)':\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n break;\r\n default:\r\n if (!this.graphical) {\r\n throw new Error('Unhandled return type');\r\n }\r\n }\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n }\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n }\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);\r\n }\r\n\r\n /**\r\n * @desc Setup and replace sub-output textures\r\n */\r\n _setupSubOutputTextures() {\r\n const gl = this.context;\r\n const texSize = this.texSize;\r\n this.drawBuffersMap = [gl.COLOR_ATTACHMENT0];\r\n this.subKernelOutputTextures = [];\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const texture = this.context.createTexture();\r\n this.subKernelOutputTextures.push(texture);\r\n this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1);\r\n gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n if (this.precision === 'single') {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n }\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0);\r\n }\r\n }\r\n\r\n /**\r\n * @desc Returns the Texture Cache of the supplied parameter (can be kernel, sub-kernel or argument)\r\n * @param {String} name - Name of the subkernel, argument, or kernel.\r\n * @returns {Object} Texture cache\r\n */\r\n getTextureCache(name) {\r\n if (this.textureCache.hasOwnProperty(name)) {\r\n return this.textureCache[name];\r\n }\r\n return this.textureCache[name] = this.context.createTexture();\r\n }\r\n\r\n /**\r\n * @desc removes a texture from the kernel's cache\r\n * @param {String} name - Name of texture\r\n */\r\n detachTextureCache(name) {\r\n delete this.textureCache[name];\r\n }\r\n\r\n setUniform1f(name, value) {\r\n if (this.uniform1fCache.hasOwnProperty(name)) {\r\n const cache = this.uniform1fCache[name];\r\n if (value === cache) {\r\n return;\r\n }\r\n }\r\n this.uniform1fCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform1f(loc, value);\r\n }\r\n\r\n setUniform1i(name, value) {\r\n if (this.uniform1iCache.hasOwnProperty(name)) {\r\n const cache = this.uniform1iCache[name];\r\n if (value === cache) {\r\n return;\r\n }\r\n }\r\n this.uniform1iCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform1i(loc, value);\r\n }\r\n\r\n setUniform2f(name, value1, value2) {\r\n if (this.uniform2fCache.hasOwnProperty(name)) {\r\n const cache = this.uniform2fCache[name];\r\n if (\r\n value1 === cache[0] &&\r\n value2 === cache[1]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform2fCache[name] = [value1, value2];\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform2f(loc, value1, value2);\r\n }\r\n\r\n setUniform2fv(name, value) {\r\n if (this.uniform2fvCache.hasOwnProperty(name)) {\r\n const cache = this.uniform2fvCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform2fvCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform2fv(loc, value);\r\n }\r\n\r\n setUniform2iv(name, value) {\r\n if (this.uniform2ivCache.hasOwnProperty(name)) {\r\n const cache = this.uniform2ivCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform2ivCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform2iv(loc, value);\r\n }\r\n\r\n setUniform3fv(name, value) {\r\n if (this.uniform3fvCache.hasOwnProperty(name)) {\r\n const cache = this.uniform3fvCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1] &&\r\n value[2] === cache[2]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform3fvCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform3fv(loc, value);\r\n }\r\n\r\n setUniform3iv(name, value) {\r\n if (this.uniform3ivCache.hasOwnProperty(name)) {\r\n const cache = this.uniform3ivCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1] &&\r\n value[2] === cache[2]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform3ivCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform3iv(loc, value);\r\n }\r\n\r\n setUniform3fv(name, value) {\r\n if (this.uniform3fvCache.hasOwnProperty(name)) {\r\n const cache = this.uniform3fvCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1] &&\r\n value[2] === cache[2]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform3fvCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform3fv(loc, value);\r\n }\r\n\r\n setUniform4iv(name, value) {\r\n if (this.uniform4ivCache.hasOwnProperty(name)) {\r\n const cache = this.uniform4ivCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1] &&\r\n value[2] === cache[2] &&\r\n value[3] === cache[3]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform4ivCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform4iv(loc, value);\r\n }\r\n\r\n setUniform4fv(name, value) {\r\n if (this.uniform4fvCache.hasOwnProperty(name)) {\r\n const cache = this.uniform4fvCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1] &&\r\n value[2] === cache[2] &&\r\n value[3] === cache[3]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform4fvCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform4fv(loc, value);\r\n }\r\n\r\n /**\r\n * @desc Return WebGlUniformLocation for various variables\r\n * related to webGl program, such as user-defined variables,\r\n * as well as, dimension sizes, etc.\r\n */\r\n getUniformLocation(name) {\r\n if (this.programUniformLocationCache.hasOwnProperty(name)) {\r\n return this.programUniformLocationCache[name];\r\n }\r\n return this.programUniformLocationCache[name] = this.context.getUniformLocation(this.program, name);\r\n }\r\n\r\n /**\r\n * @desc Generate Shader artifacts for the kernel program.\r\n * The final object contains HEADER, KERNEL, MAIN_RESULT, and others.\r\n *\r\n * @param {Array} args - The actual parameters sent to the Kernel\r\n * @returns {Object} An object containing the Shader Artifacts(CONSTANTS, HEADER, KERNEL, etc.)\r\n */\r\n _getFragShaderArtifactMap(args) {\r\n return {\r\n HEADER: this._getHeaderString(),\r\n LOOP_MAX: this._getLoopMaxString(),\r\n PLUGINS: this._getPluginsString(),\r\n CONSTANTS: this._getConstantsString(),\r\n DECODE32_ENDIANNESS: this._getDecode32EndiannessString(),\r\n ENCODE32_ENDIANNESS: this._getEncode32EndiannessString(),\r\n DIVIDE_WITH_INTEGER_CHECK: this._getDivideWithIntegerCheckString(),\r\n INJECTED_NATIVE: this._getInjectedNative(),\r\n MAIN_CONSTANTS: this._getMainConstantsString(),\r\n MAIN_ARGUMENTS: this._getMainArgumentsString(args),\r\n KERNEL: this.getKernelString(),\r\n MAIN_RESULT: this.getMainResultString(),\r\n FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(),\r\n INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(),\r\n SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(),\r\n SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(),\r\n };\r\n }\r\n\r\n /**\r\n * @desc Generate Shader artifacts for the kernel program.\r\n * The final object contains HEADER, KERNEL, MAIN_RESULT, and others.\r\n *\r\n * @param {Array} args - The actual parameters sent to the Kernel\r\n * @returns {Object} An object containing the Shader Artifacts(CONSTANTS, HEADER, KERNEL, etc.)\r\n */\r\n _getVertShaderArtifactMap(args) {\r\n return {\r\n FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(),\r\n INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(),\r\n SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(),\r\n SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(),\r\n };\r\n }\r\n\r\n /**\r\n * @desc Get the header string for the program.\r\n * This returns an empty string if no sub-kernels are defined.\r\n *\r\n * @returns {String} result\r\n */\r\n _getHeaderString() {\r\n return (\r\n this.subKernels !== null ?\r\n '#extension GL_EXT_draw_buffers : require\\n' :\r\n ''\r\n );\r\n }\r\n\r\n /**\r\n * @desc Get the maximum loop size String.\r\n * @returns {String} result\r\n */\r\n _getLoopMaxString() {\r\n return (\r\n this.loopMaxIterations ?\r\n ` ${parseInt(this.loopMaxIterations)};\\n` :\r\n ' 1000;\\n'\r\n );\r\n }\r\n\r\n _getPluginsString() {\r\n if (!this.plugins) return '\\n';\r\n return this.plugins.map(plugin => plugin.source && this.source.match(plugin.functionMatch) ? plugin.source : '').join('\\n');\r\n }\r\n\r\n /**\r\n * @desc Generate transpiled glsl Strings for constant parameters sent to a kernel\r\n * @returns {String} result\r\n */\r\n _getConstantsString() {\r\n const result = [];\r\n const { threadDim, texSize } = this;\r\n if (this.dynamicOutput) {\r\n result.push(\r\n 'uniform ivec3 uOutputDim',\r\n 'uniform ivec2 uTexSize'\r\n );\r\n } else {\r\n result.push(\r\n `ivec3 uOutputDim = ivec3(${threadDim[0]}, ${threadDim[1]}, ${threadDim[2]})`,\r\n `ivec2 uTexSize = ivec2(${texSize[0]}, ${texSize[1]})`\r\n );\r\n }\r\n return utils.linesToString(result);\r\n }\r\n\r\n /**\r\n * @desc Get texture coordinate string for the program\r\n * @returns {String} result\r\n */\r\n _getTextureCoordinate() {\r\n const subKernels = this.subKernels;\r\n if (subKernels === null || subKernels.length < 1) {\r\n return 'varying vec2 vTexCoord;\\n';\r\n } else {\r\n return 'out vec2 vTexCoord;\\n';\r\n }\r\n }\r\n\r\n /**\r\n * @desc Get Decode32 endianness string for little-endian and big-endian\r\n * @returns {String} result\r\n */\r\n _getDecode32EndiannessString() {\r\n return (\r\n this.endianness === 'LE' ?\r\n '' :\r\n ' texel.rgba = texel.abgr;\\n'\r\n );\r\n }\r\n\r\n /**\r\n * @desc Get Encode32 endianness string for little-endian and big-endian\r\n * @returns {String} result\r\n */\r\n _getEncode32EndiannessString() {\r\n return (\r\n this.endianness === 'LE' ?\r\n '' :\r\n ' texel.rgba = texel.abgr;\\n'\r\n );\r\n }\r\n\r\n /**\r\n * @desc if fixIntegerDivisionAccuracy provide method to replace /\r\n * @returns {String} result\r\n */\r\n _getDivideWithIntegerCheckString() {\r\n return this.fixIntegerDivisionAccuracy ?\r\n `float div_with_int_check(float x, float y) {\r\n if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) {\r\n return float(int(x)/int(y));\r\n }\r\n return x / y;\r\n}` :\r\n '';\r\n }\r\n\r\n /**\r\n * @desc Generate transpiled glsl Strings for user-defined parameters sent to a kernel\r\n * @param {Array} args - The actual parameters sent to the Kernel\r\n * @returns {String} result\r\n */\r\n _getMainArgumentsString(args) {\r\n const results = [];\r\n const { argumentNames } = this;\r\n for (let i = 0; i < argumentNames.length; i++) {\r\n results.push(this.kernelArguments[i].getSource(args[i]));\r\n }\r\n return results.join('');\r\n }\r\n\r\n _getInjectedNative() {\r\n return this.injectedNative || '';\r\n }\r\n\r\n _getMainConstantsString() {\r\n const result = [];\r\n const { constants } = this;\r\n if (constants) {\r\n let i = 0;\r\n for (const name in constants) {\r\n result.push(this.kernelConstants[i++].getSource(this.constants[name]));\r\n }\r\n }\r\n return result.join('');\r\n }\r\n\r\n /**\r\n * @desc Get Kernel program string (in *glsl*) for a kernel.\r\n * @returns {String} result\r\n */\r\n getKernelString() {\r\n let kernelResultDeclaration;\r\n switch (this.returnType) {\r\n case 'Array(2)':\r\n kernelResultDeclaration = 'vec2 kernelResult';\r\n break;\r\n case 'Array(3)':\r\n kernelResultDeclaration = 'vec3 kernelResult';\r\n break;\r\n case 'Array(4)':\r\n kernelResultDeclaration = 'vec4 kernelResult';\r\n break;\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n kernelResultDeclaration = 'float kernelResult';\r\n break;\r\n default:\r\n if (this.graphical) {\r\n kernelResultDeclaration = 'float kernelResult';\r\n } else {\r\n throw new Error(`unrecognized output type \"${ this.returnType }\"`);\r\n }\r\n }\r\n\r\n const result = [];\r\n const subKernels = this.subKernels;\r\n if (subKernels !== null) {\r\n result.push(\r\n kernelResultDeclaration\r\n );\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Float':\r\n case 'Integer':\r\n for (let i = 0; i < subKernels.length; i++) {\r\n const subKernel = subKernels[i];\r\n result.push(\r\n subKernel.returnType === 'Integer' ?\r\n `int subKernelResult_${ subKernel.name } = 0` :\r\n `float subKernelResult_${ subKernel.name } = 0.0`\r\n );\r\n }\r\n break;\r\n case 'Array(2)':\r\n for (let i = 0; i < subKernels.length; i++) {\r\n result.push(\r\n `vec2 subKernelResult_${ subKernels[i].name }`\r\n );\r\n }\r\n break;\r\n case 'Array(3)':\r\n for (let i = 0; i < subKernels.length; i++) {\r\n result.push(\r\n `vec3 subKernelResult_${ subKernels[i].name }`\r\n );\r\n }\r\n break;\r\n case 'Array(4)':\r\n for (let i = 0; i < subKernels.length; i++) {\r\n result.push(\r\n `vec4 subKernelResult_${ subKernels[i].name }`\r\n );\r\n }\r\n break;\r\n }\r\n } else {\r\n result.push(\r\n kernelResultDeclaration\r\n );\r\n }\r\n\r\n return utils.linesToString(result) + this.translatedSource;\r\n }\r\n\r\n getMainResultGraphical() {\r\n return utils.linesToString([\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' gl_FragColor = actualColor',\r\n ]);\r\n }\r\n\r\n getMainResultPackedPixels() {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n return this.getMainResultKernelPackedPixels() +\r\n this.getMainResultSubKernelPackedPixels();\r\n default:\r\n throw new Error(`packed output only usable with Numbers, \"${this.returnType}\" specified`);\r\n }\r\n }\r\n\r\n /**\r\n * @return {String}\r\n */\r\n getMainResultKernelPackedPixels() {\r\n return utils.linesToString([\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ` gl_FragData[0] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)`\r\n ]);\r\n }\r\n\r\n /**\r\n * @return {String}\r\n */\r\n getMainResultSubKernelPackedPixels() {\r\n const result = [];\r\n if (!this.subKernels) return '';\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))`\r\n );\r\n } else {\r\n result.push(\r\n ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})`\r\n );\r\n }\r\n }\r\n return utils.linesToString(result);\r\n }\r\n\r\n getMainResultMemoryOptimizedFloats() {\r\n const result = [\r\n ' index *= 4',\r\n ];\r\n\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n const channels = ['r', 'g', 'b', 'a'];\r\n for (let i = 0; i < channels.length; i++) {\r\n const channel = channels[i];\r\n this.getMainResultKernelMemoryOptimizedFloats(result, channel);\r\n this.getMainResultSubKernelMemoryOptimizedFloats(result, channel);\r\n if (i + 1 < channels.length) {\r\n result.push(' index += 1');\r\n }\r\n }\r\n break;\r\n default:\r\n throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`);\r\n }\r\n\r\n return utils.linesToString(result);\r\n }\r\n\r\n getMainResultKernelMemoryOptimizedFloats(result, channel) {\r\n result.push(\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ` gl_FragData[0].${channel} = kernelResult`,\r\n );\r\n }\r\n\r\n getMainResultSubKernelMemoryOptimizedFloats(result, channel) {\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` gl_FragData[${i + 1}].${channel} = float(subKernelResult_${this.subKernels[i].name})`,\r\n );\r\n } else {\r\n result.push(\r\n ` gl_FragData[${i + 1}].${channel} = subKernelResult_${this.subKernels[i].name}`,\r\n );\r\n }\r\n }\r\n }\r\n\r\n getMainResultKernelNumberTexture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' gl_FragData[0][0] = kernelResult',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelNumberTexture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = float(subKernelResult_${subKernel.name})`,\r\n );\r\n } else {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${subKernel.name}`,\r\n );\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray2Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' gl_FragData[0][0] = kernelResult[0]',\r\n ' gl_FragData[0][1] = kernelResult[1]',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray2Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,\r\n ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray3Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' gl_FragData[0][0] = kernelResult[0]',\r\n ' gl_FragData[0][1] = kernelResult[1]',\r\n ' gl_FragData[0][2] = kernelResult[2]',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray3Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,\r\n ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,\r\n ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`,\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray4Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' gl_FragData[0] = kernelResult',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray4Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Float':\r\n case 'Integer':\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` gl_FragData[${i + 1}] = float(subKernelResult_${this.subKernels[i].name})`,\r\n );\r\n } else {\r\n result.push(\r\n ` gl_FragData[${i + 1}] = subKernelResult_${this.subKernels[i].name}`,\r\n );\r\n }\r\n }\r\n break;\r\n case 'Array(2)':\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,\r\n ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,\r\n );\r\n }\r\n break;\r\n case 'Array(3)':\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,\r\n ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,\r\n ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`,\r\n );\r\n }\r\n break;\r\n case 'Array(4)':\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,\r\n ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,\r\n ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`,\r\n ` gl_FragData[${i + 1}][3] = subKernelResult_${this.subKernels[i].name}[3]`,\r\n );\r\n }\r\n break;\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * @param {String} src - Shader string\r\n * @param {Object} map - Variables/Constants associated with shader\r\n */\r\n replaceArtifacts(src, map) {\r\n return src.replace(/[ ]*__([A-Z]+[0-9]*([_]?[A-Z]*[0-9]?)*)__;\\n/g, (match, artifact) => {\r\n if (map.hasOwnProperty(artifact)) {\r\n return map[artifact];\r\n }\r\n throw `unhandled artifact ${artifact}`;\r\n });\r\n }\r\n\r\n /**\r\n * @desc Get the fragment shader String.\r\n * If the String hasn't been compiled yet,\r\n * then this method compiles it as well\r\n *\r\n * @param {Array} args - The actual parameters sent to the Kernel\r\n * @returns {string} Fragment Shader string\r\n */\r\n getFragmentShader(args) {\r\n if (this.compiledFragmentShader !== null) {\r\n return this.compiledFragmentShader;\r\n }\r\n return this.compiledFragmentShader = this.replaceArtifacts(this.constructor.fragmentShader, this._getFragShaderArtifactMap(args));\r\n }\r\n\r\n /**\r\n * @desc Get the vertical shader String\r\n * @param {Array|IArguments} args - The actual parameters sent to the Kernel\r\n * @returns {string} Vertical Shader string\r\n */\r\n getVertexShader(args) {\r\n if (this.compiledVertexShader !== null) {\r\n return this.compiledVertexShader;\r\n }\r\n return this.compiledVertexShader = this.replaceArtifacts(this.constructor.vertexShader, this._getVertShaderArtifactMap(args));\r\n }\r\n\r\n /**\r\n * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused.\r\n */\r\n toString() {\r\n const setupContextString = utils.linesToString([\r\n `const gl = context`,\r\n ]);\r\n return glKernelString(this.constructor, arguments, this, setupContextString);\r\n }\r\n\r\n destroy(removeCanvasReferences) {\r\n if (this.outputTexture) {\r\n this.context.deleteTexture(this.outputTexture);\r\n }\r\n if (this.buffer) {\r\n this.context.deleteBuffer(this.buffer);\r\n }\r\n if (this.framebuffer) {\r\n this.context.deleteFramebuffer(this.framebuffer);\r\n }\r\n if (this.vertShader) {\r\n this.context.deleteShader(this.vertShader);\r\n }\r\n if (this.fragShader) {\r\n this.context.deleteShader(this.fragShader);\r\n }\r\n if (this.program) {\r\n this.context.deleteProgram(this.program);\r\n }\r\n\r\n const keys = Object.keys(this.textureCache);\r\n\r\n for (let i = 0; i < keys.length; i++) {\r\n const name = keys[i];\r\n this.context.deleteTexture(this.textureCache[name]);\r\n }\r\n\r\n if (this.subKernelOutputTextures) {\r\n for (let i = 0; i < this.subKernelOutputTextures.length; i++) {\r\n this.context.deleteTexture(this.subKernelOutputTextures[i]);\r\n }\r\n }\r\n if (removeCanvasReferences) {\r\n const idx = canvases.indexOf(this.canvas);\r\n if (idx >= 0) {\r\n canvases[idx] = null;\r\n maxTexSizes[idx] = null;\r\n }\r\n }\r\n this.destroyExtensions();\r\n delete this.context;\r\n delete this.canvas;\r\n }\r\n\r\n destroyExtensions() {\r\n this.extensions.OES_texture_float = null;\r\n this.extensions.OES_texture_float_linear = null;\r\n this.extensions.OES_element_index_uint = null;\r\n this.extensions.WEBGL_draw_buffers = null;\r\n }\r\n\r\n static destroyContext(context) {\r\n const extension = context.getExtension('WEBGL_lose_context');\r\n if (extension) {\r\n extension.loseContext();\r\n }\r\n }\r\n\r\n toJSON() {\r\n const json = super.toJSON();\r\n json.functionNodes = FunctionBuilder.fromKernel(this, WebGLFunctionNode).toJSON();\r\n return json;\r\n }\r\n}\r\n","import { WebGLFunctionNode } from '../web-gl/function-node';\r\n\r\n/**\r\n * @class WebGL2FunctionNode\r\n * @desc [INTERNAL] Takes in a function node, and does all the AST voodoo required to toString its respective webGL code.\r\n * @extends WebGLFunctionNode\r\n * @returns the converted webGL function string\r\n */\r\nexport class WebGL2FunctionNode extends WebGLFunctionNode {\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *identifier* expression\r\n * @param {Object} idtNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astIdentifierExpression(idtNode, retArr) {\r\n if (idtNode.type !== 'Identifier') {\r\n throw this.astErrorOutput(\r\n 'IdentifierExpression - not an Identifier',\r\n idtNode\r\n );\r\n }\r\n\r\n const type = this.getType(idtNode);\r\n\r\n if (idtNode.name === 'Infinity') {\r\n retArr.push('intBitsToFloat(2139095039)');\r\n } else if (type === 'Boolean') {\r\n if (this.argumentNames.indexOf(idtNode.name) > -1) {\r\n retArr.push(`bool(user_${idtNode.name})`);\r\n } else {\r\n retArr.push(`user_${idtNode.name}`);\r\n }\r\n } else {\r\n retArr.push(`user_${idtNode.name}`);\r\n }\r\n\r\n return retArr;\r\n }\r\n}\r\n","// language=GLSL\r\nexport const fragmentShader = `#version 300 es\r\n__HEADER__;\r\n__FLOAT_TACTIC_DECLARATION__;\r\n__INT_TACTIC_DECLARATION__;\r\n__SAMPLER_2D_TACTIC_DECLARATION__;\r\n__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__;\r\n\r\nconst int LOOP_MAX = __LOOP_MAX__;\r\n\r\n__PLUGINS__;\r\n__CONSTANTS__;\r\n\r\nin vec2 vTexCoord;\r\n\r\nconst int BIT_COUNT = 32;\r\nint modi(int x, int y) {\r\n return x - y * (x / y);\r\n}\r\n\r\nint bitwiseOr(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 || b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseXOR(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 || b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseAnd(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 && b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseNot(int a) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (modi(a, 2) == 0) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n n = n * 2;\r\n }\r\n return result;\r\n}\r\nint bitwiseZeroFillLeftShift(int n, int shift) {\r\n int maxBytes = BIT_COUNT;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (maxBytes >= n) {\r\n break;\r\n }\r\n maxBytes *= 2;\r\n }\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= shift) {\r\n break;\r\n }\r\n n *= 2;\r\n }\r\n\r\n int result = 0;\r\n int byteVal = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= maxBytes) break;\r\n if (modi(n, 2) > 0) { result += byteVal; }\r\n n = int(n / 2);\r\n byteVal *= 2;\r\n }\r\n return result;\r\n}\r\n\r\nint bitwiseSignedRightShift(int num, int shifts) {\r\n return int(floor(float(num) / pow(2.0, float(shifts))));\r\n}\r\n\r\nint bitwiseZeroFillRightShift(int n, int shift) {\r\n int maxBytes = BIT_COUNT;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (maxBytes >= n) {\r\n break;\r\n }\r\n maxBytes *= 2;\r\n }\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= shift) {\r\n break;\r\n }\r\n n /= 2;\r\n }\r\n int result = 0;\r\n int byteVal = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= maxBytes) break;\r\n if (modi(n, 2) > 0) { result += byteVal; }\r\n n = int(n / 2);\r\n byteVal *= 2;\r\n }\r\n return result;\r\n}\r\n\r\nvec2 integerMod(vec2 x, float y) {\r\n vec2 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nvec3 integerMod(vec3 x, float y) {\r\n vec3 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nvec4 integerMod(vec4 x, vec4 y) {\r\n vec4 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nfloat integerMod(float x, float y) {\r\n float res = floor(mod(x, y));\r\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\r\n}\r\n\r\nint integerMod(int x, int y) {\r\n return x - (y * int(x/y));\r\n}\r\n\r\n__DIVIDE_WITH_INTEGER_CHECK__;\r\n\r\n// Here be dragons!\r\n// DO NOT OPTIMIZE THIS CODE\r\n// YOU WILL BREAK SOMETHING ON SOMEBODY\\'S MACHINE\r\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\r\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\r\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\r\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\r\nfloat decode32(vec4 texel) {\r\n __DECODE32_ENDIANNESS__;\r\n texel *= 255.0;\r\n vec2 gte128;\r\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\r\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\r\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\r\n float res = exp2(round(exponent));\r\n texel.b = texel.b - 128.0 * gte128.x;\r\n res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;\r\n res *= gte128.y * -2.0 + 1.0;\r\n return res;\r\n}\r\n\r\nfloat decode16(vec4 texel, int index) {\r\n int channel = integerMod(index, 2);\r\n return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0;\r\n}\r\n\r\nfloat decode8(vec4 texel, int index) {\r\n int channel = integerMod(index, 4);\r\n return texel[channel] * 255.0;\r\n}\r\n\r\nvec4 legacyEncode32(float f) {\r\n float F = abs(f);\r\n float sign = f < 0.0 ? 1.0 : 0.0;\r\n float exponent = floor(log2(F));\r\n float mantissa = (exp2(-exponent) * F);\r\n // exponent += floor(log2(mantissa));\r\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\r\n texel.rg = integerMod(texel.rg, 256.0);\r\n texel.b = integerMod(texel.b, 128.0);\r\n texel.a = exponent*0.5 + 63.5;\r\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\r\n texel = floor(texel);\r\n texel *= 0.003921569; // 1/255\r\n __ENCODE32_ENDIANNESS__;\r\n return texel;\r\n}\r\n\r\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\r\nvec4 encode32(float value) {\r\n if (value == 0.0) return vec4(0, 0, 0, 0);\r\n\r\n float exponent;\r\n float mantissa;\r\n vec4 result;\r\n float sgn;\r\n\r\n sgn = step(0.0, -value);\r\n value = abs(value);\r\n\r\n exponent = floor(log2(value));\r\n\r\n mantissa = value*pow(2.0, -exponent)-1.0;\r\n exponent = exponent+127.0;\r\n result = vec4(0,0,0,0);\r\n\r\n result.a = floor(exponent/2.0);\r\n exponent = exponent - result.a*2.0;\r\n result.a = result.a + 128.0*sgn;\r\n\r\n result.b = floor(mantissa * 128.0);\r\n mantissa = mantissa - result.b / 128.0;\r\n result.b = result.b + exponent*128.0;\r\n\r\n result.g = floor(mantissa*32768.0);\r\n mantissa = mantissa - result.g/32768.0;\r\n\r\n result.r = floor(mantissa*8388608.0);\r\n return result/255.0;\r\n}\r\n// Dragons end here\r\n\r\nint index;\r\nivec3 threadId;\r\n\r\nivec3 indexTo3D(int idx, ivec3 texDim) {\r\n int z = int(idx / (texDim.x * texDim.y));\r\n idx -= z * int(texDim.x * texDim.y);\r\n int y = int(idx / texDim.x);\r\n int x = int(integerMod(idx, texDim.x));\r\n return ivec3(x, y, z);\r\n}\r\n\r\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture(tex, st / vec2(texSize));\r\n return decode32(texel);\r\n}\r\n\r\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + (texDim.x * (y + (texDim.y * z)));\r\n int w = texSize.x * 2;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y));\r\n return decode16(texel, index);\r\n}\r\n\r\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + (texDim.x * (y + (texDim.y * z)));\r\n int w = texSize.x * 4;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y));\r\n return decode8(texel, index);\r\n}\r\n\r\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + (texDim.x * (y + (texDim.y * z)));\r\n int channel = integerMod(index, 4);\r\n index = index / 4;\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n index = index / 4;\r\n vec4 texel = texture(tex, st / vec2(texSize));\r\n return texel[channel];\r\n}\r\n\r\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n return texture(tex, st / vec2(texSize));\r\n}\r\n\r\nvec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n return texture(tex, vec3(st / vec2(texSize), z));\r\n}\r\n\r\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return result[0];\r\n}\r\n\r\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return vec2(result[0], result[1]);\r\n}\r\n\r\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int channel = integerMod(index, 2);\r\n index = index / 2;\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture(tex, st / vec2(texSize));\r\n if (channel == 0) return vec2(texel.r, texel.g);\r\n if (channel == 1) return vec2(texel.b, texel.a);\r\n return vec2(0.0, 0.0);\r\n}\r\n\r\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return vec3(result[0], result[1], result[2]);\r\n}\r\n\r\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\r\n int vectorIndex = fieldIndex / 4;\r\n int vectorOffset = fieldIndex - vectorIndex * 4;\r\n int readY = vectorIndex / texSize.x;\r\n int readX = vectorIndex - readY * texSize.x;\r\n vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\r\n\r\n if (vectorOffset == 0) {\r\n return tex1.xyz;\r\n } else if (vectorOffset == 1) {\r\n return tex1.yzw;\r\n } else {\r\n readX++;\r\n if (readX >= texSize.x) {\r\n readX = 0;\r\n readY++;\r\n }\r\n vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize));\r\n if (vectorOffset == 2) {\r\n return vec3(tex1.z, tex1.w, tex2.x);\r\n } else {\r\n return vec3(tex1.w, tex2.x, tex2.y);\r\n }\r\n }\r\n}\r\n\r\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n return getImage2D(tex, texSize, texDim, z, y, x);\r\n}\r\n\r\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int channel = integerMod(index, 2);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture(tex, st / vec2(texSize));\r\n return vec4(texel.r, texel.g, texel.b, texel.a);\r\n}\r\n\r\nvec4 actualColor;\r\nvoid color(float r, float g, float b, float a) {\r\n actualColor = vec4(r,g,b,a);\r\n}\r\n\r\nvoid color(float r, float g, float b) {\r\n color(r,g,b,1.0);\r\n}\r\n\r\n__INJECTED_NATIVE__;\r\n__MAIN_CONSTANTS__;\r\n__MAIN_ARGUMENTS__;\r\n__KERNEL__;\r\n\r\nvoid main(void) {\r\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\r\n __MAIN_RESULT__;\r\n}`;\r\n","// language=GLSL\r\nexport const vertexShader = `#version 300 es\r\n__FLOAT_TACTIC_DECLARATION__;\r\n__INT_TACTIC_DECLARATION__;\r\n__SAMPLER_2D_TACTIC_DECLARATION__;\r\n\r\nin vec2 aPos;\r\nin vec2 aTexCoord;\r\n\r\nout vec2 vTexCoord;\r\nuniform vec2 ratio;\r\n\r\nvoid main(void) {\r\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\r\n vTexCoord = aTexCoord;\r\n}`;\r\n","import { WebGLKernelValueBoolean } from '../../web-gl/kernel-value/boolean';\r\n\r\nexport class WebGL2KernelValueBoolean extends WebGLKernelValueBoolean {}\r\n","import { WebGLKernelValueFloat } from '../../web-gl/kernel-value/float';\r\n\r\nexport class WebGL2KernelValueFloat extends WebGLKernelValueFloat {}\r\n","import { WebGLKernelValueInteger } from '../../web-gl/kernel-value/integer';\r\n\r\nexport class WebGL2KernelValueInteger extends WebGLKernelValueInteger {\r\n getSource(value) {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n if (this.origin === 'constants') {\r\n return `const ${ variablePrecision } int ${this.id} = ${ parseInt(value) };\\n`;\r\n }\r\n return `uniform ${ variablePrecision } int ${this.id};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform1i(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueHTMLImage } from '../../web-gl/kernel-value/html-image';\r\n\r\nexport class WebGL2KernelValueHTMLImage extends WebGLKernelValueHTMLImage {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueDynamicHTMLImage } from '../../web-gl/kernel-value/dynamic-html-image';\r\n\r\nexport class WebGL2KernelValueDynamicHTMLImage extends WebGLKernelValueDynamicHTMLImage {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from '../../web-gl/kernel-value/index';\r\n\r\nexport class WebGL2KernelValueHTMLImageArray extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.checkSize(value[0].width, value[0].height);\r\n this.requestTexture();\r\n this.dimensions = [value[0].width, value[0].height, value.length];\r\n this.textureSize = [value[0].width, value[0].height];\r\n }\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2DArray ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(images) {\r\n const { context: gl } = this;\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\r\n // Upload the images into the texture.\r\n gl.texImage3D(\r\n gl.TEXTURE_2D_ARRAY,\r\n 0,\r\n gl.RGBA,\r\n images[0].width,\r\n images[0].height,\r\n images.length,\r\n 0,\r\n gl.RGBA,\r\n gl.UNSIGNED_BYTE,\r\n null\r\n );\r\n for (let i = 0; i < images.length; i++) {\r\n const xOffset = 0;\r\n const yOffset = 0;\r\n const imageDepth = 1;\r\n gl.texSubImage3D(\r\n gl.TEXTURE_2D_ARRAY,\r\n 0,\r\n xOffset,\r\n yOffset,\r\n i,\r\n images[i].width,\r\n images[i].height,\r\n imageDepth,\r\n gl.RGBA,\r\n gl.UNSIGNED_BYTE,\r\n this.uploadValue = images[i]\r\n );\r\n }\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { WebGL2KernelValueHTMLImageArray } from './html-image-array';\r\n\r\nexport class WebGL2KernelValueDynamicHTMLImageArray extends WebGL2KernelValueHTMLImageArray {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2DArray ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(images) {\r\n const { width, height } = images[0];\r\n this.checkSize(width, height);\r\n this.dimensions = [width, height, images.length];\r\n this.textureSize = [width, height];\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(images);\r\n }\r\n}\r\n","import { WebGL2KernelValueHTMLImage } from './html-image';\r\n\r\nexport class WebGL2KernelValueHTMLVideo extends WebGL2KernelValueHTMLImage {}\r\n","import { WebGL2KernelValueDynamicHTMLImage } from './dynamic-html-image';\r\n\r\nexport class WebGL2KernelValueDynamicHTMLVideo extends WebGL2KernelValueDynamicHTMLImage {}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleInput } from '../../web-gl/kernel-value/single-input';\r\n\r\nexport class WebGL2KernelValueSingleInput extends WebGLKernelValueSingleInput {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(input) {\r\n const { context: gl } = this;\r\n utils.flattenTo(input.value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGL2KernelValueSingleInput } from '../../web-gl2/kernel-value/single-input';\r\n\r\nexport class WebGL2KernelValueDynamicSingleInput extends WebGL2KernelValueSingleInput {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n let [w, h, d] = value.size;\r\n this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueUnsignedInput } from '../../web-gl/kernel-value/unsigned-input';\r\n\r\nexport class WebGL2KernelValueUnsignedInput extends WebGLKernelValueUnsignedInput {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueDynamicUnsignedInput } from '../../web-gl/kernel-value/dynamic-unsigned-input';\r\n\r\nexport class WebGL2KernelValueDynamicUnsignedInput extends WebGLKernelValueDynamicUnsignedInput {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueMemoryOptimizedNumberTexture } from '../../web-gl/kernel-value/memory-optimized-number-texture';\r\n\r\nexport class WebGL2KernelValueMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture {\r\n getSource() {\r\n const { id, sizeId, textureSize, dimensionsId, dimensions } = this;\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform sampler2D ${id}`,\r\n `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } from '../../web-gl/kernel-value/dynamic-memory-optimized-number-texture';\r\n\r\nexport class WebGL2KernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueDynamicMemoryOptimizedNumberTexture {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueNumberTexture } from '../../web-gl/kernel-value/number-texture';\r\n\r\nexport class WebGL2KernelValueNumberTexture extends WebGLKernelValueNumberTexture {\r\n getSource() {\r\n const { id, sizeId, textureSize, dimensionsId, dimensions } = this;\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${id}`,\r\n `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueDynamicNumberTexture } from '../../web-gl/kernel-value/dynamic-number-texture';\r\n\r\nexport class WebGL2KernelValueDynamicNumberTexture extends WebGLKernelValueDynamicNumberTexture {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray } from '../../web-gl/kernel-value/single-array';\r\n\r\nexport class WebGL2KernelValueSingleArray extends WebGLKernelValueSingleArray {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGL2KernelValueSingleArray } from '../../web-gl2/kernel-value/single-array';\r\n\r\nexport class WebGL2KernelValueDynamicSingleArray extends WebGL2KernelValueSingleArray {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.dimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray1DI } from '../../web-gl/kernel-value/single-array1d-i';\r\n\r\nexport class WebGL2KernelValueSingleArray1DI extends WebGLKernelValueSingleArray1DI {\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGL2KernelValueSingleArray1DI } from '../../web-gl2/kernel-value/single-array1d-i';\r\n\r\nexport class WebGL2KernelValueDynamicSingleArray1DI extends WebGL2KernelValueSingleArray1DI {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray2DI } from '../../web-gl/kernel-value/single-array2d-i';\r\n\r\nexport class WebGL2KernelValueSingleArray2DI extends WebGLKernelValueSingleArray2DI {\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGL2KernelValueSingleArray2DI } from '../../web-gl2/kernel-value/single-array2d-i';\r\n\r\nexport class WebGL2KernelValueDynamicSingleArray2DI extends WebGL2KernelValueSingleArray2DI {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray3DI } from '../../web-gl/kernel-value/single-array3d-i';\r\n\r\nexport class WebGL2KernelValueSingleArray3DI extends WebGLKernelValueSingleArray3DI {\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGL2KernelValueSingleArray3DI } from '../../web-gl2/kernel-value/single-array3d-i';\r\n\r\nexport class WebGL2KernelValueDynamicSingleArray3DI extends WebGL2KernelValueSingleArray3DI {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { WebGLKernelValueSingleArray2 } from '../../web-gl/kernel-value/single-array2';\r\n\r\nexport class WebGL2KernelValueSingleArray2 extends WebGLKernelValueSingleArray2 {}\r\n","import { WebGLKernelValueSingleArray3 } from '../../web-gl/kernel-value/single-array3';\r\n\r\nexport class WebGL2KernelValueSingleArray3 extends WebGLKernelValueSingleArray3 {}\r\n","import { WebGLKernelValueSingleArray4 } from '../../web-gl/kernel-value/single-array4';\r\n\r\nexport class WebGL2KernelValueSingleArray4 extends WebGLKernelValueSingleArray4 {}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueUnsignedArray } from '../../web-gl/kernel-value/unsigned-array';\r\n\r\nexport class WebGL2KernelValueUnsignedArray extends WebGLKernelValueUnsignedArray {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueDynamicUnsignedArray } from '../../web-gl/kernel-value/dynamic-unsigned-array';\r\n\r\nexport class WebGL2KernelValueDynamicUnsignedArray extends WebGLKernelValueDynamicUnsignedArray {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n}\r\n","import { WebGL2KernelValueBoolean } from './kernel-value/boolean';\r\nimport { WebGL2KernelValueFloat } from './kernel-value/float';\r\nimport { WebGL2KernelValueInteger } from './kernel-value/integer';\r\n\r\nimport { WebGL2KernelValueHTMLImage } from './kernel-value/html-image';\r\nimport { WebGL2KernelValueDynamicHTMLImage } from './kernel-value/dynamic-html-image';\r\n\r\nimport { WebGL2KernelValueHTMLImageArray } from './kernel-value/html-image-array';\r\nimport { WebGL2KernelValueDynamicHTMLImageArray } from './kernel-value/dynamic-html-image-array';\r\n\r\nimport { WebGL2KernelValueHTMLVideo } from './kernel-value/html-video';\r\nimport { WebGL2KernelValueDynamicHTMLVideo } from './kernel-value/dynamic-html-video';\r\n\r\nimport { WebGL2KernelValueSingleInput } from './kernel-value/single-input';\r\nimport { WebGL2KernelValueDynamicSingleInput } from './kernel-value/dynamic-single-input';\r\n\r\nimport { WebGL2KernelValueUnsignedInput } from './kernel-value/unsigned-input';\r\nimport { WebGL2KernelValueDynamicUnsignedInput } from './kernel-value/dynamic-unsigned-input';\r\n\r\nimport { WebGL2KernelValueMemoryOptimizedNumberTexture } from './kernel-value/memory-optimized-number-texture';\r\nimport { WebGL2KernelValueDynamicMemoryOptimizedNumberTexture } from './kernel-value/dynamic-memory-optimized-number-texture';\r\n\r\nimport { WebGL2KernelValueNumberTexture } from './kernel-value/number-texture';\r\nimport { WebGL2KernelValueDynamicNumberTexture } from './kernel-value/dynamic-number-texture';\r\n\r\nimport { WebGL2KernelValueSingleArray } from './kernel-value/single-array';\r\nimport { WebGL2KernelValueDynamicSingleArray } from './kernel-value/dynamic-single-array';\r\n\r\nimport { WebGL2KernelValueSingleArray1DI } from './kernel-value/single-array1d-i';\r\nimport { WebGL2KernelValueDynamicSingleArray1DI } from './kernel-value/dynamic-single-array1d-i';\r\n\r\nimport { WebGL2KernelValueSingleArray2DI } from './kernel-value/single-array2d-i';\r\nimport { WebGL2KernelValueDynamicSingleArray2DI } from './kernel-value/dynamic-single-array2d-i';\r\n\r\nimport { WebGL2KernelValueSingleArray3DI } from './kernel-value/single-array3d-i';\r\nimport { WebGL2KernelValueDynamicSingleArray3DI } from './kernel-value/dynamic-single-array3d-i';\r\n\r\nimport { WebGL2KernelValueSingleArray2 } from './kernel-value/single-array2';\r\nimport { WebGL2KernelValueSingleArray3 } from './kernel-value/single-array3';\r\nimport { WebGL2KernelValueSingleArray4 } from './kernel-value/single-array4';\r\n\r\nimport { WebGL2KernelValueUnsignedArray } from './kernel-value/unsigned-array';\r\nimport { WebGL2KernelValueDynamicUnsignedArray } from './kernel-value/dynamic-unsigned-array';\r\n\r\nexport const kernelValueMaps = {\r\n unsigned: {\r\n dynamic: {\r\n 'Boolean': WebGL2KernelValueBoolean,\r\n 'Integer': WebGL2KernelValueInteger,\r\n 'Float': WebGL2KernelValueFloat,\r\n 'Array': WebGL2KernelValueDynamicUnsignedArray,\r\n 'Array(2)': false,\r\n 'Array(3)': false,\r\n 'Array(4)': false,\r\n 'Array1D(2)': false,\r\n 'Array1D(3)': false,\r\n 'Array1D(4)': false,\r\n 'Array2D(2)': false,\r\n 'Array2D(3)': false,\r\n 'Array2D(4)': false,\r\n 'Array3D(2)': false,\r\n 'Array3D(3)': false,\r\n 'Array3D(4)': false,\r\n 'Input': WebGL2KernelValueDynamicUnsignedInput,\r\n 'NumberTexture': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGL2KernelValueDynamicHTMLImage,\r\n 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray,\r\n 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo,\r\n },\r\n static: {\r\n 'Boolean': WebGL2KernelValueBoolean,\r\n 'Float': WebGL2KernelValueFloat,\r\n 'Integer': WebGL2KernelValueInteger,\r\n 'Array': WebGL2KernelValueUnsignedArray,\r\n 'Array(2)': false,\r\n 'Array(3)': false,\r\n 'Array(4)': false,\r\n 'Array1D(2)': false,\r\n 'Array1D(3)': false,\r\n 'Array1D(4)': false,\r\n 'Array2D(2)': false,\r\n 'Array2D(3)': false,\r\n 'Array2D(4)': false,\r\n 'Array3D(2)': false,\r\n 'Array3D(3)': false,\r\n 'Array3D(4)': false,\r\n 'Input': WebGL2KernelValueUnsignedInput,\r\n 'NumberTexture': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(1)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(2)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(3)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(4)': WebGL2KernelValueNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGL2KernelValueHTMLImage,\r\n 'HTMLImageArray': WebGL2KernelValueHTMLImageArray,\r\n 'HTMLVideo': WebGL2KernelValueHTMLVideo,\r\n }\r\n },\r\n single: {\r\n dynamic: {\r\n 'Boolean': WebGL2KernelValueBoolean,\r\n 'Integer': WebGL2KernelValueInteger,\r\n 'Float': WebGL2KernelValueFloat,\r\n 'Array': WebGL2KernelValueDynamicSingleArray,\r\n 'Array(2)': WebGL2KernelValueSingleArray2,\r\n 'Array(3)': WebGL2KernelValueSingleArray3,\r\n 'Array(4)': WebGL2KernelValueSingleArray4,\r\n 'Array1D(2)': WebGL2KernelValueDynamicSingleArray1DI,\r\n 'Array1D(3)': WebGL2KernelValueDynamicSingleArray1DI,\r\n 'Array1D(4)': WebGL2KernelValueDynamicSingleArray1DI,\r\n 'Array2D(2)': WebGL2KernelValueDynamicSingleArray2DI,\r\n 'Array2D(3)': WebGL2KernelValueDynamicSingleArray2DI,\r\n 'Array2D(4)': WebGL2KernelValueDynamicSingleArray2DI,\r\n 'Array3D(2)': WebGL2KernelValueDynamicSingleArray3DI,\r\n 'Array3D(3)': WebGL2KernelValueDynamicSingleArray3DI,\r\n 'Array3D(4)': WebGL2KernelValueDynamicSingleArray3DI,\r\n 'Input': WebGL2KernelValueDynamicSingleInput,\r\n 'NumberTexture': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGL2KernelValueDynamicHTMLImage,\r\n 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray,\r\n 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo,\r\n },\r\n static: {\r\n 'Boolean': WebGL2KernelValueBoolean,\r\n 'Float': WebGL2KernelValueFloat,\r\n 'Integer': WebGL2KernelValueInteger,\r\n 'Array': WebGL2KernelValueSingleArray,\r\n 'Array(2)': WebGL2KernelValueSingleArray2,\r\n 'Array(3)': WebGL2KernelValueSingleArray3,\r\n 'Array(4)': WebGL2KernelValueSingleArray4,\r\n 'Array1D(2)': WebGL2KernelValueSingleArray1DI,\r\n 'Array1D(3)': WebGL2KernelValueSingleArray1DI,\r\n 'Array1D(4)': WebGL2KernelValueSingleArray1DI,\r\n 'Array2D(2)': WebGL2KernelValueSingleArray2DI,\r\n 'Array2D(3)': WebGL2KernelValueSingleArray2DI,\r\n 'Array2D(4)': WebGL2KernelValueSingleArray2DI,\r\n 'Array3D(2)': WebGL2KernelValueSingleArray3DI,\r\n 'Array3D(3)': WebGL2KernelValueSingleArray3DI,\r\n 'Array3D(4)': WebGL2KernelValueSingleArray3DI,\r\n 'Input': WebGL2KernelValueSingleInput,\r\n 'NumberTexture': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(1)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(2)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(3)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(4)': WebGL2KernelValueNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGL2KernelValueMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGL2KernelValueHTMLImage,\r\n 'HTMLImageArray': WebGL2KernelValueHTMLImageArray,\r\n 'HTMLVideo': WebGL2KernelValueHTMLVideo,\r\n }\r\n },\r\n};\r\n\r\nexport function lookupKernelValueType(type, dynamic, precision, value) {\r\n if (!type) {\r\n throw new Error('type missing');\r\n }\r\n if (!dynamic) {\r\n throw new Error('dynamic missing');\r\n }\r\n if (!precision) {\r\n throw new Error('precision missing');\r\n }\r\n if (value.type) {\r\n type = value.type;\r\n }\r\n const types = kernelValueMaps[precision][dynamic];\r\n if (types[type] === false) {\r\n return null;\r\n } else if (types[type] === undefined) {\r\n throw new Error(`Could not find a KernelValue for ${ type }`);\r\n }\r\n return types[type];\r\n}\r\n","import { WebGLKernel } from '../web-gl/kernel';\r\nimport { WebGL2FunctionNode } from './function-node';\r\nimport { FunctionBuilder } from '../function-builder';\r\nimport { utils } from '../../utils';\r\nimport { fragmentShader } from './fragment-shader';\r\nimport { vertexShader } from './vertex-shader';\r\nimport { lookupKernelValueType } from './kernel-value-maps';\r\n\r\nlet isSupported = null;\r\nlet testCanvas = null;\r\nlet testContext = null;\r\nlet testExtensions = null;\r\n\r\n/**\r\n *\r\n * @type {IKernelFeatures}\r\n */\r\nlet features = null;\r\n\r\n/**\r\n * @extends WebGLKernel\r\n */\r\nexport class WebGL2Kernel extends WebGLKernel {\r\n static get isSupported() {\r\n if (isSupported !== null) {\r\n return isSupported;\r\n }\r\n this.setupFeatureChecks();\r\n isSupported = this.isContextMatch(testContext);\r\n return isSupported;\r\n }\r\n\r\n static setupFeatureChecks() {\r\n if (typeof document !== 'undefined') {\r\n testCanvas = document.createElement('canvas');\r\n } else if (typeof OffscreenCanvas !== 'undefined') {\r\n testCanvas = new OffscreenCanvas(0, 0);\r\n }\r\n if (!testCanvas) return;\r\n testContext = testCanvas.getContext('webgl2');\r\n if (!testContext || !testContext.getExtension) return;\r\n testExtensions = {\r\n EXT_color_buffer_float: testContext.getExtension('EXT_color_buffer_float'),\r\n OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'),\r\n };\r\n features = this.getFeatures();\r\n }\r\n\r\n static isContextMatch(context) {\r\n // from global\r\n if (typeof WebGL2RenderingContext !== 'undefined') {\r\n return context instanceof WebGL2RenderingContext;\r\n }\r\n return false;\r\n }\r\n\r\n static getFeatures() {\r\n return Object.freeze({\r\n isFloatRead: this.getIsFloatRead(),\r\n isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(),\r\n kernelMap: true,\r\n isTextureFloat: true,\r\n channelCount: this.getChannelCount(),\r\n maxTextureSize: this.getMaxTextureSize(),\r\n });\r\n }\r\n\r\n static getIsTextureFloat() {\r\n return true;\r\n }\r\n\r\n static getIsIntegerDivisionAccurate() {\r\n return super.getIsIntegerDivisionAccurate();\r\n }\r\n\r\n static getChannelCount() {\r\n return testContext.getParameter(testContext.MAX_DRAW_BUFFERS);\r\n }\r\n\r\n static getMaxTextureSize() {\r\n return testContext.getParameter(testContext.MAX_TEXTURE_SIZE);\r\n }\r\n\r\n static lookupKernelValueType(type, dynamic, precision, value) {\r\n return lookupKernelValueType(type, dynamic, precision, value);\r\n }\r\n\r\n static get testCanvas() {\r\n return testCanvas;\r\n }\r\n\r\n static get testContext() {\r\n return testContext;\r\n }\r\n\r\n /**\r\n *\r\n * @returns {{isFloatRead: Boolean, isIntegerDivisionAccurate: Boolean, kernelMap: Boolean, isTextureFloat: Boolean}}\r\n */\r\n static get features() {\r\n return features;\r\n }\r\n\r\n static get fragmentShader() {\r\n return fragmentShader;\r\n }\r\n static get vertexShader() {\r\n return vertexShader;\r\n }\r\n\r\n initContext() {\r\n const settings = {\r\n alpha: false,\r\n depth: false,\r\n antialias: false\r\n };\r\n const context = this.canvas.getContext('webgl2', settings);\r\n return context;\r\n }\r\n\r\n initExtensions() {\r\n this.extensions = {\r\n EXT_color_buffer_float: this.context.getExtension('EXT_color_buffer_float'),\r\n OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'),\r\n };\r\n }\r\n\r\n /**\r\n * @desc Validate settings related to Kernel, such as dimensions size, and auto output support.\r\n * @param {IArguments} args\r\n */\r\n validateSettings(args) {\r\n if (!this.validate) {\r\n this.texSize = utils.getKernelTextureSize({\r\n optimizeFloatMemory: this.optimizeFloatMemory,\r\n precision: this.precision,\r\n }, this.output);\r\n return;\r\n }\r\n\r\n const features = this.constructor.features;\r\n if (this.precision === 'single' && !features.isFloatRead) {\r\n throw new Error('Float texture outputs are not supported');\r\n } else if (!this.graphical && this.precision === null) {\r\n this.precision = features.isFloatRead ? 'single' : 'unsigned';\r\n }\r\n\r\n if (this.fixIntegerDivisionAccuracy === null) {\r\n this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate;\r\n } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) {\r\n this.fixIntegerDivisionAccuracy = false;\r\n }\r\n\r\n this.checkOutput();\r\n\r\n if (!this.output || this.output.length === 0) {\r\n if (args.length !== 1) {\r\n throw new Error('Auto output only supported for kernels with only one input');\r\n }\r\n\r\n const argType = utils.getVariableType(args[0], this.strictIntegers);\r\n switch (argType) {\r\n case 'Array':\r\n this.output = utils.getDimensions(argType);\r\n break;\r\n case 'NumberTexture':\r\n case 'MemoryOptimizedNumberTexture':\r\n case 'ArrayTexture(1)':\r\n case 'ArrayTexture(2)':\r\n case 'ArrayTexture(3)':\r\n case 'ArrayTexture(4)':\r\n this.output = args[0].output;\r\n break;\r\n default:\r\n throw new Error('Auto output not supported for input type: ' + argType);\r\n }\r\n }\r\n\r\n if (this.graphical) {\r\n if (this.output.length !== 2) {\r\n throw new Error('Output must have 2 dimensions on graphical mode');\r\n }\r\n\r\n if (this.precision === 'single') {\r\n console.warn('Cannot use graphical mode and single precision at the same time');\r\n this.precision = 'unsigned';\r\n }\r\n\r\n this.texSize = utils.clone(this.output);\r\n return;\r\n } else if (!this.graphical && this.precision === null && features.isTextureFloat) {\r\n this.precision = 'single';\r\n }\r\n\r\n this.texSize = utils.getKernelTextureSize({\r\n optimizeFloatMemory: this.optimizeFloatMemory,\r\n precision: this.precision,\r\n }, this.output);\r\n\r\n this.checkTextureSize();\r\n }\r\n\r\n translateSource() {\r\n const functionBuilder = FunctionBuilder.fromKernel(this, WebGL2FunctionNode, {\r\n fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy\r\n });\r\n this.translatedSource = functionBuilder.getPrototypeString('kernel');\r\n if (!this.graphical && !this.returnType) {\r\n this.returnType = functionBuilder.getKernelResultType();\r\n }\r\n\r\n if (this.subKernels && this.subKernels.length > 0) {\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (!subKernel.returnType) {\r\n subKernel.returnType = functionBuilder.getSubKernelResultType(i);\r\n }\r\n }\r\n }\r\n }\r\n\r\n run() {\r\n const { kernelArguments, texSize, forceUploadKernelConstants } = this;\r\n const gl = this.context;\r\n\r\n gl.useProgram(this.program);\r\n gl.scissor(0, 0, texSize[0], texSize[1]);\r\n\r\n if (this.dynamicOutput) {\r\n this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim));\r\n this.setUniform2iv('uTexSize', texSize);\r\n }\r\n\r\n this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]);\r\n\r\n this.switchingKernels = false;\r\n for (let i = 0; i < forceUploadKernelConstants.length; i++) {\r\n const constant = forceUploadKernelConstants[i];\r\n constant.updateValue(this.constants[constant.name]);\r\n if (this.switchingKernels) return;\r\n }\r\n for (let i = 0; i < kernelArguments.length; i++) {\r\n kernelArguments[i].updateValue(arguments[i]);\r\n if (this.switchingKernels) return;\r\n }\r\n\r\n if (this.plugins) {\r\n for (let i = 0; i < this.plugins.length; i++) {\r\n const plugin = this.plugins[i];\r\n if (plugin.onBeforeRun) {\r\n plugin.onBeforeRun(this);\r\n }\r\n }\r\n }\r\n\r\n if (this.graphical) {\r\n if (this.pipeline) {\r\n gl.bindRenderbuffer(gl.RENDERBUFFER, null);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n if (!this.outputTexture || this.immutable) {\r\n this._setupOutputTexture();\r\n }\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n return new this.TextureConstructor({\r\n texture: this.outputTexture,\r\n size: texSize,\r\n dimensions: this.threadDim,\r\n output: this.output,\r\n context: this.context\r\n });\r\n }\r\n gl.bindRenderbuffer(gl.RENDERBUFFER, null);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n return;\r\n }\r\n\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n if (this.immutable) {\r\n this._setupOutputTexture();\r\n }\r\n\r\n if (this.subKernels !== null) {\r\n if (this.immutable) {\r\n this._setupSubOutputTextures();\r\n }\r\n gl.drawBuffers(this.drawBuffersMap);\r\n }\r\n\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n }\r\n\r\n drawBuffers() {\r\n this.context.drawBuffers(this.drawBuffersMap);\r\n }\r\n\r\n getOutputTexture() {\r\n return this.outputTexture;\r\n }\r\n\r\n _setupOutputTexture() {\r\n const { texSize } = this;\r\n const gl = this.context;\r\n const texture = this.outputTexture = gl.createTexture();\r\n gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n if (this.precision === 'single') {\r\n if (this.pipeline) {\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Float':\r\n case 'Integer':\r\n if (this.optimizeFloatMemory) {\r\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]);\r\n } else {\r\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.R32F, texSize[0], texSize[1]);\r\n }\r\n break;\r\n case 'Array(2)':\r\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RG32F, texSize[0], texSize[1]);\r\n break;\r\n case 'Array(3)': // there is _no_ 3 channel format which is guaranteed to be color-renderable\r\n case 'Array(4)':\r\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]);\r\n break;\r\n default:\r\n throw new Error('Unhandled return type');\r\n }\r\n } else {\r\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]);\r\n }\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n }\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);\r\n }\r\n\r\n _setupSubOutputTextures() {\r\n const { texSize } = this;\r\n const gl = this.context;\r\n this.drawBuffersMap = [gl.COLOR_ATTACHMENT0];\r\n this.subKernelOutputTextures = [];\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const texture = this.context.createTexture();\r\n this.subKernelOutputTextures.push(texture);\r\n this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1);\r\n gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n // TODO: upgrade this\r\n if (this.precision === 'single') {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n }\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0);\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @desc Get the header string for the program.\r\n * This returns an empty string if no sub-kernels are defined.\r\n *\r\n * @returns {String} result\r\n */\r\n _getHeaderString() {\r\n return '';\r\n }\r\n\r\n /**\r\n * @desc Get texture coordinate string for the program\r\n * @returns {String} result\r\n */\r\n _getTextureCoordinate() {\r\n const subKernels = this.subKernels;\r\n if (subKernels === null || subKernels.length < 1) {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'in lowp vec2 vTexCoord;\\n';\r\n case 'performance':\r\n return 'in highp vec2 vTexCoord;\\n';\r\n case 'balanced':\r\n default:\r\n return 'in mediump vec2 vTexCoord;\\n';\r\n }\r\n } else {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'out lowp vec2 vTexCoord;\\n';\r\n case 'performance':\r\n return 'out highp vec2 vTexCoord;\\n';\r\n case 'balanced':\r\n default:\r\n return 'out mediump vec2 vTexCoord;\\n';\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @desc Generate transpiled glsl Strings for user-defined parameters sent to a kernel\r\n * @param {Array} args - The actual parameters sent to the Kernel\r\n * @returns {String} result\r\n */\r\n _getMainArgumentsString(args) {\r\n const result = [];\r\n const argumentNames = this.argumentNames;\r\n for (let i = 0; i < argumentNames.length; i++) {\r\n result.push(this.kernelArguments[i].getSource(args[i]));\r\n }\r\n return result.join('');\r\n }\r\n\r\n /**\r\n * @desc Get Kernel program string (in *glsl*) for a kernel.\r\n * @returns {String} result\r\n */\r\n getKernelString() {\r\n let kernelResultDeclaration;\r\n switch (this.returnType) {\r\n case 'Array(2)':\r\n kernelResultDeclaration = 'vec2 kernelResult';\r\n break;\r\n case 'Array(3)':\r\n kernelResultDeclaration = 'vec3 kernelResult';\r\n break;\r\n case 'Array(4)':\r\n kernelResultDeclaration = 'vec4 kernelResult';\r\n break;\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n kernelResultDeclaration = 'float kernelResult';\r\n break;\r\n default:\r\n if (this.graphical) {\r\n kernelResultDeclaration = 'float kernelResult';\r\n } else {\r\n throw new Error(`unrecognized output type \"${ this.returnType }\"`);\r\n }\r\n }\r\n\r\n const result = [];\r\n const subKernels = this.subKernels;\r\n if (subKernels !== null) {\r\n result.push(\r\n kernelResultDeclaration,\r\n 'layout(location = 0) out vec4 data0'\r\n );\r\n for (let i = 0; i < subKernels.length; i++) {\r\n const subKernel = subKernels[i];\r\n result.push(\r\n subKernel.returnType === 'Integer' ?\r\n `int subKernelResult_${ subKernel.name } = 0` :\r\n `float subKernelResult_${ subKernel.name } = 0.0`,\r\n `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }`\r\n );\r\n }\r\n } else {\r\n result.push(\r\n 'out vec4 data0',\r\n kernelResultDeclaration\r\n );\r\n }\r\n\r\n return utils.linesToString(result) + this.translatedSource;\r\n }\r\n\r\n getMainResultGraphical() {\r\n return utils.linesToString([\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' data0 = actualColor',\r\n ]);\r\n }\r\n\r\n getMainResultPackedPixels() {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n return this.getMainResultKernelPackedPixels() +\r\n this.getMainResultSubKernelPackedPixels();\r\n default:\r\n throw new Error(`packed output only usable with Numbers, \"${this.returnType}\" specified`);\r\n }\r\n }\r\n\r\n /**\r\n * @return {String}\r\n */\r\n getMainResultKernelPackedPixels() {\r\n return utils.linesToString([\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ` data0 = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)`\r\n ]);\r\n }\r\n\r\n /**\r\n * @return {String}\r\n */\r\n getMainResultSubKernelPackedPixels() {\r\n const result = [];\r\n if (!this.subKernels) return '';\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))`\r\n );\r\n } else {\r\n result.push(\r\n ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})`\r\n );\r\n }\r\n }\r\n return utils.linesToString(result);\r\n }\r\n\r\n getMainResultMemoryOptimizedFloats() {\r\n const result = [\r\n ' index *= 4',\r\n ];\r\n\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n const channels = ['r', 'g', 'b', 'a'];\r\n for (let i = 0; i < channels.length; i++) {\r\n const channel = channels[i];\r\n this.getMainResultKernelMemoryOptimizedFloats(result, channel);\r\n this.getMainResultSubKernelMemoryOptimizedFloats(result, channel);\r\n if (i + 1 < channels.length) {\r\n result.push(' index += 1');\r\n }\r\n }\r\n break;\r\n default:\r\n throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`);\r\n }\r\n\r\n return utils.linesToString(result);\r\n }\r\n\r\n getMainResultKernelMemoryOptimizedFloats(result, channel) {\r\n result.push(\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ` data0.${channel} = kernelResult`,\r\n );\r\n }\r\n\r\n getMainResultSubKernelMemoryOptimizedFloats(result, channel) {\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` data${i + 1}.${channel} = float(subKernelResult_${subKernel.name})`,\r\n );\r\n } else {\r\n result.push(\r\n ` data${i + 1}.${channel} = subKernelResult_${subKernel.name}`,\r\n );\r\n }\r\n }\r\n }\r\n\r\n getMainResultKernelNumberTexture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' data0[0] = kernelResult',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelNumberTexture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` data${i + 1}[0] = float(subKernelResult_${subKernel.name})`,\r\n );\r\n } else {\r\n result.push(\r\n ` data${i + 1}[0] = subKernelResult_${subKernel.name}`,\r\n );\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray2Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' data0[0] = kernelResult[0]',\r\n ' data0[1] = kernelResult[1]',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray2Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n const subKernel = this.subKernels[i];\r\n result.push(\r\n ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`,\r\n ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`,\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray3Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' data0[0] = kernelResult[0]',\r\n ' data0[1] = kernelResult[1]',\r\n ' data0[2] = kernelResult[2]',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray3Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n const subKernel = this.subKernels[i];\r\n result.push(\r\n ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`,\r\n ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`,\r\n ` data${i + 1}[2] = subKernelResult_${subKernel.name}[2]`,\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray4Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' data0 = kernelResult',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray4Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` data${i + 1} = subKernelResult_${this.subKernels[i].name}`,\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n destroyExtensions() {\r\n this.extensions.EXT_color_buffer_float = null;\r\n this.extensions.OES_texture_float_linear = null;\r\n }\r\n\r\n toJSON() {\r\n const json = super.toJSON();\r\n json.functionNodes = FunctionBuilder.fromKernel(this, WebGL2FunctionNode).toJSON();\r\n return json;\r\n }\r\n}\r\n","import { utils } from './utils';\r\n\r\n/**\r\n * Makes kernels easier for mortals (including me)\r\n * @param kernel\r\n * @returns {function()}\r\n */\r\nexport function kernelRunShortcut(kernel) {\r\n let run = function() {\r\n kernel.build.apply(kernel, arguments);\r\n if (kernel.renderKernels) {\r\n run = function() {\r\n kernel.run.apply(kernel, arguments);\r\n if (kernel.switchingKernels) {\r\n kernel.switchingKernels = false;\r\n return kernel.onRequestSwitchKernel(arguments, kernel);\r\n }\r\n return kernel.renderKernels();\r\n };\r\n } else if (kernel.renderOutput) {\r\n run = function() {\r\n kernel.run.apply(kernel, arguments);\r\n if (kernel.switchingKernels) {\r\n kernel.switchingKernels = false;\r\n return kernel.onRequestSwitchKernel(arguments, kernel);\r\n }\r\n return kernel.renderOutput();\r\n };\r\n } else {\r\n run = function() {\r\n return kernel.run.apply(kernel, arguments);\r\n };\r\n }\r\n return run.apply(kernel, arguments);\r\n };\r\n const shortcut = function() {\r\n return run.apply(kernel, arguments);\r\n };\r\n /**\r\n * Run kernel in async mode\r\n * @returns {Promise}\r\n */\r\n shortcut.exec = function() {\r\n return new Promise((accept, reject) => {\r\n try {\r\n accept(run.apply(this, arguments));\r\n } catch (e) {\r\n reject(e);\r\n }\r\n });\r\n };\r\n shortcut.replaceKernel = function(replacementKernel) {\r\n kernel = replacementKernel;\r\n bindKernelToShortcut(kernel, shortcut);\r\n shortcut.kernel = kernel;\r\n };\r\n\r\n bindKernelToShortcut(kernel, shortcut);\r\n shortcut.kernel = kernel;\r\n return shortcut;\r\n}\r\n\r\nfunction bindKernelToShortcut(kernel, shortcut) {\r\n const properties = utils.allPropertiesOf(kernel);\r\n for (let i = 0; i < properties.length; i++) {\r\n const property = properties[i];\r\n if (property[0] === '_' && property[1] === '_') continue;\r\n if (typeof kernel[property] === 'function') {\r\n if (property.substring(0, 3) === 'add' || property.substring(0, 3) === 'set') {\r\n shortcut[property] = function() {\r\n kernel[property].apply(kernel, arguments);\r\n return shortcut;\r\n };\r\n } else {\r\n if (property === 'toString') {\r\n shortcut.toString = function() {\r\n return kernel.toString.apply(kernel, arguments);\r\n };\r\n } else {\r\n shortcut[property] = kernel[property].bind(kernel);\r\n }\r\n }\r\n } else {\r\n shortcut.__defineGetter__(property, () => {\r\n return kernel[property];\r\n });\r\n shortcut.__defineSetter__(property, (value) => {\r\n kernel[property] = value;\r\n });\r\n }\r\n }\r\n}\r\n","import { gpuMock } from 'gpu-mock.js';\r\nimport { CPUKernel } from './backend/cpu/kernel';\r\nimport { WebGL2Kernel } from './backend/web-gl2/kernel';\r\nimport { WebGLKernel } from './backend/web-gl/kernel';\r\nimport { kernelRunShortcut } from './kernel-run-shortcut';\r\nimport {\r\n functionToIFunction,\r\n getFunctionNameFromString,\r\n isFunction,\r\n warnDeprecated\r\n} from './common';\r\nimport { getVariableType } from './utils';\r\n\r\n/**\r\n * @type {Kernel[]}\r\n */\r\nconst kernelOrder = [ WebGL2Kernel, WebGLKernel ];\r\n\r\n/**\r\n * @type {string[]}\r\n */\r\nconst kernelTypes = [ 'gpu', 'cpu' ];\r\n\r\nconst internalKernels = {\r\n 'webgl2': WebGL2Kernel,\r\n 'webgl': WebGLKernel,\r\n};\r\n\r\nlet validate = true;\r\n\r\n/**\r\n * The GPU.js library class which manages the GPU context for the creating kernels\r\n */\r\nexport class GPU {\r\n static disableValidation() {\r\n validate = false;\r\n }\r\n\r\n static enableValidation() {\r\n validate = true;\r\n }\r\n\r\n static get isGPUSupported() {\r\n return kernelOrder.some(Kernel => Kernel.isSupported);\r\n }\r\n\r\n /**\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isKernelMapSupported() {\r\n return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.kernelMap);\r\n }\r\n\r\n /**\r\n * @desc TRUE is platform supports OffscreenCanvas\r\n */\r\n static get isOffscreenCanvasSupported() {\r\n return (typeof Worker !== 'undefined' && typeof OffscreenCanvas !== 'undefined') || typeof importScripts !== 'undefined';\r\n }\r\n\r\n /**\r\n * @desc TRUE if platform supports WebGL\r\n */\r\n static get isWebGLSupported() {\r\n return WebGLKernel.isSupported;\r\n }\r\n\r\n /**\r\n * @desc TRUE if platform supports WebGL2\r\n */\r\n static get isWebGL2Supported() {\r\n return WebGL2Kernel.isSupported;\r\n }\r\n\r\n /**\r\n * @desc TRUE if platform supports HeadlessGL\r\n */\r\n static get isHeadlessGLSupported() {\r\n return false;\r\n }\r\n\r\n /**\r\n *\r\n * @desc TRUE if platform supports Canvas\r\n */\r\n static get isCanvasSupported() {\r\n return typeof HTMLCanvasElement !== 'undefined';\r\n }\r\n\r\n /**\r\n * @desc TRUE if platform supports HTMLImageArray}\r\n */\r\n static get isGPUHTMLImageArraySupported() {\r\n return WebGL2Kernel.isSupported;\r\n }\r\n\r\n /**\r\n * @desc TRUE if platform supports single precision}\r\n * @returns {boolean}\r\n */\r\n static get isSinglePrecisionSupported() {\r\n return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.isFloatRead && Kernel.features.isTextureFloat);\r\n }\r\n\r\n /**\r\n * Creates an instance of GPU.\r\n * @param {IGPUSettings} [settings] - Settings to set mode, and other properties\r\n */\r\n constructor(settings) {\r\n settings = settings || {};\r\n this.canvas = settings.canvas || null;\r\n this.context = settings.context || null;\r\n this.mode = settings.mode;\r\n this.Kernel = null;\r\n this.kernels = [];\r\n this.functions = [];\r\n this.nativeFunctions = [];\r\n this.injectedNative = null;\r\n if (this.mode === 'dev') return;\r\n this.chooseKernel();\r\n // add functions from settings\r\n if (settings.functions) {\r\n for (let i = 0; i < settings.functions.length; i++) {\r\n this.addFunction(settings.functions[i]);\r\n }\r\n }\r\n\r\n // add native functions from settings\r\n if (settings.nativeFunctions) {\r\n for (const p in settings.nativeFunctions) {\r\n this.addNativeFunction(p, settings.nativeFunctions[p]);\r\n }\r\n }\r\n }\r\n\r\n getValidate() {\r\n return validate;\r\n }\r\n\r\n /**\r\n * Choose kernel type and save on .Kernel property of GPU\r\n */\r\n chooseKernel() {\r\n if (this.Kernel) return;\r\n\r\n let Kernel = null;\r\n\r\n if (this.context) {\r\n for (let i = 0; i < kernelOrder.length; i++) {\r\n const ExternalKernel = kernelOrder[i];\r\n if (ExternalKernel.isContextMatch(this.context)) {\r\n if (!ExternalKernel.isSupported) {\r\n throw new Error(`Kernel type ${ExternalKernel.name} not supported`);\r\n }\r\n Kernel = ExternalKernel;\r\n break;\r\n }\r\n }\r\n if (Kernel === null) {\r\n throw new Error('unknown Context');\r\n }\r\n } else if (this.mode) {\r\n if (this.mode in internalKernels) {\r\n if (!validate || internalKernels[this.mode].isSupported) {\r\n Kernel = internalKernels[this.mode];\r\n }\r\n } else if (this.mode === 'gpu') {\r\n for (let i = 0; i < kernelOrder.length; i++) {\r\n if (kernelOrder[i].isSupported) {\r\n Kernel = kernelOrder[i];\r\n break;\r\n }\r\n }\r\n } else if (this.mode === 'cpu') {\r\n Kernel = CPUKernel;\r\n }\r\n if (!Kernel) {\r\n throw new Error(`A requested mode of \"${this.mode}\" and is not supported`);\r\n }\r\n } else {\r\n for (let i = 0; i < kernelOrder.length; i++) {\r\n if (kernelOrder[i].isSupported) {\r\n Kernel = kernelOrder[i];\r\n break;\r\n }\r\n }\r\n if (!Kernel) {\r\n Kernel = CPUKernel;\r\n }\r\n }\r\n\r\n if (!this.mode) {\r\n this.mode = Kernel.mode;\r\n }\r\n this.Kernel = Kernel;\r\n }\r\n\r\n /**\r\n * @desc This creates a callable function object to call the kernel function with the argument parameter set\r\n * @param {Function|String|object} source - The calling to perform the conversion\r\n * @param {Object} [settings] - The parameter configuration object\r\n * @return {Kernel} callable function to run\r\n */\r\n createKernel(source, settings) {\r\n if (typeof source === 'undefined') {\r\n throw new Error('Missing source parameter');\r\n }\r\n if (typeof source !== 'object' && !isFunction(source) && typeof source !== 'string') {\r\n throw new Error('source parameter not a function');\r\n }\r\n\r\n if (this.mode === 'dev') {\r\n const devKernel = gpuMock(source, upgradeDeprecatedCreateKernelSettings(settings));\r\n this.kernels.push(devKernel);\r\n return devKernel;\r\n }\r\n\r\n source = typeof source === 'function' ? source.toString() : source;\r\n const switchableKernels = {};\r\n const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings) || {};\r\n // handle conversion of argumentTypes\r\n if (settings && typeof settings.argumentTypes === 'object') {\r\n settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]);\r\n }\r\n\r\n function onRequestFallback(args) {\r\n const fallbackKernel = new CPUKernel(source, {\r\n argumentTypes: kernelRun.argumentTypes,\r\n constantTypes: kernelRun.constantTypes,\r\n graphical: kernelRun.graphical,\r\n loopMaxIterations: kernelRun.loopMaxIterations,\r\n constants: kernelRun.constants,\r\n dynamicOutput: kernelRun.dynamicOutput,\r\n dynamicArgument: kernelRun.dynamicArguments,\r\n output: kernelRun.output,\r\n precision: kernelRun.precision,\r\n pipeline: kernelRun.pipeline,\r\n immutable: kernelRun.immutable,\r\n optimizeFloatMemory: kernelRun.optimizeFloatMemory,\r\n fixIntegerDivisionAccuracy: kernelRun.fixIntegerDivisionAccuracy,\r\n functions: kernelRun.functions,\r\n nativeFunctions: kernelRun.nativeFunctions,\r\n injectedNative: kernelRun.injectedNative,\r\n subKernels: kernelRun.subKernels,\r\n strictIntegers: kernelRun.strictIntegers,\r\n debug: kernelRun.debug,\r\n warnVarUsage: kernelRun.warnVarUsage,\r\n });\r\n fallbackKernel.build.apply(fallbackKernel, args);\r\n const result = fallbackKernel.run.apply(fallbackKernel, args);\r\n kernelRun.replaceKernel(fallbackKernel);\r\n return result;\r\n }\r\n\r\n function onRequestSwitchKernel(args, kernel) {\r\n const argumentTypes = new Array(args.length);\r\n for (let i = 0; i < args.length; i++) {\r\n const arg = args[i];\r\n const type = kernel.argumentTypes[i];\r\n if (arg.type) {\r\n argumentTypes[i] = arg.type;\r\n } else {\r\n switch (type) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n case 'ArrayTexture(1)':\r\n argumentTypes[i] = getVariableType(arg);\r\n break;\r\n default:\r\n argumentTypes[i] = type;\r\n }\r\n }\r\n }\r\n const signature = argumentTypes.join(',');\r\n const existingKernel = switchableKernels[signature];\r\n if (existingKernel) {\r\n existingKernel.run.apply(existingKernel, args);\r\n if (existingKernel.renderKernels) {\r\n return existingKernel.renderKernels();\r\n } else {\r\n return existingKernel.renderOutput();\r\n }\r\n }\r\n\r\n const newKernel = switchableKernels[signature] = new kernel.constructor(source, {\r\n argumentTypes,\r\n constantTypes: kernel.constantTypes,\r\n graphical: kernel.graphical,\r\n loopMaxIterations: kernel.loopMaxIterations,\r\n constants: kernel.constants,\r\n dynamicOutput: kernel.dynamicOutput,\r\n dynamicArgument: kernel.dynamicArguments,\r\n context: kernel.context,\r\n canvas: kernel.canvas,\r\n output: kernel.output,\r\n precision: kernel.precision,\r\n pipeline: kernel.pipeline,\r\n immutable: kernel.immutable,\r\n optimizeFloatMemory: kernel.optimizeFloatMemory,\r\n fixIntegerDivisionAccuracy: kernel.fixIntegerDivisionAccuracy,\r\n functions: kernel.functions,\r\n nativeFunctions: kernel.nativeFunctions,\r\n injectedNative: kernel.injectedNative,\r\n subKernels: kernel.subKernels,\r\n strictIntegers: kernel.strictIntegers,\r\n debug: kernel.debug,\r\n gpu: kernel.gpu,\r\n validate,\r\n warnVarUsage: kernel.warnVarUsage,\r\n returnType: kernel.returnType,\r\n onRequestFallback,\r\n onRequestSwitchKernel,\r\n });\r\n newKernel.build.apply(newKernel, args);\r\n newKernel.run.apply(newKernel, args);\r\n kernelRun.replaceKernel(newKernel);\r\n if (newKernel.renderKernels) {\r\n return newKernel.renderKernels();\r\n } else {\r\n return newKernel.renderOutput();\r\n }\r\n }\r\n const mergedSettings = Object.assign({\r\n context: this.context,\r\n canvas: this.canvas,\r\n functions: this.functions,\r\n nativeFunctions: this.nativeFunctions,\r\n injectedNative: this.injectedNative,\r\n gpu: this,\r\n validate,\r\n onRequestFallback,\r\n onRequestSwitchKernel\r\n }, settingsCopy);\r\n\r\n const kernelRun = kernelRunShortcut(new this.Kernel(source, mergedSettings));\r\n\r\n //if canvas didn't come from this, propagate from kernel\r\n if (!this.canvas) {\r\n this.canvas = kernelRun.canvas;\r\n }\r\n\r\n //if context didn't come from this, propagate from kernel\r\n if (!this.context) {\r\n this.context = kernelRun.context;\r\n }\r\n\r\n this.kernels.push(kernelRun);\r\n\r\n return kernelRun;\r\n }\r\n\r\n /**\r\n *\r\n * Create a super kernel which executes sub kernels\r\n * and saves their output to be used with the next sub kernel.\r\n * This can be useful if we want to save the output on one kernel,\r\n * and then use it as an input to another kernel. *Machine Learning*\r\n *\r\n * @param {Object|Array} subKernels - Sub kernels for this kernel\r\n * @param {Function} rootKernel - Root kernel\r\n *\r\n * @returns {Function} callable kernel function\r\n *\r\n * @example\r\n * const megaKernel = gpu.createKernelMap({\r\n * addResult: function add(a, b) {\r\n * return a[this.thread.x] + b[this.thread.x];\r\n * },\r\n * multiplyResult: function multiply(a, b) {\r\n * return a[this.thread.x] * b[this.thread.x];\r\n * },\r\n * }, function(a, b, c) {\r\n * return multiply(add(a, b), c);\r\n * });\r\n *\r\n * megaKernel(a, b, c);\r\n *\r\n * Note: You can also define subKernels as an array of functions.\r\n * > [add, multiply]\r\n *\r\n */\r\n createKernelMap() {\r\n let fn;\r\n let settings;\r\n if (typeof arguments[arguments.length - 2] === 'function') {\r\n fn = arguments[arguments.length - 2];\r\n settings = arguments[arguments.length - 1];\r\n } else {\r\n fn = arguments[arguments.length - 1];\r\n }\r\n\r\n if (this.mode !== 'dev') {\r\n if (!this.Kernel.isSupported || !this.Kernel.features.kernelMap) {\r\n if (this.mode && kernelTypes.indexOf(this.mode) < 0) {\r\n throw new Error(`kernelMap not supported on ${this.Kernel.name}`);\r\n }\r\n }\r\n }\r\n\r\n const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings);\r\n // handle conversion of argumentTypes\r\n if (settings && typeof settings.argumentTypes === 'object') {\r\n settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]);\r\n }\r\n\r\n if (Array.isArray(arguments[0])) {\r\n settingsCopy.subKernels = [];\r\n const functions = arguments[0];\r\n for (let i = 0; i < functions.length; i++) {\r\n const source = functions[i].toString();\r\n const name = getFunctionNameFromString(source);\r\n settingsCopy.subKernels.push({\r\n name,\r\n source,\r\n property: i,\r\n });\r\n }\r\n } else {\r\n settingsCopy.subKernels = [];\r\n const functions = arguments[0];\r\n for (let p in functions) {\r\n if (!functions.hasOwnProperty(p)) continue;\r\n const source = functions[p].toString();\r\n const name = getFunctionNameFromString(source);\r\n settingsCopy.subKernels.push({\r\n name: name || p,\r\n source,\r\n property: p,\r\n });\r\n }\r\n }\r\n const kernel = this.createKernel(fn, settingsCopy);\r\n\r\n return kernel;\r\n }\r\n\r\n /**\r\n *\r\n * Combine different kernels into one super Kernel,\r\n * useful to perform multiple operations inside one\r\n * kernel without the penalty of data transfer between\r\n * cpu and gpu.\r\n *\r\n * The number of kernel functions sent to this method can be variable.\r\n * You can send in one, two, etc.\r\n *\r\n * @param {Function} subKernels - Kernel function(s) to combine.\r\n * @param {Function} rootKernel - Root kernel to combine kernels into\r\n *\r\n * @example\r\n * combineKernels(add, multiply, function(a,b,c){\r\n * return add(multiply(a,b), c)\r\n * })\r\n *\r\n * @returns {Function} Callable kernel function\r\n *\r\n */\r\n combineKernels() {\r\n const firstKernel = arguments[0];\r\n const combinedKernel = arguments[arguments.length - 1];\r\n if (firstKernel.kernel.constructor.mode === 'cpu') return combinedKernel;\r\n const canvas = arguments[0].canvas;\r\n const context = arguments[0].context;\r\n const max = arguments.length - 1;\r\n for (let i = 0; i < max; i++) {\r\n arguments[i]\r\n .setCanvas(canvas)\r\n .setContext(context)\r\n .setPipeline(true);\r\n }\r\n\r\n return function() {\r\n const texture = combinedKernel.apply(this, arguments);\r\n if (texture.toArray) {\r\n return texture.toArray();\r\n }\r\n return texture;\r\n };\r\n }\r\n\r\n /**\r\n * @desc Adds additional functions, that the kernel may call.\r\n * @param {Function|String} source - Javascript function to convert\r\n * @param {IFunctionSettings} [settings]\r\n * @returns {GPU} returns itself\r\n */\r\n addFunction(source, settings) {\r\n this.functions.push(functionToIFunction(source, settings));\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Adds additional native functions, that the kernel may call.\r\n * @param {String} name - native function name, used for reverse lookup\r\n * @param {String} source - the native function implementation, as it would be defined in it's entirety\r\n * @param {object} [settings]\r\n * @returns {GPU} returns itself\r\n */\r\n addNativeFunction(name, source, settings) {\r\n if (this.kernels.length > 0) {\r\n throw new Error('Cannot call \"addNativeFunction\" after \"createKernels\" has been called.');\r\n }\r\n settings = settings || {};\r\n const { argumentTypes, argumentNames } = this.Kernel.nativeFunctionArguments(source) || {};\r\n this.nativeFunctions.push({\r\n name,\r\n source,\r\n settings,\r\n argumentTypes,\r\n argumentNames,\r\n returnType: settings.returnType || this.Kernel.nativeFunctionReturnType(source),\r\n });\r\n return this;\r\n }\r\n\r\n /**\r\n * Inject a string just before translated kernel functions\r\n * @param {String} source\r\n * @return {GPU}\r\n */\r\n injectNative(source) {\r\n this.injectedNative = source;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Destroys all memory associated with gpu.js & the webGl if we created it\r\n */\r\n destroy() {\r\n if (!this.kernels) return;\r\n // perform on next run loop - for some reason we dont get lose context events\r\n // if webGl is created and destroyed in the same run loop.\r\n setTimeout(() => {\r\n for (let i = 0; i < this.kernels.length; i++) {\r\n this.kernels[i].destroy(true); // remove canvas if exists\r\n }\r\n // all kernels are associated with one context, go ahead and take care of it here\r\n let firstKernel = this.kernels[0];\r\n if (firstKernel) {\r\n // if it is shortcut\r\n if (firstKernel.kernel) {\r\n firstKernel = firstKernel.kernel;\r\n }\r\n if (firstKernel.constructor.destroyContext) {\r\n firstKernel.constructor.destroyContext(this.context);\r\n }\r\n }\r\n }, 0);\r\n }\r\n}\r\n\r\nfunction upgradeDeprecatedCreateKernelSettings(settings) {\r\n if (!settings) {\r\n return {};\r\n }\r\n const upgradedSettings = Object.assign({}, settings);\r\n\r\n if (settings.hasOwnProperty('floatOutput')) {\r\n warnDeprecated('setting', 'floatOutput', 'precision');\r\n upgradedSettings.precision = settings.floatOutput ? 'single' : 'unsigned';\r\n }\r\n if (settings.hasOwnProperty('outputToTexture')) {\r\n warnDeprecated('setting', 'outputToTexture', 'pipeline');\r\n upgradedSettings.pipeline = Boolean(settings.outputToTexture);\r\n }\r\n if (settings.hasOwnProperty('outputImmutable')) {\r\n warnDeprecated('setting', 'outputImmutable', 'immutable');\r\n upgradedSettings.immutable = Boolean(settings.outputImmutable);\r\n }\r\n if (settings.hasOwnProperty('floatTextures')) {\r\n warnDeprecated('setting', 'floatTextures', 'optimizeFloatMemory');\r\n upgradedSettings.optimizeFloatMemory = Boolean(settings.floatTextures);\r\n }\r\n return upgradedSettings;\r\n}\r\n","import { utils } from './utils';\r\n\r\n/**\r\n * @param name\r\n * @param source\r\n * @returns {Function}\r\n */\r\nexport function alias(name, source) {\r\n const fnString = source.toString();\r\n return new Function(`return function ${ name } (${ utils.getArgumentNamesFromString(fnString).join(', ') }) {\r\n ${ utils.getFunctionBodyFromString(fnString) }\r\n}`)();\r\n}\r\n","import { GPU } from './base-gpu';\r\nimport { alias } from './alias';\r\nimport { utils } from './utils';\r\nimport * as common from './common';\r\nimport { Input, input } from './input';\r\nimport { Texture } from './texture';\r\nimport { FunctionBuilder } from './backend/function-builder';\r\nimport { FunctionNode } from './backend/function-node';\r\nimport { CPUFunctionNode } from './backend/cpu/function-node';\r\nimport { CPUKernel } from './backend/cpu/kernel';\r\nimport { WebGLFunctionNode } from './backend/web-gl/function-node';\r\nimport { WebGLKernel } from './backend/web-gl/kernel';\r\nimport { WebGL2FunctionNode } from './backend/web-gl2/function-node';\r\nimport { WebGL2Kernel } from './backend/web-gl2/kernel';\r\nimport { GLKernel } from './backend/gl/kernel';\r\nimport { Kernel } from './backend/kernel';\r\n\r\n/**\r\n * Stub for HeadlessGL.\r\n */\r\nclass HeadlessGLKernel extends WebGLKernel {\r\n static get isSupported() { return false }\r\n static isContextMatch() { return false }\r\n static getIsTextureFloat() { return false }\r\n static getIsDrawBuffers() { return false }\r\n static getChannelCount() { return 1 }\r\n static get testCanvas() { return null }\r\n static get testContext() { return null }\r\n static get features() { return null }\r\n static setupFeatureChecks() {}\r\n static destroyContext() {}\r\n initCanvas() { return {} }\r\n initContext() { return null }\r\n toString() { return '' }\r\n initExtensions() {}\r\n build() {}\r\n destroyExtensions() {}\r\n setOutput() {}\r\n\r\n static getFeatures() {\r\n return Object.freeze({\r\n isFloatRead: false,\r\n isIntegerDivisionAccurate: false,\r\n isTextureFloat: false,\r\n isDrawBuffers: false,\r\n kernelMap: false,\r\n channelCount: 1,\r\n });\r\n }\r\n};\r\n\r\nconst lib = GPU;\r\nlib.alias = alias;\r\nlib.CPUFunctionNode = CPUFunctionNode;\r\nlib.CPUKernel = CPUKernel;\r\nlib.FunctionBuilder = FunctionBuilder;\r\nlib.FunctionNode = FunctionNode;\r\nlib.HeadlessGLKernel = HeadlessGLKernel;\r\nlib.Input = Input;\r\nlib.input = input;\r\nlib.Texture = Texture;\r\nlib.utils = { ...common, ...utils };\r\nlib.WebGL2FunctionNode = WebGL2FunctionNode;\r\nlib.WebGL2Kernel = WebGL2Kernel;\r\nlib.WebGLFunctionNode = WebGLFunctionNode;\r\nlib.WebGLKernel = WebGLKernel;\r\nlib.GLKernel = GLKernel;\r\nlib.Kernel = Kernel;\r\n\r\nexport default lib;\r\n"],"names":["utils","parse","typeMap","name","glWiretap","fragmentShader","vertexShader","kernelValueMaps","lookupKernelValueType","isSupported","testCanvas","testContext","testExtensions","features","gpuMock"],"mappings":";;;;;;;;;;;;;;;;;EAAA,SAAS,cAAc,CAAC,IAAI,EAAE;IAC5B,MAAM,YAAY,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;MACpC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;MACpB,IAAI,GAAG,CAAC,OAAO,EAAE;QACf,YAAY,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;OACjC,MAAM;QACL,YAAY,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;OACvB;KACF;IACD,OAAO,YAAY,CAAC;GACrB;EAED,SAAS,MAAM,GAAG;IAChB,MAAM,IAAI,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IACvC,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;MACtC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;MAClB,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;MAClB,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;MAClB,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;KACrC;IACD,OAAO,GAAG,CAAC;GACZ;EAED,SAAS,MAAM,GAAG;IAChB,MAAM,IAAI,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;MACtC,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;MAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACtC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;QAClB,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;OACrC;MACD,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;KACjB;IACD,OAAO,MAAM,CAAC;GACf;EAED,SAAS,eAAe,GAAG;IACzB,MAAM,IAAI,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;MACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACtC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;OAC5B;KACF;GACF;EAED,SAAS,MAAM,GAAG;IAChB,MAAM,IAAI,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;MACtC,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;MACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACtC,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;UACtC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;UAClB,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;UAClB,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;UAClB,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;SACrC;QACD,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;OACjB;MACD,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;KAClB;IACD,OAAO,IAAI,CAAC;GACb;EAED,SAAS,WAAW,CAAC,MAAM,EAAE;IAC3B,MAAM,CAAC,SAAS,GAAG,CAAC,MAAM,KAAK;MAC7B,MAAM,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;MACpC,IAAI,MAAM,CAAC,SAAS,EAAE;QACpB,cAAc,CAAC,MAAM,CAAC,CAAC;OACxB;KACF,CAAC;IACF,MAAM,CAAC,MAAM,GAAG,MAAM;MACpB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;KAC5C,CAAC;IACF,MAAM,CAAC,YAAY,GAAG,CAAC,IAAI,KAAK;MAC9B,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC;MACxB,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,YAAY,GAAG,CAAC,IAAI,KAAK;MAC9B,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC;MACxB,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,SAAS,GAAG,CAAC,IAAI,KAAK;MAC3B,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC;MACrB,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,UAAU,GAAG,CAAC,IAAI,KAAK;MAC5B,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;MACtB,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,IAAI,GAAG,WAAW;MACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK;QACtC,IAAI;UACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;SAC1C,CAAC,MAAM,CAAC,EAAE;UACT,MAAM,CAAC,CAAC,CAAC,CAAC;SACX;OACF,CAAC,CAAC;KACJ,CAAC;IACF,MAAM,CAAC,SAAS,GAAG,CAAC,IAAI,KAAK;MAC3B,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;MAE7B,OAAO,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KAC1F,CAAC;IACF,MAAM,CAAC,KAAK,GAAG,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;MAClC,IAAI,OAAO,CAAC,KAAK,WAAW,EAAE;QAC5B,CAAC,GAAG,CAAC,CAAC;OACP;MAED,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;MACxB,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;MACxB,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;MACxB,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;MAExB,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;MAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;MAE/B,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;MAC1B,MAAM,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;MAEvC,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;MAE5B,MAAM,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;MACrC,MAAM,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;MACrC,MAAM,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;MACrC,MAAM,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;KACtC,CAAC;IAGF,MAAM,CAAC,eAAe,GAAG,MAAM;MAC7B,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,sBAAsB,GAAG,MAAM;MACpC,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,gBAAgB,GAAG,MAAM;MAC9B,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,QAAQ,GAAG,MAAM;MACtB,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,oBAAoB,GAAG,MAAM;MAClC,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,WAAW,GAAG,MAAM;MACzB,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,YAAY,GAAG,MAAM;MAC1B,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,YAAY,GAAG,MAAM;MAC1B,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,YAAY,GAAG,MAAM;MAC1B,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,YAAY,GAAG,MAAM;MAC1B,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,OAAO,GAAG,MAAM,EAAE,CAAC;IAC1B,MAAM,CAAC,gBAAgB,GAAG,MAAM,EAAE,CAAC;IACnC,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE;MACrC,cAAc,CAAC,MAAM,CAAC,CAAC;KACxB;IACD,OAAO,MAAM,CAAC;GACf;EAED,SAAS,cAAc,CAAC,MAAM,EAAE;IAC9B,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,eAAe,EAAE;MACpD,MAAM,IAAI,GAAG,IAAI,iBAAiB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;MAC9C,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;MACzD,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;KAC1B,MAAM;MACL,MAAM,IAAI,GAAG,IAAI,iBAAiB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;MAC9C,MAAM,CAAC,UAAU,GAAG,EAAE,IAAI,EAAE,CAAC;MAC7B,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;KAC1B;GACF;EAED,SAAS,WAAW,CAAC,MAAM,EAAE;IAC3B,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,MAAM,CAAC,MAAM,EAAE;MACjB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;QACvB,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;QACvB,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;OACtB,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;QAC9B,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;QACrB,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;OACnB,MAAM;QACL,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;QACnB,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC;OAChB;KACF,MAAM;MACL,MAAM,GAAG,MAAM,CAAC;KACjB;IACD,OAAO,MAAM,CAAC;GACf;EAED,SAAS,OAAO,CAAC,EAAE,EAAE,QAAQ,GAAG,EAAE,EAAE;IAClC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IACrE,SAAS,MAAM,GAAG;MAChB,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE;QACnB,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;OACxC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE;QAC1B,IAAI,MAAM,CAAC,SAAS,EAAE;UACpB,OAAO,eAAe,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;SACjD;QACD,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;OACxC,MAAM;QACL,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;OACxC;KACF;IACD,MAAM,CAAC,GAAG,GAAG,EAAE,CAAC;IAChB,MAAM,CAAC,SAAS,GAAG,QAAQ,CAAC,SAAS,IAAI,IAAI,CAAC;IAC9C,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,IAAI,IAAI,CAAC;IAC1C,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,IAAI,CAAC;IACxC,MAAM,CAAC,SAAS,GAAG,QAAQ,CAAC,SAAS,IAAI,KAAK,CAAC;IAC/C,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;IACzB,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;IACzB,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,MAAM,CAAC,MAAM,GAAG;MACd,CAAC,EAAE,CAAC;MACJ,CAAC,EAAE,CAAC;MACJ,CAAC,EAAE,CAAC;KACL,CAAC;IACF,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;GAC5B;EAED,SAAS,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;IAEzC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;IAE9B,MAAM,IAAI,GAAG,IAAI,iBAAiB,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,EAAE,CAAC,EAAE;MACnC,MAAM,SAAS,GAAG,CAAC,GAAG,WAAW,CAAC;MAClC,MAAM,YAAY,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC;MAGpD,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC;MAG9D,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,YAAY,EAAE,YAAY,GAAG,WAAW,CAAC,CAAC;MAGvE,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;KAChC;IACD,OAAO,MAAM,CAAC;GACf;EAED,cAAc,GAAG;IACf,OAAO;GACR,CAAC;;;ECnQF,MAAM,cAAc,GAAG,YAAY,CAAC;EACpC,MAAM,aAAa,GAAG,kBAAkB,CAAC;EACzC,MAAM,cAAc,GAAG,kCAAkC,CAAC;AAO1D,EAAO,SAAS,UAAU,CAAC,OAAO,EAAE;EACpC,EAAE,OAAO,OAAO,OAAO,CAAC,KAAK,UAAU,CAAC;EACxC,CAAC,AAOM,SAAS,yBAAyB,CAAC,OAAO,EAAE;EACnD,EAAE,OAAO,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;EAC/C,CAAC,AAQM,SAAS,mBAAmB,CAAC,MAAM,EAAE,QAAQ,EAAE;EACtD,EAAE,QAAQ,GAAG,QAAQ,IAAI,EAAE,CAAC;EAC5B,EAAE,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;EACrH,EAAE,MAAM,YAAY,GAAG,OAAO,MAAM,KAAK,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;EAE/E,EAAE,IAAI,aAAa,GAAG,EAAE,CAAC;EAEzB,EAAE,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE;EAC7C,IAAI,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC;EAC3C,GAAG,MAAM,IAAI,OAAO,QAAQ,CAAC,aAAa,KAAK,QAAQ,EAAE;EACzD,IAAI,aAAa,GAAG,0BAA0B,CAAC,YAAY,CAAC;EAC5D,OAAO,GAAG,CAAC,IAAI,IAAI,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;EACvD,GAAG,MAAM;EACT,IAAI,aAAa,GAAG,QAAQ,CAAC,aAAa,IAAI,EAAE,CAAC;EACjD,GAAG;EAEH,EAAE,OAAO;EACT,IAAI,MAAM,EAAE,YAAY;EACxB,IAAI,aAAa;EACjB,IAAI,UAAU,EAAE,QAAQ,CAAC,UAAU,IAAI,IAAI;EAC3C,GAAG,CAAC;EACJ,CAAC,AAEM,SAAS,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE;EACvD,EAAE,MAAM,GAAG,GAAG,OAAO;EACrB,MAAM,CAAC,2BAA2B,GAAG,OAAO,EAAE,CAAC,CAAC;EAChD,MAAM,qBAAqB,CAAC;EAC5B,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,2BAA2B,GAAG,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,wDAAwD,CAAC,EAAC;EACrI,CAAC,AASM,SAAS,gBAAgB,CAAC,EAAE,EAAE;EACrC,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE;EAC9B,IAAI,QAAQ,EAAE;EACd,OAAO,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC;EAClC,OAAO,WAAW,EAAE,KAAK,UAAU,EAAE;EACrC,GAAG;EACH,EAAE,OAAO,KAAK,CAAC;EACf,CAAC,AAOM,SAAS,0BAA0B,CAAC,EAAE,EAAE;EAC/C,EAAE,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;EAC/C,EAAE,IAAI,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;EAC7F,EAAE,IAAI,MAAM,KAAK,IAAI,EAAE;EACvB,IAAI,MAAM,GAAG,EAAE,CAAC;EAChB,GAAG;EACH,EAAE,OAAO,MAAM,CAAC;EAChB,CAAC,AAOM,SAAS,OAAO,CAAC,KAAK,EAAE;EAC/B,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;EAC9B,CAAC,AAEM,SAAS,2BAA2B,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE;EAClE,EAAE,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACrC,EAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACnC,IAAI,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC;EAC7B,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC;EACzD,GAAG;EACH,EAAE,OAAO,QAAQ,CAAC;EAClB,CAAC,AAEM,SAAS,2BAA2B,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE;EACzE,EAAE,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACpC,EAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;EAClC,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACvC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACrC,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,MAAM,GAAG,KAAK,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC;EACxD,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC;EAC3D,KAAK;EACL,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC3B,GAAG;EACH,EAAE,OAAO,QAAQ,CAAC;EAClB,CAAC,AAEM,SAAS,YAAY,CAAC,MAAM,EAAE,GAAG,EAAE;EAC1C,EAAE,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;EACxE,EAAE,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC;EAC9B,EAAE,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;EAC1B,EAAE,MAAM,MAAM,GAAG,EAAE,CAAC;EACpB,EAAE,IAAI,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,EAAE;EAC/B,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;EAC3E,GAAG,MAAM;EACT,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;EAC3D,IAAI,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;EAChD,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;EAC5B,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;EAC1D,GAAG;EACH,EAAE,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC3B,CAAC;;;;;;;;;;;;;;;ECxIM,MAAM,KAAK,CAAC;EACnB,EAAE,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE;EAC3B,IAAI,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;EACvB,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;EAC7B,MAAM,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;EACvB,KAAK,MAAM;EACX,MAAM,IAAI,CAAC,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;EACpC,MAAM,IAAI,IAAI,CAAC,CAAC,EAAE;EAClB,QAAQ,IAAI,CAAC,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC7D,OAAO,MAAM,IAAI,IAAI,CAAC,CAAC,EAAE;EACzB,QAAQ,IAAI,CAAC,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EACrD,OAAO,MAAM;EACb,QAAQ,IAAI,CAAC,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC7C,OAAO;EACP,KAAK;EAEL,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;EAChC,IAAI,IAAI,CAAC,EAAE;EACX,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE;EAC7C,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;EAC9G,OAAO;EACP,KAAK,MAAM,IAAI,CAAC,EAAE;EAClB,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE;EACzC,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;EACnG,OAAO;EACP,KAAK,MAAM;EACX,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;EACnC,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/E,OAAO;EACP,KAAK;EAEL,GAAG;EAEH,EAAE,OAAO,GAAG;EACZ,IAAI,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC;EAClC,IAAI,IAAI,CAAC,EAAE;EACX,MAAM,OAAO,2BAA2B,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;EACnH,KAAK,MAAM,IAAI,CAAC,EAAE;EAClB,MAAM,OAAO,2BAA2B,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;EAChH,KAAK,MAAM;EACX,MAAM,OAAO,IAAI,CAAC,KAAK,CAAC;EACxB,KAAK;EACL,GAAG;EACH,CAAC,AAEM,SAAS,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE;EACnC,EAAE,OAAO,IAAI,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EAChC,CAAC;;EC7CM,MAAM,OAAO,CAAC;EACrB,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,MAAM;EACV,MAAM,OAAO;EACb,MAAM,IAAI;EACV,MAAM,UAAU;EAChB,MAAM,MAAM;EACZ,MAAM,OAAO;EACb,MAAM,IAAI,GAAG,eAAe;EAC5B,KAAK,GAAG,QAAQ,CAAC;EACjB,IAAI,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;EACzE,IAAI,IAAI,CAAC,OAAO,EAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;EAC3E,IAAI,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;EAC3B,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;EACrB,IAAI,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;EACjC,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;EACzB,IAAI,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;EAC3B,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;EACvB,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;EACrB,GAAG;EAMH,EAAE,OAAO,GAAG;EACZ,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,mBAAmB,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EACnE,GAAG;EAKH,EAAE,MAAM,GAAG;EACX,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACpD,GAAG;EACH,CAAC;;ECvBM,SAAS,mBAAmB,GAAG;EACtC,EAAE,MAAM,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;EAC/B,EAAE,MAAM,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;EAC/B,EAAE,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;EAC9B,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC;EACpB,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,OAAO,IAAI,CAAC;EACjC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,OAAO,IAAI,CAAC;EACjC,EAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;EACxC,CAAC,AAED,MAAM,iBAAiB,GAAG,mBAAmB,EAAE,CAAC;AAQhD,EAAO,SAAS,gBAAgB,GAAG;EACnC,EAAE,OAAO,iBAAiB,CAAC;EAC3B,CAAC,AAOM,SAAS,eAAe,CAAC,KAAK,EAAE,cAAc,EAAE;EACvD,EAAE,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE;EACtB,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,KAAK,EAAE;EACrC,MAAM,OAAO,gBAAgB,CAAC;EAC9B,KAAK;EACL,IAAI,OAAO,OAAO,CAAC;EACnB,GAAG;EAEH,EAAE,QAAQ,KAAK,CAAC,WAAW;EAC3B,IAAI,KAAK,OAAO;EAChB,MAAM,OAAO,SAAS,CAAC;EACvB,IAAI,KAAK,MAAM;EACf,MAAM,OAAO,cAAc,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC;EAC7E,IAAI,KAAK,OAAO;EAChB,MAAM,OAAO,KAAK,CAAC,IAAI,CAAC;EACxB,IAAI,KAAK,KAAK;EACd,MAAM,OAAO,OAAO,CAAC;EACrB,GAAG;EAEH,EAAE,QAAQ,KAAK,CAAC,QAAQ;EACxB,IAAI,KAAK,KAAK;EACd,MAAM,OAAO,WAAW,CAAC;EACzB,IAAI,KAAK,OAAO;EAChB,MAAM,OAAO,WAAW,CAAC;EACzB,GAAG;EAEH,EAAE,OAAO,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC;EAC/D,CAAC,AAMD,MAAMA,OAAK,GAAG;EACd,EAAE,gBAAgB;EAClB,EAAE,mBAAmB;EACrB,EAAE,UAAU;EACZ,EAAE,gBAAgB;EAClB,EAAE,yBAAyB;EAE3B,EAAE,yBAAyB,CAAC,OAAO,EAAE;EACrC,IAAI,OAAO,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;EACjF,GAAG;EAEH,EAAE,0BAA0B;EAO5B,EAAE,KAAK,CAAC,GAAG,EAAE;EACb,IAAI,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,cAAc,CAAC,eAAe,CAAC,EAAE,OAAO,GAAG,CAAC;EAEnG,IAAI,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;EAEnC,IAAI,KAAK,IAAI,GAAG,IAAI,GAAG,EAAE;EACzB,MAAM,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE;EAC1D,QAAQ,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC;EACjC,QAAQ,IAAI,CAAC,GAAG,CAAC,GAAGA,OAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;EAC1C,QAAQ,OAAO,GAAG,CAAC,aAAa,CAAC;EACjC,OAAO;EACP,KAAK;EAEL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,OAAO;EACT,EAAE,eAAe;EAEjB,EAAE,oBAAoB,CAAC,QAAQ,EAAE,UAAU,EAAE;EAC7C,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC;EAC/B,IAAI,IAAI,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EAEpD,IAAI,IAAI,QAAQ,CAAC,mBAAmB,IAAI,QAAQ,CAAC,SAAS,KAAK,QAAQ,EAAE;EACzE,MAAM,CAAC,GAAG,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;EACjD,KAAK;EAEL,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,UAAU,EAAE;EACvC,MAAM,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;EACpC,KAAK;EACL,IAAI,OAAOA,OAAK,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;EACrD,GAAG;EAOH,EAAE,uBAAuB,CAAC,MAAM,EAAE;EAClC,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACnC,IAAI,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC/B,IAAI,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;EAC/B,IAAI,OAAO,IAAI,GAAG,GAAG,GAAG,MAAM,EAAE;EAChC,MAAM,IAAI,EAAE,CAAC;EACb,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;EACrC,KAAK;EACL,IAAI,OAAO,IAAI,UAAU,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;EAC1D,GAAG;EAQH,EAAE,kCAAkC,CAAC,UAAU,EAAE,QAAQ,EAAE;EAC3D,IAAI,MAAM,SAAS,GAAGA,OAAK,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;EAClI,IAAI,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;EAC5C,IAAI,OAAOA,OAAK,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;EACrD,GAAG;EAQH,EAAE,mCAAmC,CAAC,UAAU,EAAE,QAAQ,EAAE;EAC5D,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC;EACjC,IAAI,MAAM,SAAS,GAAGA,OAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;EACvE,IAAI,MAAM,UAAU,GAAG,SAAS,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;EAClD,IAAI,OAAOA,OAAK,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;EACrD,GAAG;EAEH,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE;EAChB,IAAI,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;EAC3C,GAAG;EAOH,EAAE,aAAa,CAAC,CAAC,EAAE,GAAG,EAAE;EACxB,IAAI,IAAI,GAAG,CAAC;EACZ,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE;EACpB,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC;EACrB,MAAM,IAAI,IAAI,GAAG,CAAC,CAAC;EACnB,MAAM,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE;EAC5B,QAAQ,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC9B,QAAQ,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;EACvB,OAAO;EACP,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;EAC1B,KAAK,MAAM,IAAI,CAAC,YAAY,OAAO,EAAE;EACrC,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC;EACrB,KAAK,MAAM,IAAI,CAAC,YAAY,KAAK,EAAE;EACnC,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC;EACnB,KAAK,MAAM;EACX,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,sBAAsB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;EACpD,KAAK;EAEL,IAAI,IAAI,GAAG,EAAE;EACb,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC5B,MAAM,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE;EAC7B,QAAQ,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EACpB,OAAO;EACP,KAAK;EAEL,IAAI,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;EAC/B,GAAG;EAOH,EAAE,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE;EAClC,IAAI,IAAI,MAAM,GAAG,CAAC,CAAC;EACnB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC3C,MAAM,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EACnC,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;EAChC,KAAK;EACL,GAAG;EAOH,EAAE,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE;EAClC,IAAI,IAAI,MAAM,GAAG,CAAC,CAAC;EACnB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC3C,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAChD,QAAQ,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EACxC,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;EACrC,OAAO;EACP,KAAK;EACL,GAAG;EAOH,EAAE,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE;EAClC,IAAI,IAAI,MAAM,GAAG,CAAC,CAAC;EACnB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC3C,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAChD,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,UAAU,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EAC7C,UAAU,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;EAC1C,SAAS;EACT,OAAO;EACP,KAAK;EACL,GAAG;EAOH,EAAE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE;EAC3B,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;EAC3B,MAAM,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;EAChC,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;EACrC,UAAUA,OAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAChD,SAAS,MAAM;EACf,UAAUA,OAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAChD,SAAS;EACT,OAAO,MAAM;EACb,QAAQA,OAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC9C,OAAO;EACP,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;EACxB,KAAK;EACL,GAAG;EAYH,EAAE,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE;EAC1B,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,EAAE;EACjD,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;EACvF,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,YAAY;EAEd,EAAE,eAAe,CAAC,GAAG,EAAE;EACvB,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;EAErB,IAAI,GAAG;EACP,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC;EAC/D,KAAK,QAAQ,GAAG,GAAG,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;EAE/C,IAAI,OAAO,KAAK,CAAC;EACjB,GAAG;EAMH,EAAE,aAAa,CAAC,KAAK,EAAE;EACvB,IAAI,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;EAC1B,MAAM,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC;EACvC,KAAK,MAAM;EACX,MAAM,OAAO,IAAI,CAAC;EAClB,KAAK;EACL,GAAG;EAEH,EAAE,cAAc;EAChB,EAAE,mBAAmB;EAErB,EAAE,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;EAEpC,IAAI,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC;EACtC,IAAI,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;EAElC,IAAI,MAAM,IAAI,GAAG,IAAI,iBAAiB,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;EAClD,IAAI,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;EACnC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,EAAE,CAAC,EAAE;EACzC,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,WAAW,CAAC;EACxC,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC;EAG1D,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC;EAGpE,MAAM,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,YAAY,EAAE,YAAY,GAAG,WAAW,CAAC,CAAC;EAG7E,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;EACrC,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,gBAAgB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK;EACtC,IAAI,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;EACpC,GAAG;EACH,EAAE,kBAAkB,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK;EAChD,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACvC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACrC,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC;EAC/B,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,KAAK,CAAC;EAClC,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;EACjD,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,kBAAkB,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,KAAK;EACvD,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACtC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;EACpC,MAAM,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACzC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACvC,QAAQ,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,MAAM,GAAG,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC;EACxD,QAAQ,MAAM,IAAI,GAAG,MAAM,GAAG,KAAK,CAAC;EACpC,QAAQ,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;EACnD,OAAO;EACP,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC7B,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,yBAAyB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK;EAC/C,IAAI,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;EACpC,GAAG;EACH,EAAE,2BAA2B;EAC7B,EAAE,2BAA2B;EAC7B,EAAE,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK;EAChC,IAAI,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;EAC7C,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;EACd,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;EACpC,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;EAC7B,MAAM,CAAC,IAAI,CAAC,CAAC;EACb,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK;EAC1C,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACvC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;EACd,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACrC,MAAM,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;EAC/C,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;EACtC,QAAQ,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;EAC/B,QAAQ,CAAC,IAAI,CAAC,CAAC;EACf,OAAO;EACP,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC7B,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,KAAK;EACjD,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACtC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;EACd,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;EACpC,MAAM,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACzC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACvC,QAAQ,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;EACjD,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;EACxC,UAAU,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;EACjC,UAAU,CAAC,IAAI,CAAC,CAAC;EACjB,SAAS;EACT,QAAQ,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC/B,OAAO;EACP,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC7B,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK;EACjC,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACtC,IAAI,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;EACd,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE;EAC7C,MAAM,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;EAC/C,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK;EAC3C,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACvC,IAAI,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;EAClC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACrC,MAAM,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACxC,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,WAAW,CAAC;EACrC,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;EAChB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE;EAC/C,QAAQ,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;EACnE,OAAO;EACP,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC7B,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,KAAK;EAClD,IAAI,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;EAClC,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACtC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;EACpC,MAAM,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACzC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACvC,QAAQ,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EAC1C,QAAQ,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,WAAW,GAAG,MAAM,KAAK,CAAC,GAAG,WAAW,CAAC,CAAC;EACtE,QAAQ,IAAI,CAAC,GAAG,CAAC,CAAC;EAClB,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE;EACjD,UAAU,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;EACrE,SAAS;EACT,QAAQ,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC/B,OAAO;EACP,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC7B,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK;EACjC,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACtC,IAAI,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;EACd,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE;EAC7C,MAAM,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;EAC/C,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK;EAC3C,IAAI,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;EAClC,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACvC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACrC,MAAM,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACxC,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,WAAW,CAAC;EACrC,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;EAChB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE;EAC/C,QAAQ,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;EACnE,OAAO;EACP,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC7B,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,KAAK;EAClD,IAAI,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;EAClC,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACtC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;EACpC,MAAM,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACzC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACvC,QAAQ,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EAC1C,QAAQ,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,WAAW,GAAG,MAAM,KAAK,CAAC,GAAG,WAAW,CAAC,CAAC;EACtE,QAAQ,IAAI,CAAC,GAAG,CAAC,CAAC;EAClB,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE;EACjD,UAAU,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;EACrE,SAAS;EACT,QAAQ,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC/B,OAAO;EACP,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC7B,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK;EACjC,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACtC,IAAI,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;EACd,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE;EAC7C,MAAM,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;EAC/C,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK;EAC3C,IAAI,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;EAClC,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACvC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACrC,MAAM,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACxC,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,WAAW,CAAC;EACrC,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;EAChB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE;EAC/C,QAAQ,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;EACnE,OAAO;EACP,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC7B,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,KAAK;EAClD,IAAI,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;EAClC,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACtC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;EACpC,MAAM,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACzC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACvC,QAAQ,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EAC1C,QAAQ,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,WAAW,GAAG,MAAM,KAAK,CAAC,GAAG,WAAW,CAAC,CAAC;EACtE,QAAQ,IAAI,CAAC,GAAG,CAAC,CAAC;EAClB,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE;EACjD,UAAU,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;EACrE,SAAS;EACT,QAAQ,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC/B,OAAO;EACP,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC7B,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EAOH,EAAE,uBAAuB,EAAE,CAAC,MAAM,EAAE,QAAQ,KAAK;EACjD,IAAI,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,QAAQ,CAAC;EACjE,IAAI,IAAI,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC;EACvC,IAAI,IAAI,CAAC,SAAS,EAAE;EACpB,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,GAAG,EAAE,CAAC;EAC1C,KAAK;EAEL,IAAI,MAAM,GAAG,GAAGC,WAAK,CAAC,MAAM,CAAC,CAAC;EAC9B,IAAI,MAAM,oBAAoB,GAAG,EAAE,CAAC;EAEpC,IAAI,SAAS,OAAO,CAAC,GAAG,EAAE;EAC1B,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;EAC9B,QAAQ,MAAM,OAAO,GAAG,EAAE,CAAC;EAC3B,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC7C,UAAU,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACxC,SAAS;EACT,QAAQ,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EAChC,OAAO;EACP,MAAM,QAAQ,GAAG,CAAC,IAAI;EACtB,QAAQ,KAAK,SAAS;EACtB,UAAU,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EACnC,QAAQ,KAAK,qBAAqB;EAClC,UAAU,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EACzG,QAAQ,KAAK,gBAAgB,EAAE;EAC/B,UAAU,MAAM,MAAM,GAAG,EAAE,CAAC;EAC5B,UAAU,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACpD,YAAY,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;EACrD,WAAW;EACX,UAAU,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1C,SAAS;EACT,QAAQ,KAAK,qBAAqB;EAClC,UAAU,QAAQ,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI;EAC7C,YAAY,KAAK,eAAe,EAAE;EAClC,cAAc,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EAC/D,cAAc,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,IAAI,WAAW,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAChH,cAAc,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;EACvC,gBAAgB,MAAM,MAAM,GAAG,EAAE,CAAC;EAClC,gBAAgB,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;EAC3D,gBAAgB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACzD,kBAAkB,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EAC5C,kBAAkB,IAAI,MAAM,KAAK,IAAI,EAAE,SAAS;EAChD,kBAAkB,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;EACjD,kBAAkB,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,QAAQ,EAAE,GAAG,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;EAC5E,iBAAiB;EAEjB,gBAAgB,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EACvC,eAAe;EACf,cAAc,OAAO,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;EACjE,aAAa;EACb,YAAY,KAAK,cAAc;EAC/B,cAAc,OAAO,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC3J,WAAW;EACX,UAAU,IAAI,WAAW,IAAI,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE;EACtF,YAAY,OAAO,EAAE,CAAC;EACtB,WAAW;EACX,UAAU,OAAO,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EACrG,QAAQ,KAAK,gBAAgB,EAAE;EAC/B,UAAU,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,UAAU,EAAE;EACvD,YAAY,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC7I,WAAW;EACX,UAAU,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE;EACvF,YAAY,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC7I,WAAW;EACX,UAAU,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,gBAAgB,EAAE;EAC3D,YAAY,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;EACxF,YAAY,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC3G,WAAW,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;EAC7C,YAAY,MAAM,WAAW,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;EACjG,YAAY,IAAI,WAAW,KAAK,IAAI,EAAE;EAEtC,cAAc,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EACvI,aAAa,MAAM;EACnB,cAAc,oBAAoB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;EAErD,cAAc,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC7G,aAAa;EACb,WAAW,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,kBAAkB,EAAE;EACpE,YAAY,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EACzI,WAAW,MAAM;EACjB,YAAY,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;EAClD,WAAW;EACX,SAAS;EACT,QAAQ,KAAK,iBAAiB;EAC9B,UAAU,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;EACnD,QAAQ,KAAK,kBAAkB;EAC/B,UAAU,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;EAC9E,QAAQ,KAAK,iBAAiB;EAC9B,UAAU,IAAI,GAAG,CAAC,MAAM,EAAE;EAC1B,YAAY,OAAO,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;EAC9D,WAAW,MAAM;EACjB,YAAY,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;EAC9D,WAAW;EACX,UAAU,KAAK,qBAAqB;EACpC,YAAY,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;EAClD,UAAU,KAAK,yBAAyB;EACxC,YAAY,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EACrF,UAAU,KAAK,SAAS;EACxB,YAAY,OAAO,GAAG,CAAC,GAAG,CAAC;EAC3B,UAAU,KAAK,YAAY;EAC3B,YAAY,OAAO,GAAG,CAAC,IAAI,CAAC;EAC5B,UAAU,KAAK,kBAAkB;EACjC,YAAY,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,gBAAgB,EAAE;EACtD,cAAc,OAAO,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;EACnD,aAAa;EACb,YAAY,IAAI,GAAG,CAAC,QAAQ,EAAE;EAC9B,cAAc,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;EACxE,aAAa;EACb,YAAY,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EACrE,UAAU,KAAK,gBAAgB;EAC/B,YAAY,OAAO,MAAM,CAAC;EAC1B,UAAU,KAAK,eAAe;EAC9B,YAAY,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1G,UAAU,KAAK,cAAc;EAC7B,YAAY,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EACjH,UAAU,KAAK,sBAAsB;EACrC,YAAY,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;EAC9E,UAAU,KAAK,kBAAkB;EACjC,YAAY,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;EAC7D,UAAU,KAAK,aAAa;EAC5B,YAAY,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC1E,UAAU,KAAK,gBAAgB;EAC/B,YAAY,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;EACpD,UAAU,KAAK,eAAe;EAC9B,YAAY,OAAO,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC1D,UAAU,KAAK,cAAc;EAC7B,YAAY,OAAO,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EACxD,UAAU,KAAK,mBAAmB;EAClC,YAAY,OAAO,WAAW,CAAC;EAC/B,UAAU,KAAK,uBAAuB;EACtC,YAAY,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;EAC/F,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE;EACrC,cAAc,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;EACtC,aAAa;EACb,OAAO;EACP,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,sBAAsB,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC7D,KAAK;EACL,IAAI,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;EAChC,IAAI,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE;EACzC,MAAM,MAAM,6BAA6B,GAAG,EAAE,CAAC;EAC/C,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,oBAAoB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC5D,QAAQ,MAAM,kBAAkB,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC;EAC3D,QAAQ,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,EAAE;EAC5C,UAAU,SAAS,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC;EAC/C,SAAS;EACT,QAAQ,6BAA6B,CAAC,IAAI,CAACD,OAAK,CAAC,uBAAuB,CAAC,kBAAkB,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,CAAC;EAChH,OAAO;EACP,MAAM,OAAO,6BAA6B,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC;EAC7D,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,CAAC,CAAC;;ECtqBK,MAAM,MAAM,CAAC;EAIpB,EAAE,WAAW,WAAW,GAAG;EAC3B,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,iCAAiC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACvE,GAAG;EAKH,EAAE,OAAO,cAAc,CAAC,OAAO,EAAE;EACjC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oCAAoC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC1E,GAAG;EAMH,EAAE,OAAO,WAAW,GAAG;EACvB,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,iCAAiC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACvE,GAAG;EAEH,EAAE,OAAO,cAAc,CAAC,OAAO,EAAE;EACjC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,2BAA2B,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACjE,GAAG;EAEH,EAAE,OAAO,uBAAuB,GAAG;EACnC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oCAAoC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC1E,GAAG;EAEH,EAAE,OAAO,wBAAwB,GAAG;EACpC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,qCAAqC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC3E,GAAG;EAEH,EAAE,OAAO,cAAc,GAAG;EAC1B,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,2BAA2B,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACjE,GAAG;EAOH,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE;EAChC,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;EACpC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;EACtC,QAAQ,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;EAC/C,OAAO;EACP,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE;EACrC,QAAQ,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;EACxD,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;EAClC,IAAI,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;EACnC,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;EAMlC,IAAI,IAAI,CAAC,aAAa,GAAG,OAAO,MAAM,KAAK,QAAQ,GAAG,0BAA0B,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;EAChG,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;EAC9B,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;EAC9B,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;EAClC,IAAI,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;EAChC,IAAI,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;EAOhC,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;EAMzB,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;EAMvB,IAAI,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;EAMvB,IAAI,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;EAM3B,IAAI,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;EAM/B,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAC1B,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;EAC9B,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;EAClC,IAAI,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;EAClC,IAAI,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;EAM/B,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;EAMvB,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;EAMxB,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;EAM7B,IAAI,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;EAMpB,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAM1B,IAAI,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;EAMhC,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;EAM/B,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EAM3B,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;EAMzB,IAAI,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;EAM3B,IAAI,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;EAO1B,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAO1B,IAAI,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC;EAE7B,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;EAExB,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EAC3B,IAAI,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC;EACvC,IAAI,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC;EACzC,IAAI,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;EACpC,IAAI,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;EAChC,IAAI,IAAI,CAAC,0BAA0B,GAAG,IAAI,CAAC;EAC3C,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;EAC7B,GAAG;EAEH,EAAE,aAAa,CAAC,QAAQ,EAAE;EAC1B,IAAI,KAAK,IAAI,CAAC,IAAI,QAAQ,EAAE;EAC5B,MAAM,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS;EAC3E,MAAM,QAAQ,CAAC;EACf,QAAQ,KAAK,QAAQ;EACrB,UAAU,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;EAC/C,YAAY,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;EAC5C,YAAY,SAAS;EACrB,WAAW;EACX,UAAU,MAAM;EAChB,QAAQ,KAAK,WAAW;EACxB,UAAU,IAAI,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE;EAC3D,YAAY,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC;EAC3F,YAAY,SAAS;EACrB,WAAW;EACX,UAAU,MAAM;EAChB,QAAQ,KAAK,WAAW;EACxB,UAAU,IAAI,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE;EACpE,YAAY,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC;EACxC,WAAW;EACX,UAAU,IAAI,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;EAChC,UAAU,SAAS;EACnB,OAAO;EACP,MAAM,IAAI,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;EAC5B,KAAK;EAEL,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;EACtD,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;EACzD,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;EACjE,GAAG;EAMH,EAAE,KAAK,GAAG;EACV,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,uBAAuB,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACzE,GAAG;EAQH,EAAE,GAAG,GAAG;EACR,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,qBAAqB,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;EACtE,GAAG;EAMH,EAAE,UAAU,GAAG;EACf,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,4BAA4B,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC9E,GAAG;EAMH,EAAE,WAAW,GAAG;EAChB,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,6BAA6B,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC/E,GAAG;EAOH,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,6BAA6B,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC/E,GAAG;EAQH,EAAE,cAAc,CAAC,IAAI,EAAE;EACvB,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE;EAC7B,MAAM,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE;EAC/B,QAAQ,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAChC,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC9C,UAAU,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;EACxE,UAAU,MAAM,IAAI,GAAG,OAAO,KAAK,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;EAClE,UAAU,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EACxC,UAAU,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;EACpC,YAAY,IAAI;EAChB,WAAW,CAAC,CAAC;EACb,SAAS;EACT,OAAO;EACP,KAAK,MAAM;EACX,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC1D,QAAQ,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;EAClC,UAAU,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;EACrC,SAAS,CAAC,CAAC;EACX,OAAO;EACP,KAAK;EAGL,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAChD,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAEzD,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC1C,MAAM,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;EAC1B,MAAM,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,WAAW,KAAK,KAAK,GAAG,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;EAC1E,MAAM,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;EACxD,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE;EACnD,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC;EACpD,KAAK;EACL,GAAG;EAKH,EAAE,cAAc,GAAG;EACnB,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,kBAAkB,GAAG,IAAI,CAAC,aAAa,KAAK,IAAI,CAAC;EACzD,IAAI,IAAI,kBAAkB,EAAE;EAC5B,MAAM,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAC9B,KAAK;EACL,IAAI,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;EAChC,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,KAAK,IAAI,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACvC,QAAQ,IAAI,kBAAkB,EAAE;EAChC,UAAU,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;EAClF,UAAU,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;EAC1C,UAAU,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;EACpC,YAAY,IAAI;EAChB,YAAY,IAAI;EAChB,WAAW,CAAC,CAAC;EACb,SAAS,MAAM;EACf,UAAU,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;EACpC,YAAY,IAAI;EAChB,YAAY,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;EAC1C,WAAW,CAAC,CAAC;EACb,SAAS;EACT,QAAQ,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;EAC9E,OAAO;EACP,KAAK;EACL,GAAG;EAOH,EAAE,sBAAsB,CAAC,IAAI,EAAE;EAC/B,IAAI,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;EACpC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAMH,EAAE,SAAS,CAAC,MAAM,EAAE;EACpB,IAAI,IAAI,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;EACpC,MAAM,IAAI,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;EACtC,QAAQ,IAAI,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;EACxC,UAAU,IAAI,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;EACvD,SAAS,MAAM;EACf,UAAU,IAAI,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;EAC7C,SAAS;EACT,OAAO,MAAM;EACb,QAAQ,IAAI,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;EACjC,OAAO;EACP,KAAK,MAAM;EACX,MAAM,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;EAC3B,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAMH,EAAE,QAAQ,CAAC,IAAI,EAAE;EACjB,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;EACtB,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAMH,EAAE,YAAY,CAAC,IAAI,EAAE;EACrB,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAC1B,IAAI,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC;EAChC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,oBAAoB,CAAC,GAAG,EAAE;EAC5B,IAAI,IAAI,CAAC,iBAAiB,GAAG,GAAG,CAAC;EACjC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAKH,EAAE,YAAY,CAAC,SAAS,EAAE;EAC1B,IAAI,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;EAC/B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,gBAAgB,CAAC,aAAa,EAAE;EAClC,IAAI,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;EACvC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,YAAY,CAAC,SAAS,EAAE;EAC1B,IAAI,IAAI,OAAO,SAAS,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE;EAC5C,MAAM,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC;EAC5E,KAAK,MAAM;EACX,MAAM,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;EACjC,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,kBAAkB,CAAC,eAAe,EAAE;EACtC,IAAI,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;EAC3C,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,iBAAiB,CAAC,cAAc,EAAE;EACpC,IAAI,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;EACzC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,WAAW,CAAC,IAAI,EAAE;EACpB,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;EACzB,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,YAAY,CAAC,IAAI,EAAE;EACrB,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAC1B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,kBAAkB,CAAC,IAAI,EAAE;EAC3B,IAAI,cAAc,CAAC,QAAQ,EAAE,oBAAoB,EAAE,aAAa,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;EACzB,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,YAAY,CAAC,IAAI,EAAE;EACrB,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAC1B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAMH,EAAE,SAAS,CAAC,MAAM,EAAE;EACpB,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;EACzB,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAMH,EAAE,iBAAiB,CAAC,IAAI,EAAE;EAC1B,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;EAC/B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,gBAAgB,CAAC,IAAI,EAAE;EACzB,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;EAC9B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,oBAAoB,CAAC,IAAI,EAAE;EAC7B,IAAI,cAAc,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAAC;EACrD,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;EAChC,IAAI,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;EACnC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,mBAAmB,CAAC,IAAI,EAAE;EAC5B,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;EACjC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAMH,EAAE,mBAAmB,CAAC,IAAI,EAAE;EAC5B,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;EACjC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,eAAe,CAAC,IAAI,EAAE;EACxB,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;EAC7B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAMH,EAAE,SAAS,GAAG;EACd,IAAI,cAAc,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;EAC1C,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC;EACvB,GAAG;EAMH,EAAE,QAAQ,GAAG;EACb,IAAI,cAAc,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;EACzC,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC;EACxB,GAAG;EAMH,EAAE,UAAU,CAAC,OAAO,EAAE;EACtB,IAAI,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;EAC3B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,gBAAgB,CAAC,aAAa,EAAE;EAClC,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE;EACtC,MAAM,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;EACzC,KAAK,MAAM;EACX,MAAM,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAC9B,MAAM,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE;EACrC,QAAQ,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;EAC5D,QAAQ,IAAI,aAAa,KAAK,CAAC,CAAC,EAAE,MAAM,IAAI,KAAK,CAAC,CAAC,wBAAwB,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;EACpF,QAAQ,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;EAC7D,OAAO;EACP,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,SAAS,CAAC,MAAM,EAAE;EACpB,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;EACzB,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,eAAe,CAAC,IAAI,EAAE;EACxB,IAAI,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE;EACjC,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,mCAAmC,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACvF,KAAK;EACL,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;EAClC,IAAI,OAAO,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;EACxC,GAAG;EAMH,EAAE,gBAAgB,GAAG;EACrB,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,kCAAkC,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACpF,GAAG;EAQH,EAAE,YAAY,CAAC,SAAS,EAAE;EAC1B,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;EAClC,MAAM,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;EAC3B,KAAK;EACL,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;EAClF,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,IAAI,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;EACnH,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;EAC9E,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EACpC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAMH,EAAE,OAAO,CAAC,sBAAsB,EAAE;EAClC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACtE,GAAG;EAOH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE;EAErC,MAAM,OAAO,CAAC,CAAC;EACf,KAAK,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;EACxC,MAAM,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;EACxC,KAAK,MAAM,IAAI,KAAK,CAAC,WAAW,KAAK,KAAK,EAAE;EAC5C,MAAM,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;EAC3C,KAAK;EACL,IAAI,QAAQ,KAAK,CAAC,WAAW;EAC7B,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,SAAS;EACpB,QAAQ,OAAO,CAAC,CAAC;EACjB,MAAM,KAAK,WAAW,CAAC;EACvB,MAAM,KAAK,UAAU;EACrB,QAAQ,OAAO,CAAC,CAAC;EACjB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM;EACN,QAAQ,OAAO,CAAC,CAAC;EACjB,KAAK;EACL,GAAG;EAKH,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,sBAAsB,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACxE,GAAG;EAEH,EAAE,WAAW,GAAG;EAChB,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;EAC7F,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;EAClG,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACjD,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACvD,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,CAAC,EAAE,2BAA2B,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,2CAA2C,CAAC,CAAC,CAAC;EAC7J,OAAO;EACP,KAAK;EACL,GAAG;EAEH,EAAE,MAAM,GAAG;EACX,IAAI,MAAM,QAAQ,GAAG;EACrB,MAAM,MAAM,EAAE,IAAI,CAAC,MAAM;EACzB,MAAM,SAAS,EAAE,IAAI,CAAC,SAAS;EAC/B,MAAM,QAAQ,EAAE,IAAI,CAAC,QAAQ;EAC7B,MAAM,aAAa,EAAE,IAAI,CAAC,aAAa;EACvC,MAAM,cAAc,EAAE,IAAI,CAAC,aAAa;EACxC,MAAM,SAAS,EAAE,IAAI,CAAC,SAAS;EAC/B,MAAM,WAAW,EAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI;EAChF,MAAM,UAAU,EAAE,IAAI,CAAC,UAAU;EACjC,KAAK,CAAC;EACN,IAAI,OAAO;EACX,MAAM,QAAQ;EACd,KAAK,CAAC;EACN,GAAG;EACH,CAAC;;EC5tBM,MAAM,eAAe,CAAC;EAS7B,EAAE,OAAO,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,gBAAgB,EAAE;EAC5D,IAAI,MAAM;EACV,MAAM,eAAe;EACrB,MAAM,eAAe;EACrB,MAAM,aAAa;EACnB,MAAM,aAAa;EACnB,MAAM,iBAAiB;EACvB,MAAM,SAAS;EACf,MAAM,iBAAiB;EACvB,MAAM,KAAK;EACX,MAAM,iBAAiB;EACvB,MAAM,eAAe;EACrB,MAAM,MAAM;EACZ,MAAM,mBAAmB;EACzB,MAAM,SAAS;EACf,MAAM,OAAO;EACb,MAAM,MAAM;EACZ,MAAM,UAAU;EAChB,MAAM,SAAS;EACf,MAAM,sBAAsB;EAC5B,MAAM,wBAAwB;EAC9B,MAAM,gBAAgB;EACtB,MAAM,aAAa;EACnB,MAAM,YAAY;EAClB,KAAK,GAAG,MAAM,CAAC;EAEf,IAAI,MAAM,aAAa,GAAG,IAAI,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;EAC5D,IAAI,MAAM,aAAa,GAAG,EAAE,CAAC;EAE7B,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,aAAa,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;EACjD,KAAK;EAEL,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,MAAM,cAAc,GAAG,eAAe,CAAC,CAAC,EAAC;EAC/C,MAAM,aAAa,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC;EAC/D,KAAK;EAEL,IAAI,MAAM,iBAAiB,GAAG,CAAC,YAAY,EAAE,KAAK,KAAK;EACvD,MAAM,OAAO,eAAe,CAAC,iBAAiB,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;EACpE,KAAK,CAAC;EAEN,IAAI,MAAM,kBAAkB,GAAG,CAAC,YAAY,EAAE,KAAK,EAAE,IAAI,KAAK;EAC9D,MAAM,eAAe,CAAC,kBAAkB,CAAC,YAAY,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;EACpE,KAAK,CAAC;EAEN,IAAI,MAAM,gBAAgB,GAAG,CAAC,YAAY,EAAE,GAAG,EAAE,cAAc,KAAK;EACpE,MAAM,OAAO,eAAe,CAAC,gBAAgB,CAAC,YAAY,EAAE,GAAG,EAAE,cAAc,CAAC,CAAC;EACjF,KAAK,CAAC;EAEN,IAAI,MAAM,2BAA2B,GAAG,CAAC,YAAY,KAAK;EAC1D,MAAM,OAAO,eAAe,CAAC,2BAA2B,CAAC,YAAY,CAAC,CAAC;EACvE,KAAK,CAAC;EAEN,IAAI,MAAM,0BAA0B,GAAG,CAAC,YAAY,EAAE,aAAa,KAAK;EACxE,MAAM,OAAO,eAAe,CAAC,0BAA0B,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;EACrF,KAAK,CAAC;EAEN,IAAI,MAAM,8BAA8B,GAAG,CAAC,YAAY,EAAE,YAAY,KAAK;EAC3E,MAAM,OAAO,eAAe,CAAC,8BAA8B,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;EACxF,KAAK,CAAC;EAEN,IAAI,MAAM,wBAAwB,GAAG,CAAC,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,cAAc,KAAK;EACxF,MAAM,eAAe,CAAC,kBAAkB,CAAC,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC;EACxF,KAAK,CAAC;EAEN,IAAI,MAAM,2BAA2B,GAAG,CAAC,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,aAAa,KAAK;EAC3G,MAAM,eAAe,CAAC,oBAAoB,CAAC,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,aAAa,CAAC,CAAC;EAC1G,KAAK,CAAC;EAEN,IAAI,MAAM,qBAAqB,GAAG,CAAC,kBAAkB,EAAE,YAAY,EAAE,YAAY,KAAK;EACtF,MAAM,OAAO,eAAe,CAAC,qBAAqB,CAAC,kBAAkB,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;EACnG,KAAK,CAAC;EAEN,IAAI,MAAM,cAAc,GAAG,CAAC,YAAY,EAAE,kBAAkB,EAAE,IAAI,KAAK;EACvE,MAAM,eAAe,CAAC,iBAAiB,CAAC,YAAY,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC;EAChF,KAAK,CAAC;EAEN,IAAI,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,UAAU,KAAK;EAClD,MAAM,MAAM,aAAa,GAAG,EAAE,CAAC;EAC/B,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,QAAQ,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EAC/C,OAAO;EACP,MAAM,MAAM,cAAc,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,WAAW,EAAE;EACnF,QAAQ,UAAU,EAAE,IAAI;EACxB,QAAQ,GAAG;EACX,QAAQ,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI;EACzB,QAAQ,aAAa;EACrB,QAAQ,gBAAgB;EACxB,QAAQ,2BAA2B;EACnC,QAAQ,0BAA0B;EAClC,QAAQ,8BAA8B;EACtC,QAAQ,iBAAiB;EACzB,QAAQ,kBAAkB;EAC1B,QAAQ,wBAAwB;EAChC,QAAQ,2BAA2B;EACnC,QAAQ,qBAAqB;EAC7B,QAAQ,cAAc;EACtB,QAAQ,YAAY;EACpB,OAAO,CAAC,CAAC,CAAC;EACV,MAAM,cAAc,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;EAC3C,MAAM,eAAe,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;EACtD,KAAK,CAAC;EAEN,IAAI,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;EACtC,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,gBAAgB;EACtB,MAAM,gBAAgB;EACtB,MAAM,2BAA2B;EACjC,MAAM,0BAA0B;EAChC,MAAM,8BAA8B;EACpC,MAAM,iBAAiB;EACvB,MAAM,kBAAkB;EACxB,MAAM,wBAAwB;EAC9B,MAAM,2BAA2B;EACjC,MAAM,qBAAqB;EAC3B,MAAM,cAAc;EACpB,MAAM,mBAAmB;EACzB,MAAM,SAAS;EACf,MAAM,SAAS;EACf,MAAM,aAAa;EACnB,MAAM,iBAAiB;EACvB,MAAM,KAAK;EACX,MAAM,iBAAiB;EACvB,MAAM,MAAM;EACZ,MAAM,OAAO;EACb,MAAM,gBAAgB;EACtB,MAAM,aAAa;EACnB,KAAK,EAAE,gBAAgB,IAAI,EAAE,CAAC,CAAC;EAE/B,IAAI,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,WAAW,EAAE;EAC3D,MAAM,YAAY,EAAE,IAAI;EACxB,MAAM,IAAI,EAAE,QAAQ;EACpB,MAAM,aAAa;EACnB,MAAM,aAAa;EACnB,MAAM,aAAa;EACnB,MAAM,iBAAiB;EACvB,MAAM,sBAAsB;EAC5B,MAAM,wBAAwB;EAC9B,KAAK,CAAC,CAAC;EAEP,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,aAAa,EAAE;EAC5D,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;EAChF,KAAK;EAEL,IAAI,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;EAE/D,IAAI,IAAI,aAAa,GAAG,IAAI,CAAC;EAC7B,IAAI,IAAI,SAAS,EAAE;EACnB,MAAM,aAAa,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,IAAI,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE;EACxE,QAAQ,UAAU,EAAE,EAAE,CAAC,UAAU;EACjC,QAAQ,aAAa,EAAE,EAAE,CAAC,aAAa;EACvC,QAAQ,MAAM;EACd,QAAQ,OAAO;EACf,QAAQ,SAAS;EACjB,QAAQ,aAAa;EACrB,QAAQ,iBAAiB;EACzB,QAAQ,mBAAmB;EAC3B,QAAQ,SAAS;EACjB,QAAQ,gBAAgB;EACxB,QAAQ,2BAA2B;EACnC,QAAQ,0BAA0B;EAClC,QAAQ,8BAA8B;EACtC,QAAQ,iBAAiB;EACzB,QAAQ,kBAAkB;EAC1B,QAAQ,wBAAwB;EAChC,QAAQ,2BAA2B;EACnC,QAAQ,qBAAqB;EAC7B,QAAQ,cAAc;EACtB,OAAO,CAAC,CAAC,CAAC;EACV,KAAK;EAEL,IAAI,IAAI,cAAc,GAAG,IAAI,CAAC;EAC9B,IAAI,IAAI,UAAU,EAAE;EACpB,MAAM,cAAc,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK;EACrD,QAAQ,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;EAC3C,QAAQ,OAAO,IAAI,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,WAAW,EAAE;EACvE,UAAU,IAAI;EACd,UAAU,WAAW,EAAE,IAAI;EAC3B,UAAU,YAAY,EAAE,KAAK;EAC7B,SAAS,CAAC,CAAC,CAAC;EACZ,OAAO,CAAC,CAAC;EACT,KAAK;EAEL,IAAI,MAAM,eAAe,GAAG,IAAI,eAAe,CAAC;EAChD,MAAM,MAAM;EACZ,MAAM,QAAQ;EACd,MAAM,aAAa;EACnB,MAAM,eAAe;EACrB,MAAM,cAAc;EACpB,KAAK,CAAC,CAAC;EAEP,IAAI,OAAO,eAAe,CAAC;EAC3B,GAAG;EAMH,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,QAAQ,GAAG,QAAQ,IAAI,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;EAClC,IAAI,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC;EACtC,IAAI,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC,aAAa,IAAI,EAAE,CAAC;EACtD,IAAI,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC,cAAc,IAAI,EAAE,CAAC;EACxD,IAAI,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC,eAAe,IAAI,EAAE,CAAC;EAC1D,IAAI,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,mBAAmB,GAAG,EAAE,CAAC;EAClC,IAAI,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAC5B,IAAI,IAAI,CAAC,wBAAwB,GAAG,EAAE,CAAC;EACvC,IAAI,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAE5B,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE;EACvB,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;EACjD,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,aAAa,EAAE;EAC5B,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC1D,QAAQ,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;EAC7E,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,cAAc,EAAE;EAC7B,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC3D,QAAQ,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;EAC/E,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,eAAe,EAAE;EAC9B,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC5D,QAAQ,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;EACvD,QAAQ,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;EAC3D,OAAO;EACP,KAAK;EACL,GAAG;EAQH,EAAE,eAAe,CAAC,YAAY,EAAE;EAChC,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;EAC3E,IAAI,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC;EACvD,IAAI,IAAI,YAAY,CAAC,YAAY,EAAE;EACnC,MAAM,IAAI,CAAC,QAAQ,GAAG,YAAY,CAAC;EACnC,KAAK;EACL,GAAG;EAaH,EAAE,kBAAkB,CAAC,YAAY,EAAE,OAAO,EAAE;EAC5C,IAAI,YAAY,GAAG,YAAY,IAAI,QAAQ,CAAC;EAC5C,IAAI,OAAO,GAAG,OAAO,IAAI,EAAE,CAAC;EAE5B,IAAI,IAAI,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE;EAC7D,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE;EAChD,QAAQ,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EACnC,OAAO;EACP,MAAM,OAAO,OAAO,CAAC;EACrB,KAAK;EAEL,IAAI,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;EACxD,IAAI,IAAI,YAAY,EAAE;EAEtB,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;EAC1D,MAAM,IAAI,aAAa,KAAK,CAAC,CAAC,EAAE;EAChC,QAAQ,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EACnC,QAAQ,YAAY,CAAC,QAAQ,EAAE,CAAC;EAChC,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,eAAe,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACtE,UAAU,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;EAC5E,SAAS;EACT,OAAO,MAAM;EAMb,QAAQ,MAAM,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1E,QAAQ,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;EAC5C,OAAO;EACP,KAAK;EAEL,IAAI,OAAO,OAAO,CAAC;EACnB,GAAG;EAOH,EAAE,kBAAkB,CAAC,YAAY,EAAE;EACnC,IAAI,OAAO,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EACvD,GAAG;EAOH,EAAE,aAAa,CAAC,YAAY,EAAE;EAC9B,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE;EACvB,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;EAC/B,KAAK;EACL,IAAI,IAAI,YAAY,EAAE;EACtB,MAAM,OAAO,IAAI,CAAC,8BAA8B,CAAC,IAAI,CAAC,kBAAkB,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;EACtG,KAAK;EACL,IAAI,OAAO,IAAI,CAAC,8BAA8B,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;EAC9E,GAAG;EAOH,EAAE,0BAA0B,CAAC,YAAY,EAAE;EAC3C,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;EACnB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EAClD,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;EACrD,MAAM,IAAI,IAAI,EAAE;EAChB,QAAQ,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;EAC/D,OAAO;EACP,KAAK;EACL,IAAI,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC1B,GAAG;EAOH,EAAE,8BAA8B,CAAC,YAAY,EAAE;EAC/C,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;EACnB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EAClD,MAAM,MAAM,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;EAC3C,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;EAC3E,MAAM,IAAI,aAAa,GAAG,CAAC,CAAC,EAAE;EAC9B,QAAQ,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;EAC7D,QAAQ,SAAS;EACjB,OAAO;EACP,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;EAClD,MAAM,IAAI,IAAI,EAAE;EAChB,QAAQ,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;EAClC,OAAO;EACP,KAAK;EACL,IAAI,OAAO,GAAG,CAAC;EACf,GAAG;EAEH,EAAE,MAAM,GAAG;EACX,IAAI,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,IAAI,IAAI;EAC7E,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EAC7D,MAAM,IAAI,WAAW,GAAG,CAAC,CAAC,EAAE;EAC5B,QAAQ,OAAO;EACf,UAAU,IAAI;EACd,UAAU,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,MAAM;EAC1D,SAAS,CAAC;EACV,OAAO,MAAM,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;EACzC,QAAQ,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;EAC/C,OAAO,MAAM;EACb,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,SAAS,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;EACxD,OAAO;EACP,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,QAAQ,CAAC,iBAAiB,EAAE,YAAY,EAAE;EAC5C,IAAI,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;EAC1B,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,iBAAiB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACvD,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;EACpD,MAAM,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,YAAY,CAAC,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;EAC3H,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,SAAS,CAAC,YAAY,EAAE;EAC1B,IAAI,IAAI,YAAY,EAAE;EACtB,MAAM,OAAO,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;EAC9F,KAAK;EACL,IAAI,OAAO,IAAI,CAAC,0BAA0B,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;EAC1E,GAAG;EAEH,EAAE,gBAAgB,CAAC,YAAY,EAAE,GAAG,EAAE,cAAc,EAAE;EACtD,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,gBAAgB,EAAE;EACvC,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,8CAA8C,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACrF,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,EAAE;EAC9C,MAAM,OAAO,IAAI,CAAC,+BAA+B,CAAC,YAAY,CAAC,CAAC;EAChE,KAAK,MAAM,IAAI,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE;EAC/C,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;EACnD,MAAM,IAAI,IAAI,CAAC,UAAU,EAAE;EAC3B,QAAQ,OAAO,IAAI,CAAC,UAAU,CAAC;EAC/B,OAAO,MAAM;EACb,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAE1D,UAAU,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,EAAE;EAG/C,YAAY,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;EAC7E,cAAc,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC;EACzC,cAAc,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACpD,gBAAgB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;EACtC,kBAAkB,IAAI,EAAE,cAAc,CAAC,IAAI;EAC3C,kBAAkB,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;EAC9B,kBAAkB,cAAc;EAChC,iBAAiB,CAAC,CAAC;EACnB,gBAAgB,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EACxE,gBAAgB,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC;EACvC,eAAe;EACf,cAAc,OAAO,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;EACrE,aAAa;EAEb,YAAY,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;EACzD,WAAW;EACX,SAAS;EAET,QAAQ,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;EAC9B,UAAU,IAAI,EAAE,cAAc,CAAC,IAAI;EACnC,UAAU,GAAG;EACb,UAAU,cAAc;EACxB,SAAS,CAAC,CAAC;EACX,QAAQ,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;EACnD,QAAQ,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC;EAC/B,QAAQ,OAAO,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EACtC,OAAO;EACP,KAAK;EAGL,IAAI,OAAO,IAAI,CAAC;EAsDhB,GAAG;EAEH,EAAE,YAAY,CAAC,YAAY,EAAE;EAC7B,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,CAEpC;EACL,IAAI,OAAO,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;EAC1C,GAAG;EAEH,EAAE,WAAW,CAAC,YAAY,EAAE;EAC5B,IAAI,OAAO,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC;EACnD,GAAG;EAEH,EAAE,kBAAkB,CAAC,YAAY,EAAE;EACnC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC1D,MAAM,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,EAAE,OAAO,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;EACxF,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,iBAAiB,CAAC,YAAY,EAAE;EAClC,IAAI,OAAO,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC;EAC1D,GAAG;EAEH,EAAE,+BAA+B,CAAC,YAAY,EAAE;EAChD,IAAI,IAAI,cAAc,GAAG,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;EAC/D,IAAI,IAAI,cAAc,EAAE;EACxB,MAAM,OAAO,cAAc,CAAC,UAAU,CAAC;EACvC,KAAK;EACL,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,gBAAgB,GAAG,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;EACnE,GAAG;EAEH,EAAE,2BAA2B,CAAC,YAAY,EAAE;EAC5C,IAAI,IAAI,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,EAAE;EAC9C,MAAM,OAAO,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,aAAa,CAAC;EACjE,KAAK,MAAM,IAAI,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE;EAC/C,MAAM,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,aAAa,CAAC;EAC3D,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,0BAA0B,CAAC,YAAY,EAAE,aAAa,EAAE;EAC1D,IAAI,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;EACxE,GAAG;EAEH,EAAE,8BAA8B,CAAC,YAAY,EAAE,YAAY,EAAE;EAC7D,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE;EACzC,MAAM,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;EAC5C,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,EAAE;EAC7C,MAAM,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;EAClE,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE;EACpB,QAAQ,OAAO,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;EAClD,OAAO,MAAM;EACb,QAAQ,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;EACxD,OAAO;EACP,KAAK,MAAM;EACX,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;EACnD,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EACtE,MAAM,IAAI,CAAC,eAAe,EAAE;EAC5B,QAAQ,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;EACtD,OAAO;EACP,MAAM,OAAO,IAAI,CAAC,8BAA8B,CAAC,eAAe,CAAC,YAAY,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;EAC7G,KAAK;EACL,GAAG;EAEH,EAAE,iBAAiB,CAAC,YAAY,EAAE,CAAC,EAAE;EACrC,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,OAAO,KAAK,CAAC;EACtD,IAAI,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;EACnD,IAAI,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;EACpC,GAAG;EAEH,EAAE,kBAAkB,CAAC,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,cAAc,EAAE;EACpE,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,OAAO;EAChD,IAAI,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;EACnD,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE;EAClC,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC;EAC7C,KAAK;EACL,GAAG;EAEH,EAAE,oBAAoB,CAAC,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,aAAa,EAAE;EACtF,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,EAAE,OAAO;EACtD,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC;EACvD,IAAI,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE;EAC/B,MAAM,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAChC,KAAK;EACL,IAAI,MAAM,kBAAkB,GAAG,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;EACjE,IAAI,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,kBAAkB,CAAC,EAAE;EACnD,MAAM,IAAI,CAAC,eAAe,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC;EACpD,KAAK;EACL,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;EACxB,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG;EAC9C,MAAM,YAAY;EAClB,MAAM,YAAY;EAClB,MAAM,kBAAkB;EACxB,MAAM,kBAAkB;EACxB,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,qBAAqB,CAAC,kBAAkB,EAAE,YAAY,EAAE,YAAY,EAAE;EACxE,IAAI,IAAI,kBAAkB,KAAK,YAAY,EAAE,OAAO,YAAY,CAAC;EACjE,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,OAAO,IAAI,CAAC;EACrD,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;EACjD,IAAI,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;EACvE,IAAI,IAAI,CAAC,eAAe,EAAE,OAAO,IAAI,CAAC;EACtC,IAAI,IAAI,eAAe,CAAC,kBAAkB,KAAK,YAAY,EAAE,OAAO,IAAI,CAAC;EACzE,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;EAC3B,IAAI,IAAI,kBAAkB,KAAK,YAAY,EAAE;EAC7C,MAAM,OAAO,IAAI,CAAC,qBAAqB,CAAC,kBAAkB,EAAE,eAAe,CAAC,YAAY,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;EACxH,KAAK;EACL,IAAI,OAAO,eAAe,CAAC,YAAY,CAAC;EACxC,GAAG;EAEH,EAAE,iBAAiB,CAAC,YAAY,EAAE,kBAAkB,EAAE,IAAI,EAAE;EAC5D,IAAI,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAAC,YAAY,CAAC,EAAE;EACtD,MAAM,IAAI,CAAC,wBAAwB,CAAC,YAAY,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC;EAC9D,MAAM,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC;EAC5C,KAAK;EACL,IAAI,IAAI,CAAC,wBAAwB,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;EACxE,IAAI,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAChD,GAAG;EAEH,EAAE,mBAAmB,GAAG;EACxB,IAAI,OAAO,IAAI,CAAC,QAAQ,CAAC,UAAU,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;EAChF,GAAG;EAEH,EAAE,sBAAsB,CAAC,KAAK,EAAE;EAChC,IAAI,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;EACrD,IAAI,IAAI,MAAM,GAAG,KAAK,CAAC;EACvB,IAAI,KAAK,IAAI,iBAAiB,GAAG,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,EAAE,iBAAiB,EAAE,EAAE;EACjH,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC;EAC1E,MAAM,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,aAAa,CAAC,IAAI,EAAE;EAC/D,QAAQ,MAAM,GAAG,IAAI,CAAC;EACtB,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,MAAM,EAAE;EACjB,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,UAAU,GAAG,aAAa,CAAC,IAAI,EAAE,uBAAuB,CAAC,CAAC,CAAC;EAClF,KAAK;EACL,IAAI,OAAO,aAAa,CAAC,UAAU,IAAI,aAAa,CAAC,OAAO,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAC;EACvF,GAAG;EAEH,EAAE,cAAc,GAAG;EACnB,IAAI,MAAM,MAAM,GAAG;EACnB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;EACpE,KAAK,CAAC;EACN,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;EAC7D,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC1C,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;EACnC,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;EAC1D,MAAM,MAAM,CAAC,YAAY,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;EACpE,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,CAAC;;ECvpBM,MAAM,cAAc,CAAC;EAC5B,EAAE,WAAW,CAAC,GAAG,EAAE;EACnB,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;EACvB,IAAI,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAC5B,IAAI,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;EAC3B,IAAI,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;EACxB,IAAI,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;EAC/B,IAAI,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;EAC5B,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACnB,GAAG;EAEH,EAAE,IAAI,cAAc,GAAG;EACvB,IAAI,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC;EAC1G,GAAG;EAEH,EAAE,UAAU,CAAC,GAAG,EAAE;EAClB,IAAI,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;EAC9D,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EACnC,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EAC1C,IAAI,GAAG,EAAE,CAAC;EACV,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,CAAC;EAC/B,GAAG;EAMH,EAAE,IAAI,CAAC,GAAG,EAAE;EACZ,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;EAC5B,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC3C,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1B,OAAO;EACP,MAAM,OAAO;EACb,KAAK;EACL,IAAI,QAAQ,GAAG,CAAC,IAAI;EACpB,MAAM,KAAK,SAAS;EACpB,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC5B,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM;EAC9B,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC9B,SAAS,CAAC,CAAC;EACX,QAAQ,MAAM;EACd,MAAM,KAAK,sBAAsB,CAAC;EAClC,MAAM,KAAK,mBAAmB;EAC9B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC5B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;EAC7B,QAAQ,MAAM;EACd,MAAM,KAAK,kBAAkB;EAC7B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC5B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;EAC7B,QAAQ,MAAM;EACd,MAAM,KAAK,kBAAkB,CAAC;EAC9B,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAChC,QAAQ,MAAM;EACd,MAAM,KAAK,qBAAqB;EAChC,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;EACpC,QAAQ,MAAM;EACd,MAAM,KAAK,oBAAoB;EAC/B,QAAQ,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;EACxC,QAAQ,MAAM,WAAW,GAAG;EAC5B,UAAU,GAAG,EAAE,GAAG;EAClB,UAAU,OAAO,EAAE,cAAc;EACjC,UAAU,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI;EAC3B,UAAU,MAAM,EAAE,aAAa;EAC/B,UAAU,YAAY,EAAE,IAAI,CAAC,UAAU;EACvC,UAAU,UAAU,EAAE,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC;EACrF,SAAS,CAAC;EACV,QAAQ,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC;EAClD,QAAQ,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;EAC5C,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;EAC1B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC5B,QAAQ,MAAM;EACd,MAAM,KAAK,oBAAoB,CAAC;EAChC,MAAM,KAAK,qBAAqB;EAChC,QAAQ,IAAI,IAAI,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE;EAC/C,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC9B,SAAS,MAAM;EACf,UAAU,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACnC,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,aAAa;EACxB,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC5B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;EAClC,QAAQ,IAAI,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;EACpD,QAAQ,MAAM;EACd,MAAM,KAAK,cAAc;EACzB,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM;EAC9B,UAAU,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EACjC,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC9B,UAAU,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;EAClC,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC9B,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;EAChC,UAAU,IAAI,CAAC,UAAU,CAAC,MAAM;EAChC,YAAY,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAChC,WAAW,CAAC,CAAC;EACb,SAAS,CAAC,CAAC;EACX,QAAQ,MAAM;EACd,MAAM,KAAK,kBAAkB,CAAC;EAC9B,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM;EAC9B,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC9B,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC9B,SAAS,CAAC,CAAC;EACX,QAAQ,MAAM;EACd,MAAM,KAAK,YAAY;EACvB,QAAQ,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;EAC9B,UAAU,OAAO,EAAE,IAAI,CAAC,cAAc;EACtC,UAAU,GAAG;EACb,SAAS,CAAC,CAAC;EACX,QAAQ,MAAM;EACd,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACxC,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAChC,QAAQ,MAAM;EACd,MAAM,KAAK,kBAAkB;EAC7B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;EAC9B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAChC,QAAQ,MAAM;EACd,MAAM,KAAK,qBAAqB;EAChC,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;EAClC,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;EAChC,UAAU,OAAO,EAAE,IAAI,CAAC,cAAc;EACtC,UAAU,GAAG;EACb,SAAS,CAAC,CAAC;EACX,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;EACjC,QAAQ,MAAM;EACd,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAChC,QAAQ,MAAM;EACd,MAAM,KAAK,uBAAuB;EAClC,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC5B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;EACjC,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;EAClC,QAAQ,MAAM;EACd,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;EACpC,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;EAC7B,QAAQ,MAAM;EACd,MAAM,KAAK,YAAY;EACvB,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC5B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;EAClC,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC5B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;EAC7B,QAAQ,MAAM;EACd,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,mBAAmB,CAAC;EAC/B,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,mBAAmB;EAC9B,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,gBAAgB,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EACxD,KAAK;EACL,GAAG;EACH,CAAC;;ECpJM,MAAM,YAAY,CAAC;EAM1B,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE;EAChC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE;EAClC,MAAM,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;EACrD,KAAK;EACL,IAAI,QAAQ,GAAG,QAAQ,IAAI,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;EACzB,IAAI,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,OAAO,MAAM,KAAK,QAAQ,GAAG,QAAQ,CAAC,YAAY;EAClE,MAAM,QAAQ;EACd,OAAO,QAAQ,CAAC,IAAI,IAAI,yBAAyB,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;EAClE,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;EACxB,IAAI,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAC5B,IAAI,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;EAChC,IAAI,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;EAC9B,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;EAC7B,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;EACtB,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;EAC7B,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAC1B,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;EAC5B,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;EACzB,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;EAC9B,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;EACrB,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;EAClC,IAAI,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;EACnC,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;EACjC,IAAI,IAAI,CAAC,2BAA2B,GAAG,IAAI,CAAC;EAC5C,IAAI,IAAI,CAAC,8BAA8B,GAAG,IAAI,CAAC;EAC/C,IAAI,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC;EACzC,IAAI,IAAI,CAAC,4BAA4B,GAAG,IAAI,CAAC;EAC7C,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;EACjC,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;EAC/B,IAAI,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;EACpC,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAC1B,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;EAClC,IAAI,IAAI,CAAC,aAAa,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,GAAG,0BAA0B,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;EAC5G,IAAI,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAC5B,IAAI,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAC5B,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;EAClC,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EAC3B,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;EACrB,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;EACxB,IAAI,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC;EACvC,IAAI,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC;EACzC,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;EAC9B,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;EACjC,IAAI,IAAI,CAAC,oBAAoB,GAAG,KAAK,CAAC;EACtC,IAAI,IAAI,CAAC,0BAA0B,GAAG,IAAI,CAAC;EAC3C,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;EAE7B,IAAI,IAAI,QAAQ,EAAE;EAClB,MAAM,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE;EAChC,QAAQ,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS;EAClD,QAAQ,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS;EAC9C,QAAQ,IAAI,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;EAC9B,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;EAE3B,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;EACpB,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;EACxB,IAAI,IAAI,CAAC,sBAAsB,GAAG,EAAE,CAAC;EACrC,GAAG;EAEH,EAAE,QAAQ,GAAG;EACb,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;EACtD,MAAM,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;EAClD,KAAK;EAEL,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;EACrD,MAAM,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;EAC3D,KAAK;EAEL,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;EACpB,MAAM,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;EACpD,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE;EAClG,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,uBAAuB,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;EACtH,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;EAChC,MAAM,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;EACvD,KAAK;EACL,GAAG;EAMH,EAAE,oBAAoB,CAAC,IAAI,EAAE;EAC7B,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,KAAK,CAAC;EACtC,IAAI,OAAO,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;EAC/C,GAAG;EAEH,EAAE,OAAO,CAAC,YAAY,EAAE;EACxB,IAAI,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,KAAK,OAAO,CAAC;EACpF,GAAG;EAEH,EAAE,SAAS,CAAC,KAAK,EAAE;EACnB,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EAC5B,GAAG;EAEH,EAAE,QAAQ,CAAC,KAAK,EAAE;EAClB,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,EAAE;EAC9B,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,gBAAgB,GAAG,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;EAC5E,KAAK;EACL,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;EACtB,GAAG;EAEH,EAAE,OAAO,CAAC,KAAK,EAAE;EACjB,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC;EAChC,GAAG;EAEH,EAAE,IAAI,KAAK,GAAG;EACd,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;EAC/C,GAAG;EAaH,EAAE,yBAAyB,CAAC,GAAG,EAAE;EACjC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE;EACnC,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC;EACtB,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,gBAAgB,EAAE;EAC9C,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK;EAEL,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,kBAAkB,EAAE;EACzC,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE;EAEtC,QAAQ,IAAI,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;EAC7E,UAAU,OAAO,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC9D,SAAS;EAET,QAAQ;EACR,UAAU,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,MAAM,CAAC;EACpD,UAAU,GAAG;EACb,UAAU,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,QAAQ,CAAC;EACtD,UAAU;EACV,OAAO;EACP,KAAK;EAGL,IAAI,IAAI,GAAG,CAAC,cAAc,CAAC,aAAa,CAAC,EAAE;EAC3C,MAAM,MAAM,eAAe,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;EACjD,MAAM,IAAI,eAAe,CAAC,IAAI,KAAK,SAAS,IAAI,eAAe,CAAC,KAAK,KAAK,CAAC,IAAI,GAAG,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE;EAC7G,QAAQ,OAAO,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;EAClE,OAAO;EACP,KAAK;EAGL,IAAI,MAAM,IAAI,CAAC,cAAc,CAAC,mCAAmC,EAAE,GAAG,CAAC,CAAC;EACxE,GAAG;EAUH,EAAE,QAAQ,CAAC,QAAQ,EAAE;EACrB,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE;EAClB,MAAM,OAAO,IAAI,CAAC,GAAG,CAAC;EACtB,KAAK;EACL,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE;EACzC,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACzC,MAAM,OAAO,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;EACpC,KAAK;EAEL,IAAI,MAAM,MAAM,GAAG,QAAQ,IAAI,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,GAAGC,YAAK;EACxF,IAAI,IAAI,QAAQ,KAAK,IAAI,EAAE;EAC3B,MAAM,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;EAClD,KAAK;EAEL,IAAI,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,aAAa,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE;EACxF,MAAM,SAAS,EAAE,IAAI;EACrB,KAAK,CAAC,CAAC,CAAC;EAER,IAAI,MAAM,WAAW,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;EACzD,IAAI,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;EAEvC,IAAI,IAAI,CAAC,GAAG,EAAE;EACd,MAAM,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;EACjD,KAAK;EAEL,IAAI,OAAO,IAAI,CAAC,GAAG,GAAG,WAAW,CAAC;EAClC,GAAG;EAEH,EAAE,gBAAgB,CAAC,GAAG,EAAE;EACxB,IAAI,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC;EACtG,IAAI,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;EAC7B,IAAI,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;EACnC,IAAI,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;EACvC,IAAI,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;EAC3B,IAAI,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;EAC/B,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,MAAM,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;EAC1C,MAAM,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,WAAW,CAAC;EACnF,MAAM,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC;EAC3B,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EACtD,MAAM,IAAI,SAAS,GAAG,IAAI,CAAC;EAE3B,MAAM,IAAI,YAAY,EAAE;EACxB,QAAQ,SAAS,GAAG,SAAS,CAAC;EAC9B,OAAO,MAAM;EACb,QAAQ,IAAI,IAAI,EAAE;EAClB,UAAU,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EAC9C,UAAU,QAAQ,QAAQ;EAC1B,YAAY,KAAK,SAAS,CAAC;EAC3B,YAAY,KAAK,OAAO,CAAC;EACzB,YAAY,KAAK,QAAQ;EACzB,cAAc,IAAI,IAAI,CAAC,IAAI,KAAK,kBAAkB,EAAE;EACpD,gBAAgB,SAAS,GAAG,QAAQ,CAAC;EACrC,eAAe,MAAM;EACrB,gBAAgB,SAAS,GAAG,QAAQ,CAAC;EACrC,eAAe;EACf,cAAc,MAAM;EACpB,YAAY,KAAK,gBAAgB;EACjC,cAAc,SAAS,GAAG,QAAQ,CAAC;EACnC,cAAc,MAAM;EACpB,YAAY;EACZ,cAAc,SAAS,GAAG,QAAQ,CAAC;EACnC,WAAW;EACX,SAAS;EACT,OAAO;EACP,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;EAC7B,QAAQ,SAAS;EACjB,QAAQ,YAAY;EACpB,QAAQ,MAAM,EAAE,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC;EACrD,QAAQ,GAAG;EACX,QAAQ,IAAI;EACZ,QAAQ,OAAO;EACf,QAAQ,MAAM;EACd,QAAQ,UAAU;EAClB,OAAO,CAAC,CAAC;EACT,KAAK;EAEL,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC/C,MAAM,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1C,KAAK;EACL,GAAG;EAEH,EAAE,cAAc,CAAC,GAAG,EAAE;EACtB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACtD,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;EAC7C,MAAM,IAAI,GAAG,KAAK,UAAU,CAAC,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;EACjF,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC3D,UAAU,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;EACnD,UAAU,IAAI,WAAW,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,IAAI,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;EAC/G,YAAY,OAAO,WAAW,CAAC;EAC/B,WAAW;EACX,SAAS;EACT,OAAO;EACP,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,eAAe,CAAC,GAAG,EAAE;EACvB,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE;EACnC,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;EAC7D,KAAK;EACL,IAAI,IAAI,IAAI,GAAG,IAAI,CAAC;EACpB,IAAI,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC/D,IAAI,IAAI,aAAa,KAAK,CAAC,CAAC,EAAE;EAC9B,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;EACnD,MAAM,IAAI,WAAW,EAAE;EACvB,QAAQ,OAAO,WAAW,CAAC,SAAS,CAAC;EACrC,OAAO;EACP,KAAK,MAAM;EACX,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;EAC7D,MAAM,IAAI,YAAY,EAAE;EACxB,QAAQ,IAAI,GAAG,YAAY,CAAC;EAC5B,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,oBAAoB,EAAE;EAC5C,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,eAAe,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;EAC1D,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,aAAa,CAAC,IAAI,EAAE;EACtB,IAAI,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EAC7C,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,sBAAsB,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;EACzD,KAAK;EACL,IAAI,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;EAC/B,GAAG;EAEH,EAAE,eAAe,CAAC,YAAY,EAAE;EAChC,IAAI,IAAI,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,EAAE;EAC1C,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;EACpD,MAAM,IAAI,IAAI,KAAK,OAAO,EAAE;EAC5B,QAAQ,OAAO,QAAQ,CAAC;EACxB,OAAO,MAAM;EACb,QAAQ,OAAO,IAAI,CAAC;EACpB,OAAO;EACP,KAAK;EACL,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,mBAAmB,GAAG,YAAY,EAAE,cAAc,CAAC,CAAC,CAAC;EAC1E,GAAG;EAEH,EAAE,QAAQ,GAAG;EACb,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE,OAAO,IAAI,CAAC,OAAO,CAAC;EAC1C,IAAI,OAAO,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;EAC/E,GAAG;EAEH,EAAE,MAAM,GAAG;EACX,IAAI,MAAM,QAAQ,GAAG;EACrB,MAAM,MAAM,EAAE,IAAI,CAAC,MAAM;EACzB,MAAM,IAAI,EAAE,IAAI,CAAC,IAAI;EACrB,MAAM,SAAS,EAAE,IAAI,CAAC,SAAS;EAC/B,MAAM,aAAa,EAAE,IAAI,CAAC,aAAa;EACvC,MAAM,YAAY,EAAE,IAAI,CAAC,YAAY;EACrC,MAAM,WAAW,EAAE,IAAI,CAAC,WAAW;EACnC,MAAM,KAAK,EAAE,IAAI,CAAC,KAAK;EACvB,MAAM,MAAM,EAAE,IAAI,CAAC,MAAM;EACzB,MAAM,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;EAC/C,MAAM,aAAa,EAAE,IAAI,CAAC,aAAa;EACvC,MAAM,aAAa,EAAE,IAAI,CAAC,aAAa;EACvC,MAAM,aAAa,EAAE,IAAI,CAAC,aAAa;EACvC,MAAM,UAAU,EAAE,IAAI,CAAC,UAAU;EACjC,MAAM,sBAAsB,EAAE,IAAI,CAAC,sBAAsB;EACzD,MAAM,wBAAwB,EAAE,IAAI,CAAC,wBAAwB;EAC7D,KAAK,CAAC;EAEN,IAAI,OAAO;EACX,MAAM,GAAG,EAAE,IAAI,CAAC,GAAG;EACnB,MAAM,QAAQ;EACd,KAAK,CAAC;EACN,GAAG;EAOH,EAAE,OAAO,CAAC,GAAG,EAAE;EACf,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;EAC5B,MAAM,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;EAC/C,KAAK;EACL,IAAI,QAAQ,GAAG,CAAC,IAAI;EACpB,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EACtC,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;EACjD,MAAM,KAAK,SAAS;EACpB,QAAQ,MAAM,UAAU,GAAG,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;EACrD,QAAQ,IAAI,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE;EAC3C,UAAU,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;EAC/C,SAAS;EACT,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;EACzC,UAAU,OAAO,gBAAgB,CAAC;EAClC,SAAS,MAAM,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI,IAAI,GAAG,CAAC,KAAK,KAAK,KAAK,EAAE;EAC9D,UAAU,OAAO,SAAS,CAAC;EAC3B,SAAS,MAAM;EACf,UAAU,OAAO,QAAQ,CAAC;EAC1B,SAAS;EACT,QAAQ,KAAK,sBAAsB;EACnC,UAAU,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EACxC,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,IAAI,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE;EAC3C,YAAY,OAAO,QAAQ,CAAC;EAC5B,WAAW;EACX,UAAU,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE;EAC/C,YAAY,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,oBAAoB,IAAI,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE;EACrI,cAAc,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;EAC3G,cAAc,IAAI,CAAC,0BAA0B,CAAC,YAAY,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;EAC3E,cAAc,OAAO,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;EACpE,aAAa;EACb,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;EACtE,WAAW;EACX,UAAU,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE;EAC7C,YAAY,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;EACjD,YAAY,IAAI,CAAC,0BAA0B,CAAC,YAAY,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;EACzE,YAAY,OAAO,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;EAClE,WAAW;EACX,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,wBAAwB,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;EACnF,QAAQ,KAAK,kBAAkB;EAE/B,UAAU,QAAQ,GAAG,CAAC,QAAQ;EAC9B,YAAY,KAAK,GAAG,CAAC;EACrB,YAAY,KAAK,GAAG;EACpB,cAAc,IAAI,IAAI,CAAC,0BAA0B,EAAE;EACnD,gBAAgB,OAAO,QAAQ,CAAC;EAChC,eAAe,MAAM;EACrB,gBAAgB,MAAM;EACtB,eAAe;EACf,cAAc,KAAK,GAAG,CAAC;EACvB,cAAc,KAAK,GAAG;EACtB,gBAAgB,OAAO,SAAS,CAAC;EACjC,cAAc,KAAK,GAAG,CAAC;EACvB,cAAc,KAAK,GAAG,CAAC;EACvB,cAAc,KAAK,GAAG,CAAC;EACvB,cAAc,KAAK,IAAI,CAAC;EACxB,cAAc,KAAK,IAAI,CAAC;EACxB,cAAc,KAAK,KAAK;EACxB,gBAAgB,OAAO,SAAS,CAAC;EACjC,WAAW;EACX,UAAU,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC9C,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC,yBAAyB,CAAC,EAAE,OAAO,IAAI,CAAC;EACnE,UAAU,IAAI,IAAI,KAAK,gBAAgB,EAAE;EACzC,YAAY,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;EACtD,YAAY,IAAI,SAAS,KAAK,gBAAgB,EAAE;EAChD,cAAc,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,EAAE;EAC5C,gBAAgB,OAAO,SAAS,CAAC;EACjC,eAAe,MAAM;EACrB,gBAAgB,OAAO,OAAO,CAAC;EAC/B,eAAe;EACf,aAAa;EACb,YAAY,OAAO,SAAS,CAAC;EAC7B,WAAW;EACX,UAAU,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;EAC7C,QAAQ,KAAK,kBAAkB;EAC/B,UAAU,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC5C,QAAQ,KAAK,iBAAiB;EAC9B,UAAU,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,EAAE;EACpC,YAAY,OAAO,SAAS,CAAC;EAC7B,WAAW;EACX,UAAU,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC5C,QAAQ,KAAK,qBAAqB,EAAE;EACpC,UAAU,MAAM,YAAY,GAAG,GAAG,CAAC,YAAY,CAAC;EAChD,UAAU,IAAI,QAAQ,CAAC;EACvB,UAAU,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACxD,YAAY,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;EAChD,YAAY,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;EACjD,WAAW;EACX,UAAU,IAAI,CAAC,QAAQ,EAAE;EACzB,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,mCAAmC,CAAC,EAAE,GAAG,CAAC,CAAC;EAClF,WAAW;EACX,UAAU,OAAO,QAAQ,CAAC;EAC1B,SAAS;EACT,QAAQ,KAAK,oBAAoB;EACjC,UAAU,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;EAC1D,UAAU,IAAI,CAAC,WAAW,EAAE;EAC5B,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,yBAAyB,CAAC,EAAE,GAAG,CAAC,CAAC;EACxE,WAAW;EAEX,UAAU,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE;EACtC,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,mCAAmC,CAAC,EAAE,GAAG,CAAC,CAAC;EAClF,WAAW;EAEX,UAAU,OAAO,WAAW,CAAC,SAAS,CAAC;EACvC,QAAQ,KAAK,YAAY;EACzB,UAAU,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,EAAE;EACvC,YAAY,OAAO,QAAQ,CAAC;EAC5B,WAAW;EACX,UAAU,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE;EACvC,YAAY,MAAM,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;EAC7D,YAAY,IAAI,SAAS,KAAK,OAAO,EAAE;EACvC,cAAc,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;EACrD,cAAc,IAAI,CAAC,IAAI,EAAE;EACzB,gBAAgB,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,mCAAmC,CAAC,EAAE,GAAG,CAAC,CAAC;EACtF,eAAe;EACf,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,WAAW;EACX,UAAU,MAAM,MAAM,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;EACxD,UAAU,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE;EACrC,YAAY,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;EAC7C,WAAW;EACX,UAAU,OAAO,IAAI,CAAC;EACtB,QAAQ,KAAK,iBAAiB;EAC9B,UAAU,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC5C,QAAQ,KAAK,kBAAkB;EAC/B,UAAU,IAAI,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE;EAC3C,YAAY,QAAQ,GAAG,CAAC,QAAQ,CAAC,IAAI;EACrC,cAAc,KAAK,MAAM;EACzB,gBAAgB,OAAO,SAAS,CAAC;EACjC,cAAc,KAAK,OAAO;EAC1B,gBAAgB,OAAO,SAAS,CAAC;EACjC,cAAc,KAAK,OAAO;EAC1B,gBAAgB,OAAO,SAAS,CAAC;EACjC,aAAa;EACb,YAAY,OAAO,QAAQ,CAAC;EAC5B,WAAW;EACX,UAAU,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE;EACvC,YAAY,MAAM,iBAAiB,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;EACrE,YAAY,QAAQ,iBAAiB;EACrC,cAAc,KAAK,SAAS;EAC5B,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;EAC5E,cAAc,KAAK,WAAW;EAC9B,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;EACnF,cAAc,KAAK,aAAa;EAChC,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;EAC1F,cAAc,KAAK,eAAe;EAClC,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;EACjG,cAAc,KAAK,oBAAoB,CAAC;EACxC,cAAc,KAAK,mBAAmB;EACtC,gBAAgB,OAAO,SAAS,CAAC;EACjC,cAAc,KAAK,mBAAmB;EACtC,gBAAgB,OAAO,IAAI,CAAC,aAAa,GAAG,SAAS,GAAG,gBAAgB,CAAC;EACzE,cAAc,KAAK,sBAAsB;EACzC,gBAAgB,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;EAC/D,cAAc,KAAK,wBAAwB;EAC3C,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;EAC1F,cAAc,KAAK,0BAA0B;EAC7C,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;EACjG,cAAc,KAAK,4BAA4B;EAC/C,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;EACxG,cAAc,KAAK,8BAA8B;EACjD,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;EAC/G,cAAc,KAAK,QAAQ;EAC3B,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;EACpE,cAAc,KAAK,UAAU;EAC7B,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;EACpE,cAAc,KAAK,YAAY;EAC/B,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;EACpE,cAAc,KAAK,aAAa;EAChC,gBAAgB,IAAI,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE;EACjD,kBAAkB,OAAO,QAAQ,CAAC;EAClC,iBAAiB;EACjB,gBAAgB,QAAQ,GAAG,CAAC,QAAQ,CAAC,IAAI;EACzC,kBAAkB,KAAK,GAAG;EAC1B,oBAAoB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;EAChF,kBAAkB,KAAK,GAAG;EAC1B,oBAAoB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;EAChF,kBAAkB,KAAK,GAAG;EAC1B,oBAAoB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;EAChF,kBAAkB,KAAK,GAAG;EAC1B,oBAAoB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;EAChF,iBAAiB;EACjB,gBAAgB,KAAK,MAAM;EAC3B,kBAAkB,OAAO,QAAQ,CAAC;EAClC,aAAa;EACb,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,oCAAoC,EAAE,GAAG,CAAC,CAAC;EACjF,WAAW;EACX,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,oCAAoC,EAAE,GAAG,CAAC,CAAC;EAC/E,QAAQ,KAAK,uBAAuB;EACpC,UAAU,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;EAC9C,QAAQ,KAAK,qBAAqB,CAAC;EACnC,QAAQ,KAAK,oBAAoB;EACjC,UAAU,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC3D,UAAU,IAAI,UAAU,EAAE;EAC1B,YAAY,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;EAC5C,WAAW;EACX,UAAU,OAAO,IAAI,CAAC;EACtB,QAAQ,KAAK,aAAa;EAC1B,UAAU,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;EAC9C,QAAQ;EACR,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,wBAAwB,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;EACnF,KAAK;EACL,GAAG;EAEH,EAAE,0BAA0B,CAAC,YAAY,EAAE,IAAI,EAAE;EAEjD,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC1C,MAAM,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,SAAS;EAC7D,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EACzC,MAAM,IAAI,CAAC,IAAI,EAAE;EACjB,QAAQ,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,yBAAyB,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC5E,OAAO;EACP,MAAM,IAAI,CAAC,kBAAkB,CAAC,YAAY,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;EACrD,KAAK;EACL,GAAG;EAEH,EAAE,iBAAiB,CAAC,GAAG,EAAE;EACzB,IAAI,MAAM,cAAc,GAAG;EAC3B,MAAM,GAAG;EACT,MAAM,IAAI;EACV,MAAM,OAAO;EACb,MAAM,SAAS;EACf,MAAM,KAAK;EACX,MAAM,MAAM;EACZ,MAAM,OAAO;EACb,MAAM,QAAQ;EACd,KAAK,CAAC;EACN,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,kBAAkB;EAC1C,MAAM,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,YAAY;EACpD,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM;EAChC,MAAM,GAAG,CAAC,QAAQ;EAClB,MAAM,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY;EACxC,MAAM,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;EACrD,GAAG;EAEH,EAAE,iBAAiB,CAAC,GAAG,EAAE;EACzB,IAAI,MAAM,aAAa,GAAG;EAC1B,MAAM,KAAK;EACX,MAAM,MAAM;EACZ,MAAM,MAAM;EACZ,MAAM,MAAM;EACZ,MAAM,OAAO;EACb,MAAM,MAAM;EACZ,MAAM,KAAK;EACX,MAAM,KAAK;EACX,MAAM,OAAO;EACb,MAAM,KAAK;EACX,MAAM,MAAM;EACZ,MAAM,KAAK;EACX,MAAM,KAAK;EACX,MAAM,KAAK;EACX,MAAM,QAAQ;EACd,MAAM,OAAO;EACb,MAAM,MAAM;EACZ,MAAM,KAAK;EACX,MAAM,MAAM;EACZ,MAAM,KAAK;EACX,KAAK,CAAC;EACN,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,gBAAgB;EACxC,MAAM,GAAG,CAAC,MAAM;EAChB,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,kBAAkB;EAC5C,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM;EACvB,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,YAAY;EAC7C,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM;EACvC,MAAM,GAAG,CAAC,MAAM,CAAC,QAAQ;EACzB,MAAM,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY;EAC/C,MAAM,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;EAC3D,GAAG;EAEH,EAAE,aAAa,CAAC,GAAG,EAAE;EACrB,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,kBAAkB,CAAC;EACxE,GAAG;EAEH,EAAE,MAAM,CAAC,GAAG,EAAE;EACd,IAAI,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;EAC9D,GAAG;EAEH,EAAE,kBAAkB,CAAC,YAAY,EAAE;EACnC,IAAI,OAAO,YAAY,IAAI,YAAY,CAAC,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;EAC3G,GAAG;EASH,EAAE,eAAe,CAAC,GAAG,EAAE,YAAY,EAAE,SAAS,EAAE;EAChD,IAAI,IAAI,CAAC,YAAY,EAAE;EACvB,MAAM,YAAY,GAAG,EAAE,CAAC;EACxB,KAAK;EACL,IAAI,IAAI,CAAC,GAAG,EAAE,OAAO,IAAI,CAAC;EAC1B,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;EAC5B,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC3C,QAAQ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAC9D,OAAO;EACP,MAAM,OAAO,YAAY,CAAC;EAC1B,KAAK;EACL,IAAI,QAAQ,GAAG,CAAC,IAAI;EACpB,MAAM,KAAK,sBAAsB;EACjC,QAAQ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAChE,QAAQ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EACjE,QAAQ,OAAO,YAAY,CAAC;EAC5B,MAAM,KAAK,uBAAuB;EAClC,QAAQ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAChE,QAAQ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EACrE,QAAQ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EACtE,QAAQ,OAAO,YAAY,CAAC;EAC5B,MAAM,KAAK,SAAS;EACpB,QAAQ,YAAY,CAAC,IAAI,CAAC;EAC1B,UAAU,MAAM,EAAE,SAAS;EAC3B,UAAU,KAAK,EAAE,GAAG,CAAC,KAAK;EAC1B,UAAU,MAAM,EAAE,SAAS,KAAK,IAAI,GAAG,KAAK,GAAG,GAAG,CAAC,KAAK,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,KAAK,GAAG,QAAQ,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;EACjH,SAAS,CAAC,CAAC;EACX,QAAQ,MAAM;EACd,MAAM,KAAK,oBAAoB;EAC/B,QAAQ,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EACvE,MAAM,KAAK,YAAY;EACvB,QAAQ,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;EACrD,QAAQ,IAAI,WAAW,EAAE;EACzB,UAAU,YAAY,CAAC,IAAI,CAAC;EAC5B,YAAY,IAAI,EAAE,GAAG,CAAC,IAAI;EAC1B,YAAY,MAAM,EAAE,aAAa;EACjC,YAAY,MAAM,EAAE,SAAS,GAAG,KAAK,GAAG,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,YAAY,CAAC;EACzF,WAAW,CAAC,CAAC;EACb,SAAS,MAAM,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE;EAC9D,UAAU,YAAY,CAAC,IAAI,CAAC;EAC5B,YAAY,IAAI,EAAE,GAAG,CAAC,IAAI;EAC1B,YAAY,MAAM,EAAE,UAAU;EAC9B,YAAY,MAAM,EAAE,KAAK;EACzB,WAAW,CAAC,CAAC;EACb,SAAS,MAAM,IAAI,IAAI,CAAC,oBAAoB,EAAE;EAC9C,UAAU,MAAM,IAAI,KAAK,CAAC,CAAC,+BAA+B,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EACzE,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,qBAAqB;EAChC,QAAQ,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EACtG,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;EAChE,MAAM,KAAK,kBAAkB;EAC7B,QAAQ,SAAS,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,CAAC,CAAC;EACnE,QAAQ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAChE,QAAQ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EACjE,QAAQ,OAAO,YAAY,CAAC;EAC5B,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,kBAAkB;EAC7B,QAAQ,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAC3E,MAAM,KAAK,qBAAqB;EAChC,QAAQ,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,YAAY,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAC/E,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,YAAY,CAAC,IAAI,CAAC;EAC1B,UAAU,MAAM,EAAE,aAAa;EAC/B,UAAU,MAAM,EAAE,IAAI;EACtB,SAAS,CAAC,CAAC;EACX,QAAQ,OAAO,YAAY,CAAC;EAC5B,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,YAAY,CAAC,IAAI,CAAC;EAC1B,UAAU,MAAM,EAAE,UAAU;EAC5B,UAAU,MAAM,EAAE,IAAI;EACtB,SAAS,CAAC,CAAC;EACX,QAAQ,OAAO,YAAY,CAAC;EAC5B,MAAM,KAAK,kBAAkB;EAC7B,QAAQ,MAAM,OAAO,GAAG,IAAI,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC;EAC7D,QAAQ,QAAQ,OAAO,CAAC,SAAS;EACjC,UAAU,KAAK,SAAS;EACxB,YAAY,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EACtE,YAAY,MAAM;EAClB,UAAU,KAAK,WAAW;EAC1B,YAAY,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAC7E,YAAY,MAAM;EAClB,UAAU,KAAK,aAAa;EAC5B,YAAY,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EACpF,YAAY,MAAM;EAClB,UAAU,KAAK,mBAAmB;EAClC,YAAY,IAAI,IAAI,CAAC,aAAa,EAAE;EACpC,cAAc,YAAY,CAAC,IAAI,CAAC;EAChC,gBAAgB,IAAI,EAAE,OAAO,CAAC,IAAI;EAClC,gBAAgB,MAAM,EAAE,QAAQ;EAChC,gBAAgB,MAAM,EAAE,KAAK;EAC7B,eAAe,CAAC,CAAC;EACjB,aAAa;EACb,YAAY,MAAM;EAClB,SAAS;EACT,QAAQ,IAAI,OAAO,EAAE;EACrB,UAAU,IAAI,OAAO,CAAC,QAAQ,EAAE;EAChC,YAAY,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAC5E,WAAW;EACX,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE;EACjC,YAAY,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAC7E,WAAW;EACX,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE;EACjC,YAAY,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAC7E,WAAW;EACX,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE;EACjC,YAAY,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAC7E,WAAW;EACX,UAAU,OAAO,YAAY,CAAC;EAC9B,SAAS;EACT,QAAQ;EACR,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,eAAe,GAAG,GAAG,CAAC,IAAI,EAAE,mBAAmB,CAAC,EAAE,GAAG,CAAC,CAAC;EAC5F,KAAK;EACL,IAAI,OAAO,YAAY,CAAC;EACxB,GAAG;EAEH,EAAE,oBAAoB,CAAC,GAAG,EAAE;EAC5B,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE;EAClC,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,aAAa,GAAG,GAAG,CAAC,IAAI,EAAE,6BAA6B,CAAC,CAAC,CAAC;EACjF,KAAK;EACL,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE;EACnC,MAAM,OAAO,OAAO,CAAC;EACrB,KAAK;EACL,IAAI,MAAM,SAAS,GAAG,EAAE,CAAC;EACzB,IAAI,OAAO,IAAI,EAAE;EACjB,MAAM,IAAI,CAAC,GAAG,EAAE,MAAM;EACtB,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE;EACxB,QAAQ,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC7B,OAAO,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,gBAAgB,EAAE;EAChD,QAAQ,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;EAClC,OAAO,MAAM,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE;EACpD,QAAQ;EACR,UAAU,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,GAAG;EACnC,UAAU,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,GAAG;EACnC,UAAU,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,GAAG;EACnC,UAAU;EACV,UAAU,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EACtC,SAAS,MAAM;EACf,UAAU,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,WAAW;EAC3C,UAAU,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ;EACxC,UAAU,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ;EACxC,UAAU;EACV,UAAU,SAAS,CAAC,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;EACrD,SAAS,MAAM;EACf,UAAU,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EACtC,SAAS;EACT,OAAO,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE;EAC3B,QAAQ,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;EACnC,OAAO,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE;EAChD,QAAQ,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;EAClC,OAAO,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE;EAC/B,QAAQ,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EAChC,OAAO,MAAM;EACb,QAAQ,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;EACrC,OAAO;EACP,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC;EACvB,KAAK;EAEL,IAAI,MAAM,eAAe,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EAC/C,IAAI,MAAM,kBAAkB,GAAG;EAC/B,MAAM,OAAO;EACb,MAAM,SAAS;EACf,MAAM,WAAW;EACjB,MAAM,aAAa;EACnB,MAAM,eAAe;EACrB,MAAM,aAAa;EACnB,MAAM,oBAAoB;EAC1B,MAAM,mBAAmB;EACzB,MAAM,mBAAmB;EACzB,MAAM,sBAAsB;EAC5B,MAAM,wBAAwB;EAC9B,MAAM,0BAA0B;EAChC,MAAM,4BAA4B;EAClC,MAAM,8BAA8B;EACpC,MAAM,QAAQ;EACd,MAAM,UAAU;EAChB,MAAM,YAAY;EAClB,MAAM,MAAM;EACZ,KAAK,CAAC;EACN,IAAI,IAAI,kBAAkB,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,EAAE;EAC1D,MAAM,OAAO,eAAe,CAAC;EAC7B,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,KAAK,GAAG;EACV,IAAI,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;EACtC,GAAG;EAQH,EAAE,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE;EAC1B,IAAI,IAAI,GAAG,KAAK,IAAI,EAAE;EACtB,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;EACjD,KAAK,MAAM;EACX,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;EAC9B,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC7C,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EAC1C,SAAS;EACT,QAAQ,OAAO,MAAM,CAAC;EACtB,OAAO;EAEP,MAAM,QAAQ,GAAG,CAAC,IAAI;EACtB,QAAQ,KAAK,qBAAqB;EAClC,UAAU,OAAO,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EAC1D,QAAQ,KAAK,oBAAoB;EACjC,UAAU,OAAO,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACzD,QAAQ,KAAK,iBAAiB;EAC9B,UAAU,OAAO,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACtD,QAAQ,KAAK,SAAS;EACtB,UAAU,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EAC9C,QAAQ,KAAK,kBAAkB;EAC/B,UAAU,OAAO,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACvD,QAAQ,KAAK,YAAY;EACzB,UAAU,OAAO,IAAI,CAAC,uBAAuB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EAC3D,QAAQ,KAAK,sBAAsB;EACnC,UAAU,OAAO,IAAI,CAAC,uBAAuB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EAC3D,QAAQ,KAAK,qBAAqB;EAClC,UAAU,OAAO,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EAC1D,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACrD,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACrD,QAAQ,KAAK,aAAa;EAC1B,UAAU,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EAClD,QAAQ,KAAK,iBAAiB;EAC9B,UAAU,OAAO,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACtD,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACrD,QAAQ,KAAK,mBAAmB;EAChC,UAAU,OAAO,IAAI,CAAC,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACxD,QAAQ,KAAK,cAAc;EAC3B,UAAU,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACnD,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACrD,QAAQ,KAAK,kBAAkB;EAC/B,UAAU,OAAO,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACvD,QAAQ,KAAK,qBAAqB;EAClC,UAAU,OAAO,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EAC1D,QAAQ,KAAK,oBAAoB;EACjC,UAAU,OAAO,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACzD,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACrD,QAAQ,KAAK,oBAAoB;EACjC,UAAU,OAAO,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACzD,QAAQ,KAAK,iBAAiB;EAC9B,UAAU,OAAO,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACtD,QAAQ,KAAK,kBAAkB;EAC/B,UAAU,OAAO,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACvD,QAAQ,KAAK,mBAAmB;EAChC,UAAU,OAAO,IAAI,CAAC,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACxD,QAAQ,KAAK,kBAAkB;EAC/B,UAAU,OAAO,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACvD,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACrD,QAAQ,KAAK,iBAAiB;EAC9B,UAAU,OAAO,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACtD,QAAQ,KAAK,mBAAmB;EAChC,UAAU,OAAO,IAAI,CAAC,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACxD,QAAQ,KAAK,uBAAuB;EACpC,UAAU,OAAO,IAAI,CAAC,wBAAwB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EAC5D,OAAO;EAEP,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,qBAAqB,GAAG,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;EACvE,KAAK;EACL,GAAG;EAMH,EAAE,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE;EAC7B,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE;EACzC,MAAM,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EAC9B,KAAK;EAEL,IAAI,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;EACvD,IAAI,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;EACxD,IAAI,MAAM,UAAU,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;EACjD,IAAI,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;EACrF,IAAI,OAAO,IAAI,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU,CAAC,MAAM,EAAE,IAAI,GAAG,WAAW,EAAE,CAAC,CAAC,CAAC;EACrH,GAAG;EAEH,EAAE,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE;EACxC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE;EACxC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,uBAAuB,EAAE;EAC9C,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,8BAA8B,EAAE,GAAG,CAAC,CAAC;EACrE,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EACtC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;EAC5C,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC3C,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE;EAC3B,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,6BAA6B,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC/E,GAAG;EAQH,EAAE,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE;EACtC,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE;EACnC,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK;EACL,IAAI,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACzC,GAAG;EACH,EAAE,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE;EACrC,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE;EACnC,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK;EACL,IAAI,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACzC,GAAG;EACH,EAAE,eAAe,CAAC,GAAG,EAAE;EACvB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACpD,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;EACrC,QAAQ,OAAO,IAAI,CAAC;EACpB,OAAO;EACP,KAAK;EACL,IAAI,OAAO,KAAK,CAAC;EACjB,GAAG;EACH,EAAE,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE;EAClC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE;EAC1B,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC5D,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE;EACnC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE;EACvC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE;EACvC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAOH,EAAE,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE;EACzC,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;EAC/C,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAOH,EAAE,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE;EACnC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE;EACjC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE;EAC9B,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE;EAClC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAOH,EAAE,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE;EACpC,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC1B,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAOH,EAAE,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE;EACvC,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EAC/B,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE;EAC/B,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE;EACjC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE;EACnC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAOH,EAAE,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE;EAC7C,IAAI,MAAM,YAAY,GAAG,UAAU,CAAC,YAAY,CAAC;EACjD,IAAI,IAAI,CAAC,YAAY,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;EACpE,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,UAAU,CAAC,CAAC;EACrE,KAAK;EACL,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,MAAM,gBAAgB,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;EAC7C,IAAI,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC;EACvC,IAAI,IAAI,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EACjF,IAAI,IAAI,IAAI,KAAK,gBAAgB,EAAE;EAEnC,MAAM,IAAI,GAAG,QAAQ,CAAC;EACtB,KAAK;EACL,IAAI,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;EACrC,IAAI,IAAI,CAAC,UAAU,EAAE;EACrB,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,YAAY,GAAG,UAAU,EAAE,YAAY,CAAC,EAAE,UAAU,CAAC,CAAC;EACvF,KAAK;EACL,IAAI,IAAI,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;EACnE,IAAI,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC;EACjC,IAAI,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;EAChE,MAAM,IAAI;EACV,MAAM,YAAY;EAClB,MAAM,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,IAAI,MAAM,UAAU,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EACrE,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;EACtC,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;EAGrC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,MAAM,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;EAC1C,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;EACvD,MAAM,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC;EACnC,MAAM,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;EAC7D,QAAQ,IAAI;EACZ,QAAQ,YAAY;EACpB,QAAQ,MAAM,EAAE,KAAK;EACrB,OAAO,CAAC,CAAC;EACT,MAAM,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;EAC3C,KAAK;EAEL,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;EAC1C,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAOH,EAAE,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE;EAC7C,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;EAC5C,IAAI,IAAI,WAAW,CAAC,IAAI,KAAK,IAAI,EAAE;EACnC,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,MAAM,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAChD,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE;EACjC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE;EACvC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACvD,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE;EACjB,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,OAAO;EACP,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;EACjD,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAOH,EAAE,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE;EACpC,IAAI,MAAM,WAAW,GAAG,IAAI,CAAC,6BAA6B,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC1E,IAAI,IAAI,WAAW,EAAE;EACrB,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK;EAEL,IAAI,IAAI,KAAK,CAAC,MAAM,EAAE;EACtB,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;EAClC,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC9C,KAAK,MAAM;EACX,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC9C,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;EAClC,KAAK;EAEL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,6BAA6B,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;EAQjD,EAAE,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE;EACrC,IAAI,IAAI,KAAK,CAAC,MAAM,EAAE;EACtB,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;EAClC,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC9C,KAAK,MAAM;EACX,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC9C,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;EAClC,KAAK;EAEL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAOH,EAAE,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE;EACxC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC3C,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE;EACnC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE;EACjC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE;EAClC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAOH,EAAE,0BAA0B,CAAC,GAAG,EAAE;EAClC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,kBAAkB,EAAE;EACzC,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,WAAW,GAAG,GAAG,CAAC,IAAI,EAAE,uBAAuB,CAAC,EAAE,GAAG,CAAC,CAAC;EACxF,KAAK;EACL,IAAI,IAAI,IAAI,GAAG,IAAI,CAAC;EACpB,IAAI,IAAI,IAAI,GAAG,IAAI,CAAC;EACpB,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;EAC7D,IAAI,QAAQ,iBAAiB;EAC7B,MAAM,KAAK,OAAO;EAClB,QAAQ,OAAO,IAAI,CAAC;EACpB,MAAM,KAAK,oBAAoB,CAAC;EAChC,MAAM,KAAK,mBAAmB,CAAC;EAC/B,MAAM,KAAK,mBAAmB;EAC9B,QAAQ,OAAO;EACf,UAAU,SAAS,EAAE,iBAAiB;EACtC,YAAY,IAAI,EAAE,SAAS;EAC3B,YAAY,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,IAAI;EACnC,SAAS,CAAC;EACV,MAAM,KAAK,SAAS;EACpB,QAAQ,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE;EACjD,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EAClE,SAAS;EACT,QAAQ,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;EAC/B,QAAQ,OAAO;EACf,UAAU,IAAI;EACd,UAAU,MAAM,EAAE,MAAM;EACxB,YAAY,SAAS,EAAE,iBAAiB;EACxC,YAAY,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC;EAClD,YAAY,SAAS,EAAE,GAAG,CAAC,QAAQ;EACnC,SAAS,CAAC;EACV,MAAM,KAAK,WAAW;EACtB,QAAQ,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE;EACxD,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EAClE,SAAS;EACT,QAAQ,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;EACtC,QAAQ,OAAO;EACf,UAAU,IAAI;EACd,UAAU,MAAM,EAAE,MAAM;EACxB,YAAY,SAAS,EAAE,iBAAiB;EACxC,YAAY,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;EACzD,YAAY,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ;EAC1C,YAAY,SAAS,EAAE,GAAG,CAAC,QAAQ;EACnC,SAAS,CAAC;EACV,MAAM,KAAK,aAAa;EACxB,QAAQ,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE;EAC/D,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EAClE,SAAS;EACT,QAAQ,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;EAC7C,QAAQ,OAAO;EACf,UAAU,IAAI;EACd,UAAU,MAAM,EAAE,MAAM;EACxB,YAAY,SAAS,EAAE,iBAAiB;EACxC,YAAY,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;EAChE,YAAY,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ;EACjD,YAAY,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ;EAC1C,YAAY,SAAS,EAAE,GAAG,CAAC,QAAQ;EACnC,SAAS,CAAC;EACV,MAAM,KAAK,eAAe;EAC1B,QAAQ,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE;EACtE,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EAClE,SAAS;EACT,QAAQ,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;EACpD,QAAQ,OAAO;EACf,UAAU,IAAI;EACd,UAAU,MAAM,EAAE,MAAM;EACxB,YAAY,SAAS,EAAE,iBAAiB;EACxC,YAAY,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;EACvE,YAAY,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ;EACjD,YAAY,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ;EAC1C,YAAY,SAAS,EAAE,GAAG,CAAC,QAAQ;EACnC,SAAS,CAAC;EACV,MAAM,KAAK,aAAa;EACxB,QAAQ,IAAI,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE;EACnD,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EAClE,SAAS;EACT,QAAQ,IAAI,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE;EACzC,UAAU,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;EACnC,UAAU,OAAO;EACjB,YAAY,IAAI;EAChB,YAAY,MAAM,EAAE,MAAM;EAC1B,YAAY,IAAI,EAAE,QAAQ;EAC1B,YAAY,SAAS,EAAE,iBAAiB;EACxC,WAAW,CAAC;EACZ,SAAS;EACT,QAAQ,QAAQ,GAAG,CAAC,QAAQ,CAAC,IAAI;EACjC,UAAU,KAAK,GAAG,CAAC;EACnB,UAAU,KAAK,GAAG,CAAC;EACnB,UAAU,KAAK,GAAG,CAAC;EACnB,UAAU,KAAK,GAAG;EAClB,YAAY,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;EACnC,YAAY,OAAO;EACnB,cAAc,IAAI;EAClB,cAAc,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,IAAI;EACzC,gBAAgB,MAAM,EAAE,MAAM;EAC9B,gBAAgB,SAAS,EAAE,iBAAiB;EAC5C,gBAAgB,IAAI,EAAE,QAAQ;EAC9B,aAAa,CAAC;EACd,UAAU;EACV,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EACpE,SAAS;EACT,QAAQ,KAAK,sBAAsB;EACnC,UAAU,IAAI,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE;EACrD,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EACpE,WAAW;EACX,UAAU,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;EACnC,UAAU,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC5C,UAAU,IAAI,CAAC,IAAI,EAAE;EACrB,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC;EACnE,WAAW;EACX,UAAU,OAAO;EACjB,YAAY,IAAI;EAChB,YAAY,IAAI;EAChB,YAAY,MAAM,EAAE,WAAW;EAC/B,cAAc,SAAS,EAAE,iBAAiB;EAC1C,WAAW,CAAC;EACZ,QAAQ,KAAK,wBAAwB;EACrC,UAAU,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE;EAC5D,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EACpE,WAAW;EACX,UAAU,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;EAC1C,UAAU,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC5C,UAAU,IAAI,CAAC,IAAI,EAAE;EACrB,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC;EACnE,WAAW;EACX,UAAU,OAAO;EACjB,YAAY,IAAI;EAChB,YAAY,IAAI;EAChB,YAAY,MAAM,EAAE,WAAW;EAC/B,cAAc,SAAS,EAAE,iBAAiB;EAC1C,cAAc,SAAS,EAAE,GAAG,CAAC,QAAQ;EACrC,WAAW,CAAC;EACZ,QAAQ,KAAK,0BAA0B,EAAE;EACzC,UAAU,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE;EACnE,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EACpE,WAAW;EACX,UAAU,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;EACjD,UAAU,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC5C,UAAU,IAAI,CAAC,IAAI,EAAE;EACrB,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC;EACnE,WAAW;EACX,UAAU,OAAO;EACjB,YAAY,IAAI;EAChB,YAAY,IAAI;EAChB,YAAY,MAAM,EAAE,WAAW;EAC/B,YAAY,SAAS,EAAE,iBAAiB;EACxC,YAAY,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ;EAC1C,YAAY,SAAS,EAAE,GAAG,CAAC,QAAQ;EACnC,WAAW,CAAC;EACZ,SAAS;EACT,QAAQ,KAAK,4BAA4B,EAAE;EAC3C,UAAU,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE;EAC1E,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EACpE,WAAW;EACX,UAAU,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;EACxD,UAAU,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC5C,UAAU,IAAI,CAAC,IAAI,EAAE;EACrB,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC;EACnE,WAAW;EACX,UAAU,OAAO;EACjB,YAAY,IAAI;EAChB,YAAY,IAAI;EAChB,YAAY,MAAM,EAAE,WAAW;EAC/B,YAAY,SAAS,EAAE,iBAAiB;EACxC,YAAY,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ;EACjD,YAAY,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ;EAC1C,YAAY,SAAS,EAAE,GAAG,CAAC,QAAQ;EACnC,WAAW,CAAC;EACZ,SAAS;EACT,QAAQ,KAAK,QAAQ,CAAC;EACtB,QAAQ,KAAK,MAAM;EACnB,UAAU,OAAO;EACjB,YAAY,SAAS,EAAE,iBAAiB;EACxC,cAAc,QAAQ,EAAE,GAAG,CAAC,QAAQ;EACpC,WAAW,CAAC;EACZ,QAAQ;EACR,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EAClE,KAAK;EACL,GAAG;EAEH,EAAE,oBAAoB,CAAC,SAAS,EAAE;EAClC,IAAI,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAE7B,IAAI,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;EAC7B,MAAM,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;EAC9B,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,oBAAoB,IAAI,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,EAAE,CAAC,IAAI,IAAI,MAAM,CAAC,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,EAAE;EACpH,QAAQ,OAAO,MAAM,CAAC;EACtB,OAAO;EACP,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;EACpB,MAAM,IAAI,MAAM,CAAC,QAAQ,EAAE;EAC3B,QAAQ,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;EACpC,OAAO,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE;EAC9B,QAAQ,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;EAChC,OAAO,MAAM,IAAI,MAAM,CAAC,YAAY,EAAE;EACtC,QAAQ,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;EACxC,OAAO,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;EACxC,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAChD,UAAU,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAChC,SAAS;EACT,OAAO;EACP,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,cAAc,CAAC,GAAG,EAAE;EACtB,IAAI,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;EAEpC,IAAI,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;EAC7B,MAAM,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;EACjC,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,iBAAiB,EAAE;EAC7C,QAAQ,OAAO,MAAM,CAAC;EACtB,OAAO;EACP,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,qBAAqB,EAAE;EACjD,QAAQ,SAAS;EACjB,OAAO;EACP,MAAM,IAAI,MAAM,CAAC,QAAQ,EAAE;EAC3B,QAAQ,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;EACpC,OAAO,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE;EAC9B,QAAQ,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;EAChC,OAAO,MAAM,IAAI,MAAM,CAAC,YAAY,EAAE;EACtC,QAAQ,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;EACxC,OAAO,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;EACxC,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAChD,UAAU,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAChC,SAAS;EACT,OAAO,MAAM,IAAI,MAAM,CAAC,UAAU,EAAE;EACpC,QAAQ,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;EACtC,OAAO,MAAM,IAAI,MAAM,CAAC,KAAK,EAAE;EAC/B,QAAQ,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;EACjC,OAAO;EACP,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,uBAAuB,CAAC,IAAI,EAAE;EAChC,IAAI,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EAC3D,MAAM,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC5C,KAAK;EACL,IAAI,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC;EACxC,IAAI,IAAI,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;EACjD,MAAM,OAAO,IAAI,CAAC;EAClB,KAAK;EACL,IAAI,OAAO,IAAI,GAAG,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;EACpD,GAAG;EAEH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAO,CAAC,IAAI,CAAC,iKAAiK,CAAC,CAAC;EACpL,GAAG;EACH,CAAC;EAED,MAAM,aAAa,GAAG;EACtB,EAAE,QAAQ,EAAE,QAAQ;EACpB,EAAE,OAAO,EAAE,OAAO;EAClB,EAAE,SAAS,EAAE,SAAS;EACtB,EAAE,OAAO,EAAE,QAAQ;EACnB,EAAE,UAAU,EAAE,QAAQ;EACtB,EAAE,UAAU,EAAE,QAAQ;EACtB,EAAE,UAAU,EAAE,QAAQ;EACtB,EAAE,SAAS,EAAE,QAAQ;EACrB,EAAE,SAAS,EAAE,QAAQ;EACrB,EAAE,OAAO,EAAE,QAAQ;EACnB,EAAE,WAAW,EAAE,UAAU;EACzB,EAAE,WAAW,EAAE,UAAU;EACzB,EAAE,gBAAgB,EAAE,UAAU;EAC9B,EAAE,eAAe,EAAE,QAAQ;EAC3B,EAAE,8BAA8B,EAAE,QAAQ;EAC1C,EAAE,YAAY,EAAE,UAAU;EAC1B,EAAE,YAAY,EAAE,UAAU;EAC1B,EAAE,YAAY,EAAE,UAAU;EAC1B,EAAE,YAAY,EAAE,UAAU;EAC1B,EAAE,YAAY,EAAE,UAAU;EAC1B,EAAE,YAAY,EAAE,UAAU;EAC1B,EAAE,YAAY,EAAE,UAAU;EAC1B,EAAE,YAAY,EAAE,UAAU;EAC1B,EAAE,YAAY,EAAE,UAAU;EAC1B,EAAE,iBAAiB,EAAE,QAAQ;EAC7B,EAAE,iBAAiB,EAAE,UAAU;EAC/B,EAAE,iBAAiB,EAAE,UAAU;EAC/B,EAAE,iBAAiB,EAAE,UAAU;EAC/B,CAAC,CAAC;;EC99CK,MAAM,eAAe,SAAS,YAAY,CAAC;EAOlD,EAAE,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE;EAG3B,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;EAC5B,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EAC9B,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC7B,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAGvB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EAC1D,QAAQ,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;EAEnD,QAAQ,IAAI,CAAC,GAAG,CAAC,EAAE;EACnB,UAAU,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC5B,SAAS;EACT,QAAQ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC7B,QAAQ,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAClC,OAAO;EAGP,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC3B,KAAK;EAGL,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACnD,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EAChD,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EACxB,KAAK;EAEL,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;EAE5B,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE;EAClC,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAE/D,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;EAC1B,MAAM,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EAC7B,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,YAAY,EAAE;EAC3B,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;EAC/C,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC5C,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;EACjD,MAAM,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACjC,KAAK,MAAM,IAAI,IAAI,CAAC,WAAW,EAAE;EACjC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,gBAAgB,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;EACvD,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC5C,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,uBAAuB,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;EAC5D,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EAC7B,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC5C,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE;EAG1B,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;EAC1B,MAAM,MAAM,IAAI,CAAC,cAAc;EAC/B,QAAQ,sCAAsC,GAAG,GAAG,CAAC,KAAK;EAC1D,QAAQ,GAAG;EACX,OAAO,CAAC;EACR,KAAK;EAEL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;EAE3B,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE;EACnC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EACtC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC9B,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACvC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE;EAC3C,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,EAAE;EACvC,MAAM,MAAM,IAAI,CAAC,cAAc;EAC/B,QAAQ,0CAA0C;EAClD,QAAQ,OAAO;EACf,OAAO,CAAC;EACR,KAAK;EAEL,IAAI,QAAQ,OAAO,CAAC,IAAI;EACxB,MAAM,KAAK,UAAU;EACrB,QAAQ,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EAChC,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;EAC3E,UAAU,MAAM,CAAC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;EACnD,SAAS,MAAM;EACf,UAAU,MAAM,CAAC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;EAC9C,SAAS;EACT,KAAK;EAEL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE;EACnC,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,cAAc,EAAE;EACzC,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;EAClE,KAAK;EAEL,IAAI,MAAM,OAAO,GAAG,EAAE,CAAC;EACvB,IAAI,MAAM,OAAO,GAAG,EAAE,CAAC;EACvB,IAAI,MAAM,SAAS,GAAG,EAAE,CAAC;EACzB,IAAI,MAAM,OAAO,GAAG,EAAE,CAAC;EACvB,IAAI,IAAI,MAAM,GAAG,IAAI,CAAC;EAEtB,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE;EACtB,MAAM,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EACzC,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;EAC7C,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC/C,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;EAC7D,UAAU,MAAM,GAAG,KAAK,CAAC;EACzB,SAAS;EACT,OAAO;EACP,MAAM,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EACxC,KAAK,MAAM;EACX,MAAM,MAAM,GAAG,KAAK,CAAC;EACrB,KAAK;EAEL,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE;EACtB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;EAC7C,KAAK,MAAM;EACX,MAAM,MAAM,GAAG,KAAK,CAAC;EACrB,KAAK;EAEL,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE;EACxB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;EACjD,KAAK,MAAM;EACX,MAAM,MAAM,GAAG,KAAK,CAAC;EACrB,KAAK;EAEL,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE;EACtB,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;EAClC,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;EAC7C,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;EACjC,KAAK;EAGL,IAAI,IAAI,MAAM,KAAK,IAAI,EAAE;EACzB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EACtE,KAAK;EAEL,IAAI,IAAI,MAAM,EAAE;EAChB,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EAC5F,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;EACpC,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,KAAK,MAAM;EACX,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;EAClE,MAAM,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;EAC9B,QAAQ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;EAC7C,OAAO;EACP,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,aAAa,CAAC,GAAG,EAAE,aAAa,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;EAClG,MAAM,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;EAC9B,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;EAC1D,OAAO;EACP,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;EACpC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC9C,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE;EACvC,IAAI,IAAI,SAAS,CAAC,IAAI,KAAK,gBAAgB,EAAE;EAC7C,MAAM,MAAM,IAAI,CAAC,cAAc;EAC/B,QAAQ,yBAAyB;EACjC,QAAQ,SAAS;EACjB,OAAO,CAAC;EACR,KAAK;EAEL,IAAI,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;EACxD,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACxB,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACzB,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAC9B,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EAC5B,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACvB,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EAEvB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE;EAC3C,IAAI,IAAI,WAAW,CAAC,IAAI,KAAK,kBAAkB,EAAE;EACjD,MAAM,MAAM,IAAI,CAAC,cAAc;EAC/B,QAAQ,yBAAyB;EACjC,QAAQ,WAAW;EACnB,OAAO,CAAC;EACR,KAAK;EAEL,IAAI,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;EACxD,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACzB,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACzB,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EAC5B,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACvB,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EAEvB,IAAI,OAAO,MAAM,CAAC;EAElB,GAAG;EAQH,EAAE,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE;EAC3C,IAAI,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EAC1D,IAAI,IAAI,WAAW,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE;EAChD,MAAM,MAAM,IAAI,IAAI,CAAC,cAAc,CAAC,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,EAAE,OAAO,CAAC,CAAC;EACrG,KAAK;EACL,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC3C,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE;EACnC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;EACnC,MAAM,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;EACnC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,QAAQ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EAC/C,OAAO;EACP,MAAM,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;EAClC,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,QAAQ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EAC/C,OAAO;EACP,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE;EAC7C,IAAI,IAAI,UAAU,CAAC,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,YAAY,EAAE;EACxD,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;EACrB,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EACvC,IAAI,MAAM,EAAE,YAAY,EAAE,GAAG,UAAU,CAAC;EACxC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE;EACjB,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,OAAO;EACP,MAAM,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EAC/C,KAAK;EACL,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;EAC3C,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE;EACjC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACxB,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EACzC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,KAAK,gBAAgB,EAAE;EACrD,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;EACjD,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC1B,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;EACjD,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC3B,KAAK;EAEL,IAAI,IAAI,MAAM,CAAC,SAAS,EAAE;EAC1B,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC3B,MAAM,IAAI,MAAM,CAAC,SAAS,CAAC,IAAI,KAAK,gBAAgB,EAAE;EACtD,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAClD,OAAO,MAAM;EACb,QAAQ,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC5B,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAClD,QAAQ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC7B,OAAO;EACP,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAElB,GAAG;EAEH,EAAE,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE;EAClC,IAAI,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC;EACxC,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EAC5B,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;EAC1C,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACzB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC3C,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE;EAClC,QAAQ,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAClC,QAAQ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;EACrD,QAAQ,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;EACnE,UAAU,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EAClC,SAAS;EACT,QAAQ,SAAS;EACjB,OAAO;EACP,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC3B,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC7C,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;EACjE,QAAQ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;EACrD,QAAQ,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EAChC,OAAO;EACP,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACvB,GAAG;EAQH,EAAE,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE;EACnC,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACzB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE;EACrC,IAAI,MAAM;EACV,MAAM,SAAS;EACf,MAAM,IAAI;EACV,MAAM,QAAQ;EACd,MAAM,SAAS;EACf,MAAM,SAAS;EACf,MAAM,SAAS;EACf,MAAM,IAAI;EACV,MAAM,MAAM;EACZ,KAAK,GAAG,IAAI,CAAC,0BAA0B,CAAC,KAAK,CAAC,CAAC;EAC/C,IAAI,QAAQ,SAAS;EACrB,MAAM,KAAK,mBAAmB;EAC9B,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;EAC9C,QAAQ,OAAO,MAAM,CAAC;EACtB,MAAM,KAAK,mBAAmB;EAC9B,QAAQ,QAAQ,IAAI;EACpB,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EACnC,YAAY,MAAM;EAClB,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EACnC,YAAY,MAAM;EAClB,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EACnC,YAAY,MAAM;EAClB,UAAU;EACV,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;EACtE,SAAS;EACT,QAAQ,OAAO,MAAM,CAAC;EACtB,MAAM,KAAK,OAAO;EAClB,QAAQ,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;EAClE,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,WAAW,CAAC;EACvB,MAAM,KAAK,aAAa,CAAC;EACzB,MAAM,KAAK,aAAa;EACxB,QAAQ,IAAI,MAAM,KAAK,MAAM,EAAE;EAC/B,UAAU,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EAClC,UAAU,OAAO,MAAM,CAAC;EACxB,SAAS;EACT,QAAQ,QAAQ,QAAQ;EACxB,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;EAC7C,YAAY,OAAO,MAAM,CAAC;EAC1B,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;EAC7C,YAAY,OAAO,MAAM,CAAC;EAC1B,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;EAC7C,YAAY,OAAO,MAAM,CAAC;EAC1B,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;EAC7C,YAAY,OAAO,MAAM,CAAC;EAC1B,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,sBAAsB,CAAC;EAClC,MAAM,KAAK,wBAAwB,CAAC;EACpC,MAAM,KAAK,0BAA0B,CAAC;EACtC,MAAM,KAAK,4BAA4B;EACvC,QAAQ,MAAM;EACd,MAAM,KAAK,QAAQ;EACnB,QAAQ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;EAC9C,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAChD,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,OAAO,MAAM,CAAC;EACtB,MAAM;EACN,QAAQ,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;EAClE,KAAK;EAEL,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;EAEzB,MAAM,QAAQ,IAAI;EAClB,QAAQ,KAAK,QAAQ,CAAC;EACtB,QAAQ,KAAK,SAAS,CAAC;EACvB,QAAQ,KAAK,OAAO,CAAC;EACrB,QAAQ,KAAK,SAAS;EACtB,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;EAC3C,UAAU,OAAO,MAAM,CAAC;EACxB,OAAO;EACP,KAAK;EAIL,IAAI,MAAM,UAAU,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;EAE3C,IAAI,QAAQ,IAAI;EAChB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,WAAW,CAAC;EACvB,MAAM;EACN,QAAQ,IAAI,IAAI,CAAC;EACjB,QAAQ,IAAI,OAAO,CAAC;EACpB,QAAQ,IAAI,MAAM,KAAK,WAAW,EAAE;EACpC,UAAU,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;EAChD,UAAU,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC;EACzD,UAAU,IAAI,GAAG,OAAO,GAAG,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC;EAChD,SAAS,MAAM;EACf,UAAU,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EACvC,UAAU,IAAI,GAAG,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;EACvF,SAAS;EACT,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC;EACvC,QAAQ,IAAI,SAAS,IAAI,SAAS,EAAE;EACpC,UAAU,IAAI,OAAO,EAAE;EACvB,YAAY,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC9B,YAAY,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,gBAAgB,GAAG,qBAAqB,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;EACtG,YAAY,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,gBAAgB,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;EAC/E,YAAY,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,WAAW,MAAM;EACjB,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,YAAY,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,YAAY,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,YAAY,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,WAAW;EACX,SAAS,MAAM,IAAI,SAAS,EAAE;EAC9B,UAAU,IAAI,OAAO,EAAE;EACvB,YAAY,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC9B,YAAY,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,gBAAgB,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;EAC/E,YAAY,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,WAAW,MAAM;EACjB,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,YAAY,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,YAAY,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,WAAW;EACX,SAAS,MAAM,IAAI,OAAO,SAAS,KAAK,WAAW,EAAE;EACrD,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,UAAU,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC7C,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,SAAS;EACT,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE;EACjC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,gBAAgB,EAAE;EAEvC,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;EAC/D,KAAK;EAEL,IAAI,IAAI,YAAY,GAAG,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;EAGlE,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE;EACxD,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAC9C,KAAK;EAEL,IAAI,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;EAGvD,IAAI,IAAI,IAAI,CAAC,cAAc,EAAE;EAC7B,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;EAClE,KAAK;EAGL,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAG9B,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,MAAM,WAAW,GAAG,IAAI,CAAC,2BAA2B,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;EAE7E,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACnD,MAAM,MAAM,QAAQ,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;EAGxC,MAAM,IAAI,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EAChD,MAAM,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE;EAC3B,QAAQ,IAAI,CAAC,wBAAwB,CAAC,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;EAC3E,OAAO;EAEP,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE;EACjB,QAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC1B,OAAO;EACP,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EACxC,KAAK;EAEL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAErB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE;EACtC,IAAI,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;EAE3C,IAAI,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;EACtC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,EAAE,CAAC,EAAE;EACrC,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE;EACjB,QAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC1B,OAAO;EACP,MAAM,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;EAC1C,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAC;EACtC,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAEtB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE;EACxC,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7B,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,CAAC;;ECloBD,SAAS,iBAAiB,CAAC,SAAS,EAAE,KAAK,EAAE;EAC7C,EAAE,MAAM,OAAO,GAAG,EAAE,CAAC;EACrB,EAAE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;EAC5B,IAAI,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,SAAS;EAC9C,IAAI,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;EAC7B,IAAI,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;EACrC,IAAI,QAAQ,IAAI;EAChB,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,OAAO,CAAC;EACnB,MAAM,KAAK,SAAS;EACpB,QAAQ,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;EAC5C,QAAQ,MAAM;EACd,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU;EACrB,QAAQ,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1G,QAAQ,MAAM;EACd,KAAK;EACL,GAAG;EACH,EAAE,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;EACnC,CAAC;AAED,EAAO,SAAS,eAAe,CAAC,SAAS,EAAE,IAAI,EAAE;EACjD,EAAE,MAAM,MAAM,GAAG,EAAE,CAAC;EACpB,EAAE,MAAM,cAAc,GAAG,EAAE,CAAC;EAC5B,EAAE,MAAM,YAAY,GAAG,EAAE,CAAC;EAE1B,EAAE,MAAM,kBAAkB,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;EAE3E,EAAE,MAAM,CAAC,IAAI;EACb,IAAI,uEAAuE;EAC3E,IAAI,CAAC,gCAAgC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;EACvF,IAAI,CAAC,yBAAyB,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;EAC1E,IAAI,CAAC,qBAAqB,EAAE,iBAAiB,CAAC,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;EAC9F,GAAG,CAAC;EAEJ,EAAE,cAAc,CAAC,IAAI;EACrB,IAAI,4BAA4B;EAChC,IAAI,cAAc;EAClB,IAAI,aAAa;EACjB,IAAI,iCAAiC;EACrC,GAAG,CAAC;EAEJ,EAAE,IAAI,SAAS,CAAC,SAAS,EAAE;EAC3B,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,6CAA6C,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;EACjH,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,2CAA2C,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;EAEpH,IAAI,MAAM,OAAO,GAAGD,OAAK,CAAC,uBAAuB,CAAC,CAAC,kBAAkB,GAAG,WAAW,GAAG,EAAE,IAAI,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE;EACxH,MAAM,UAAU,EAAE,CAAC,YAAY,KAAK;EACpC,QAAQ,QAAQ,YAAY;EAC5B,UAAU,KAAK,YAAY;EAC3B,YAAY,OAAO,YAAY,CAAC;EAChC,UAAU,KAAK,YAAY;EAC3B,YAAY,OAAO,YAAY,CAAC;EAChC,UAAU,KAAK,QAAQ;EACvB,YAAY,OAAO,QAAQ,CAAC;EAC5B,UAAU,KAAK,QAAQ;EACvB,YAAY,OAAO,aAAa,CAAC;EACjC,SAAS;EACT,QAAQ,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;EACvD,OAAO;EACP,MAAM,cAAc,EAAE,CAAC,MAAM,EAAE,IAAI,KAAK;EACxC,QAAQ,OAAO,IAAI,CAAC;EACpB,OAAO;EACP,KAAK,CAAC,CAAC;EAEP,IAAI,MAAM,WAAW,GAAGA,OAAK,CAAC,uBAAuB,CAAC,CAAC,kBAAkB,GAAG,WAAW,GAAG,EAAE,IAAI,SAAS,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE;EAChI,MAAM,UAAU,EAAE,CAAC,YAAY,KAAK;EACpC,QAAQ,QAAQ,YAAY;EAC5B,UAAU,KAAK,YAAY;EAC3B,YAAY,OAAO,YAAY,CAAC;EAChC,UAAU,KAAK,YAAY;EAC3B,YAAY,OAAO,YAAY,CAAC;EAChC,UAAU,KAAK,QAAQ;EACvB,YAAY,OAAO,QAAQ,CAAC;EAC5B,UAAU,KAAK,QAAQ;EACvB,YAAY,OAAO,aAAa,CAAC;EACjC,SAAS;EACT,QAAQ,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;EACvD,OAAO;EACP,MAAM,cAAc,EAAE,MAAM;EAC5B,QAAQ,OAAO,IAAI,CAAC;EACpB,OAAO;EACP,KAAK,CAAC,CAAC;EAEP,IAAI,cAAc,CAAC,IAAI;EACvB,MAAM,iBAAiB;EACvB,MAAM,iBAAiB;EACvB,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;EAC9B,KAAK,CAAC;EAEN,IAAI,YAAY,CAAC,IAAI;EACrB,MAAM,CAAC,qBAAqB,EAAE,WAAW,CAAC,CAAC,CAAC;EAC5C,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,MAAM,aAAa,GAAG,EAAE,CAAC;EAC3B,EAAE,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;EAC5D,EAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAChD,IAAI,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC;EAC9D,GAAG;EACH,EAAE,IAAI,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,IAAI,aAAa,CAAC,OAAO,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE;EAClH,IAAI,MAAM,uBAAuB,GAAGA,OAAK,CAAC,uBAAuB,CAAC,CAAC,kBAAkB,GAAG,WAAW,GAAG,EAAE,IAAI,SAAS,CAAC,eAAe,CAAC,QAAQ,EAAE,EAAE;EAClJ,MAAM,WAAW,EAAE,CAAC,QAAQ,CAAC;EAC7B,MAAM,cAAc,EAAE,CAAC,MAAM,EAAE,IAAI,KAAK;EACxC,QAAQ,IAAI,MAAM,KAAK,MAAM,EAAE;EAC/B,UAAU,OAAO,CAAC,kBAAkB,GAAG,WAAW,GAAG,EAAE,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;EACtF,SAAS;EACT,QAAQ,OAAO,IAAI,CAAC;EACpB,OAAO;EACP,MAAM,UAAU,EAAE,CAAC,YAAY,KAAK;EACpC,QAAQ,QAAQ,YAAY;EAC5B,UAAU,KAAK,QAAQ;EACvB,YAAY,OAAO;EACnB,UAAU,KAAK,SAAS;EACxB,YAAY,OAAO,SAAS,CAAC;EAC7B,SAAS;EACT,OAAO;EACP,KAAK,CAAC,CAAC;EACP,IAAI,YAAY,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;EAC/C,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAChD,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAChD,GAAG,MAAM,IAAI,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,IAAI,aAAa,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE;EAC/G,IAAI,MAAM,uBAAuB,GAAGA,OAAK,CAAC,uBAAuB,CAAC,CAAC,kBAAkB,GAAG,WAAW,GAAG,EAAE,IAAI,SAAS,CAAC,eAAe,CAAC,QAAQ,EAAE,EAAE;EAClJ,MAAM,cAAc,EAAE,CAAC,MAAM,EAAE,IAAI,KAAK;EACxC,QAAQ,OAAO,IAAI,CAAC;EACpB,OAAO;EACP,MAAM,UAAU,EAAE,CAAC,YAAY,KAAK;EACpC,QAAQ,QAAQ,YAAY;EAC5B,UAAU,KAAK,QAAQ;EACvB,YAAY,OAAO,iBAAiB,CAAC;EACrC,UAAU,KAAK,SAAS;EACxB,YAAY,OAAO,kBAAkB,CAAC;EACtC,SAAS;EACT,QAAQ,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;EAChD,OAAO;EACP,KAAK,CAAC,CAAC;EACP,IAAI,YAAY,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;EAC/C,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAChD,GAAG;EAEH,EAAE,OAAO,CAAC;AACV,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;AAuBtB,EAAE,SAAS,CAAC,aAAa,CAAC;;aAEb,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EACvC,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;;CAE7B,CAAC,CAAC;EACH,CAAC;;ECpKM,MAAM,SAAS,SAAS,MAAM,CAAC;EACtC,EAAE,OAAO,WAAW,GAAG;EACvB,IAAI,OAAO,IAAI,CAAC,QAAQ,CAAC;EACzB,GAAG;EACH,EAAE,WAAW,QAAQ,GAAG;EACxB,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC;EACzB,MAAM,SAAS,EAAE,IAAI;EACrB,MAAM,yBAAyB,EAAE,IAAI;EACrC,KAAK,CAAC,CAAC;EACP,GAAG;EACH,EAAE,WAAW,WAAW,GAAG;EAC3B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EACH,EAAE,OAAO,cAAc,CAAC,OAAO,EAAE;EACjC,IAAI,OAAO,KAAK,CAAC;EACjB,GAAG;EAIH,EAAE,WAAW,IAAI,GAAG;EACpB,IAAI,OAAO,KAAK,CAAC;EACjB,GAAG;EAEH,EAAE,OAAO,uBAAuB,GAAG;EACnC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,OAAO,wBAAwB,GAAG;EACpC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,OAAO,cAAc,CAAC,cAAc,EAAE;EACxC,IAAI,OAAO,cAAc,CAAC;EAC1B,GAAG;EAEH,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE;EAChC,IAAI,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;EAC5B,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC;EAEpD,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EAC3B,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EAC3B,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;EAC9B,IAAI,IAAI,CAAC,MAAM,GAAG;EAClB,MAAM,CAAC,EAAE,CAAC;EACV,MAAM,CAAC,EAAE,CAAC;EACV,MAAM,CAAC,EAAE,CAAC;EACV,KAAK,CAAC;EACN,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;EAClC,GAAG;EAEH,EAAE,UAAU,GAAG;EACf,IAAI,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;EACzC,MAAM,OAAO,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;EAC9C,KAAK,MAAM,IAAI,OAAO,eAAe,KAAK,WAAW,EAAE;EACvD,MAAM,OAAO,IAAI,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;EACvC,KAAK;EACL,GAAG;EAEH,EAAE,WAAW,GAAG;EAChB,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI,CAAC;EAClC,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,OAAO,EAAE,CAAC;EACd,GAAG;EAMH,EAAE,gBAAgB,CAAC,IAAI,EAAE;EACzB,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;EAClD,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;EAC7B,QAAQ,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;EACtF,OAAO;EAEP,MAAM,MAAM,OAAO,GAAGA,OAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;EAC1E,MAAM,IAAI,OAAO,KAAK,OAAO,EAAE;EAC/B,QAAQ,IAAI,CAAC,MAAM,GAAGA,OAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;EACnD,OAAO,MAAM,IAAI,OAAO,KAAK,eAAe,IAAI,OAAO,KAAK,iBAAiB,EAAE;EAC/E,QAAQ,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;EACrC,OAAO,MAAM;EACb,QAAQ,MAAM,IAAI,KAAK,CAAC,4CAA4C,GAAG,OAAO,CAAC,CAAC;EAChF,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;EACpC,QAAQ,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;EAC3E,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;EACvB,GAAG;EAEH,EAAE,eAAe,GAAG;EACpB,IAAI,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,eAAe,GAAG,cAAc,CAAC;EAC5F,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE;EACzB,MAAM,MAAM,wBAAwB,GAAG,GAAE;EACzC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACvD,QAAQ,MAAM;EACd,UAAU,IAAI;EACd,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC/B,QAAQ,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,QAAQ,GAAG,IAAI,EAAE,sBAAsB,GAAG,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,EAAE,sBAAsB,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;EAC7K,OAAO;EACP,MAAM,IAAI,CAAC,wBAAwB,GAAG,wBAAwB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EACxE,KAAK;EACL,IAAI,MAAM,eAAe,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;EAC9E,IAAI,IAAI,CAAC,iBAAiB,GAAG,eAAe,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;EACrE,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;EAC7C,MAAM,IAAI,CAAC,UAAU,GAAG,eAAe,CAAC,mBAAmB,EAAE,CAAC;EAC9D,KAAK;EACL,GAAG;EASH,EAAE,KAAK,GAAG;EACV,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;EACnC,IAAI,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;EACrC,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;EAE3B,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,MAAM;EACZ,QAAQ,MAAM;EACd,QAAQ,MAAM;EACd,OAAO,GAAG,IAAI,CAAC;EACf,MAAM,IAAI,CAAC,MAAM,EAAE;EACnB,QAAQ,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;EAC1E,OAAO;EACP,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;EAC9B,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EACpC,MAAM,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;EAC3B,MAAM,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;EAC7B,MAAM,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACpE,MAAM,IAAI,CAAC,UAAU,GAAG,IAAI,iBAAiB,CAAC,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;EAClE,KAAK;EAEL,IAAI,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;EAChD,IAAI,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;EAErC,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE;EACpB,MAAM,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;EACtC,MAAM,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;EAChC,KAAK;EAEL,IAAI,IAAI;EACR,MAAM,IAAI,CAAC,GAAG,GAAG,IAAI,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;EAC7D,KAAK,CAAC,OAAO,CAAC,EAAE;EAChB,MAAM,OAAO,CAAC,KAAK,CAAC,8CAA8C,EAAE,CAAC,CAAC,CAAC;EACvE,KAAK;EACL,GAAG;EAEH,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;EACpB,IAAI,IAAI,OAAO,CAAC,KAAK,WAAW,EAAE;EAClC,MAAM,CAAC,GAAG,CAAC,CAAC;EACZ,KAAK;EAEL,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;EAC5B,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;EAC5B,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;EAC5B,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;EAE5B,IAAI,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;EACjC,IAAI,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;EAElC,IAAI,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;EAC5B,IAAI,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;EAEzC,IAAI,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;EAEhC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;EACvC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;EACvC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;EACvC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;EACvC,GAAG;EAYH,EAAE,eAAe,GAAG;EACpB,IAAI,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI,EAAE,OAAO,IAAI,CAAC,aAAa,CAAC;EAE/D,IAAI,IAAI,kBAAkB,GAAG,IAAI,CAAC;EAClC,IAAI,IAAI;EACR,MAAM,iBAAiB;EACvB,KAAK,GAAG,IAAI,CAAC;EACb,IAAI,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE;EACtC,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,MAAM,CAAC,EAAE,IAAI;EACzD,QAAQ,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC;EAC5C,QAAQ,kBAAkB,GAAG,EAAE,CAAC;EAChC,QAAQ,OAAO,KAAK,CAAC;EACrB,OAAO,EAAC;EACR,KAAK,MAAM;EACX,MAAM,kBAAkB,GAAG,iBAAiB,CAAC,KAAK,EAAE,CAAC;EACrD,KAAK;EACL,IAAI,OAAO,IAAI,CAAC,aAAa,GAAG,CAAC,mBAAmB,GAAG,IAAI,CAAC,iBAAiB,EAAE,EAAE;EAC/E,GAAG,IAAI,CAAC,cAAc,IAAI,EAAE,EAAE;;EAE9B,GAAG,IAAI,CAAC,iBAAiB,EAAE,EAAE;UACrB,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,IAAI,OAAO,GAAG,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;IACpF,GAAG,IAAI,CAAC,iBAAiB,EAAE,EAAE;IAC7B,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,EAAE;IAChH,GAAG,iBAAiB,CAAC,MAAM,GAAG,CAAC,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE;IACrE,CAAC,CAAC;EACN,GAAG;EAKH,EAAE,QAAQ,GAAG;EACb,IAAI,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;EACjC,GAAG;EAMH,EAAE,iBAAiB,GAAG;EACtB,IAAI;EACJ,MAAM,IAAI,CAAC,iBAAiB;EAC5B,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;EAC/C,MAAM,QAAQ;EACd,MAAM;EACN,GAAG;EAEH,EAAE,iBAAiB,GAAG;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC;EAEnC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE;EAClC,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;EACzC,MAAM,QAAQ,IAAI;EAClB,QAAQ,KAAK,WAAW,CAAC;EACzB,QAAQ,KAAK,WAAW;EACxB,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,oBAAoB,EAAE,CAAC,CAAC,uCAAuC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EACjG,UAAU,MAAM;EAChB,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,oBAAoB,EAAE,CAAC,CAAC,uCAAuC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EACjG,UAAU,MAAM;EAChB,QAAQ,KAAK,OAAO;EACpB,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,oBAAoB,EAAE,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;EACjF,UAAU,MAAM;EAChB,QAAQ;EACR,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,oBAAoB,EAAE,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;EAC3E,OAAO;EACP,KAAK;EACL,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3B,GAAG;EAEH,EAAE,iBAAiB,GAAG;EACtB,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACxD,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC3D,MAAM,QAAQ,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;EACnC,QAAQ,KAAK,WAAW,CAAC;EACzB,QAAQ,KAAK,WAAW;EACxB,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,YAAY,CAAC,wBAAwB,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;EACxF,UAAU,MAAM;EAChB,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,YAAY,CAAC,wBAAwB,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;EACxF,UAAU,MAAM;EAChB,QAAQ,KAAK,OAAO;EACpB,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,YAAY,CAAC,GAAG,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC;EACxE,UAAU,MAAM;EAChB,QAAQ,KAAK,iBAAiB,CAAC;EAC/B,QAAQ,KAAK,iBAAiB,CAAC;EAC/B,QAAQ,KAAK,iBAAiB,CAAC;EAC/B,QAAQ,KAAK,iBAAiB,CAAC;EAC/B,QAAQ,KAAK,eAAe,CAAC;EAC7B,QAAQ,KAAK,8BAA8B;EAC3C,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC;QACf,EAAE,YAAY,CAAC;;;;;sDAK+B,EAAE,YAAY,CAAC;;QAE7D,EAAE,YAAY,CAAC;;gCAES,EAAE,YAAY,CAAC;QACvC,EAAE,YAAY,CAAC,GAAG,EAAE,YAAY,CAAC;8BACX,EAAE,YAAY,CAAC;;KAExC,CAAC,CAAC,CAAC;EACR,UAAU,MAAM;EAChB,OAAO;EACP,KAAK;EACL,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3B,GAAG;EAEH,EAAE,eAAe,CAAC,KAAK,EAAE;EACzB,IAAI,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;EAC/B,IAAI,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC;EACnE,IAAI,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC;EACvE,IAAI,IAAI,MAAM,CAAC,KAAK,GAAG,KAAK,EAAE;EAC9B,MAAM,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;EAC3B,KAAK;EACL,IAAI,IAAI,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE;EAChC,MAAM,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;EAC7B,KAAK;EACL,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC;EAC7B,IAAI,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;EAC9C,IAAI,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC;EAClE,IAAI,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACzC,IAAI,IAAI,KAAK,GAAG,CAAC,CAAC;EAClB,IAAI,KAAK,IAAI,CAAC,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;EAC1C,MAAM,MAAM,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACnD,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;EACtC,QAAQ,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;EAC1C,QAAQ,KAAK,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC;EAC7C,QAAQ,KAAK,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC;EAC7C,QAAQ,KAAK,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC;EAC7C,QAAQ,KAAK,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC;EAC7C,QAAQ,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;EACvB,OAAO;EACP,KAAK;EACL,IAAI,OAAO,UAAU,CAAC;EACtB,GAAG;EAEH,EAAE,SAAS,CAAC,IAAI,EAAE;EAClB,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;EAExC,IAAI,OAAO,IAAI,GAAGA,OAAK,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;EACxG,GAAG;EAEH,EAAE,eAAe,CAAC,MAAM,EAAE;EAC1B,IAAI,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;EACjD,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC5C,MAAM,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACvD,KAAK;EACL,IAAI,OAAO,WAAW,CAAC;EACvB,GAAG;EAEH,EAAE,iBAAiB,CAAC,YAAY,EAAE;EAClC,IAAI,QAAQ,IAAI,CAAC,MAAM,CAAC,MAAM;EAC9B,MAAM,KAAK,CAAC;EACZ,QAAQ,OAAO,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;EAC7E,MAAM,KAAK,CAAC;EACZ,QAAQ,OAAO,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;EAC7E,MAAM,KAAK,CAAC;EACZ,QAAQ,OAAO,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;EAC7E,MAAM;EACN,QAAQ,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;EACnD,KAAK;EACL,GAAG;EAEH,EAAE,oBAAoB,CAAC,kBAAkB,EAAE;EAC3C,IAAI,QAAQ,IAAI,CAAC,MAAM,CAAC,MAAM;EAC9B,MAAM,KAAK,CAAC;EACZ,QAAQ,OAAO,IAAI,CAAC,sBAAsB,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;EACzF,MAAM;EACN,QAAQ,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;EACnD,KAAK;EACL,GAAG;EAEH,EAAE,gBAAgB,GAAG;EACrB,IAAI,OAAO,CAAC;;;WAGD,CAAC;EACZ,GAAG;EAEH,EAAE,qCAAqC,GAAG;EAC1C,IAAI,QAAQ,IAAI,CAAC,UAAU;EAC3B,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,OAAO;EAClB,QAAQ,OAAO,cAAc,CAAC;EAC9B,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU;EACrB,QAAQ,OAAO,OAAO,CAAC;EACvB,MAAM;EACN,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE;EAC5B,UAAU,OAAO,cAAc,CAAC;EAChC,SAAS;EACT,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,qBAAqB,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;EACrE,KAAK;EACL,GAAG;EAEH,EAAE,mBAAmB,CAAC,YAAY,EAAE;AACpC,EAGA,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,qCAAqC,EAAE,CAAC;EAC3E,IAAI,OAAO,CAAC;uBACW,EAAE,iBAAiB,CAAC;IACvC,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;IAC7H,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;;;;;MAK9F,GAAG,YAAY,EAAE;KAClB,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,mBAAmB,CAAC,YAAY,EAAE;AACpC,EAGA,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,qCAAqC,EAAE,CAAC;EAC3E,IAAI,OAAO,CAAC;;;IAGR,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;IAC9G,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;;;;sCAI9D,EAAE,iBAAiB,CAAC;MACpD,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;;;QAGtJ,GAAG,YAAY,EAAE;;KAEpB,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,sBAAsB,CAAC,YAAY,EAAE;AACvC,EAGA,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,qCAAqC,EAAE,CAAC;EAC3E,IAAI,OAAO,CAAC;;IAER,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;IAC9G,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;;;;MAI9F,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;;;QAGtJ,GAAG,YAAY,EAAE;;KAEpB,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,mBAAmB,CAAC,YAAY,EAAE;AACpC,EAGA,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,qCAAqC,EAAE,CAAC;EAC3E,IAAI,OAAO,CAAC;;;;IAIR,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;IAC9G,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;;;;MAI9F,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;;;yCAG5G,EAAE,iBAAiB,CAAC;QACrD,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;;;UAG/J,GAAG,YAAY,EAAE;;;KAGtB,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,aAAa,GAAG;EAClB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;EAC1B,MAAM,OAAO,sBAAsB,CAAC;EACpC,KAAK;EACL,IAAI,OAAO,CAAC;;MAEN,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,GAAG,SAAS,CAAC,QAAQ,EAAE,SAAS,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE;MAC9G,CAAC,CAAC;EACR,GAAG;EAEH,EAAE,cAAc,CAAC,EAAE,EAAE;EACrB,IAAI,OAAO,IAAI,CAAC,UAAU,KAAK,IAAI,GAAG,CAAC,EAAE,CAAC;EAC1C,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;EAC9B,GAAG;EAIH,EAAE,OAAO,CAAC,qBAAqB,EAAE;EACjC,IAAI,IAAI,qBAAqB,EAAE;EAC/B,MAAM,OAAO,IAAI,CAAC,MAAM,CAAC;EACzB,KAAK;EACL,GAAG;EAEH,EAAE,OAAO,cAAc,CAAC,OAAO,EAAE,EAAE;EAEnC,EAAE,MAAM,GAAG;EACX,IAAI,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;EAChC,IAAI,IAAI,CAAC,aAAa,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,MAAM,EAAE,CAAC;EACpF,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,SAAS,CAAC,MAAM,EAAE;EACpB,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;EAC5B,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;EACxC,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACpE,MAAM,IAAI,CAAC,UAAU,GAAG,IAAI,iBAAiB,CAAC,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;EAClE,KAAK;EACL,GAAG;EACH,CAAC;;EChhBM,MAAM,cAAc,SAAS,OAAO,CAAC;EAC5C,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,eAAe,GAAG;EACpB,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAI,MAAM,WAAW,GAAG,EAAE,CAAC,iBAAiB,EAAE,CAAC;EAC/C,IAAI,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;EACpD,IAAI,EAAE,CAAC,oBAAoB;EAC3B,MAAM,EAAE,CAAC,WAAW;EACpB,MAAM,EAAE,CAAC,iBAAiB;EAC1B,MAAM,EAAE,CAAC,UAAU;EACnB,MAAM,IAAI,CAAC,OAAO;EAClB,MAAM,CAAC;EACP,KAAK,CAAC;EACN,IAAI,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;EACrE,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC/E,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,YAAY,GAAG;EACjB,IAAI,OAAO,IAAI,CAAC,eAAe,EAAE,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,UAAU,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACjE,GAAG;EACH,CAAC;;EC1BM,MAAM,oBAAoB,SAAS,cAAc,CAAC;EACzD,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAClF,GAAG;EACH,CAAC;;ECRM,MAAM,sBAAsB,SAAS,cAAc,CAAC;EAC3D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,GAAG;EACH,CAAC;;ECRM,MAAM,sBAAsB,SAAS,cAAc,CAAC;EAC3D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACpG,GAAG;EACH,CAAC;;ECRM,MAAM,oBAAoB,SAAS,cAAc,CAAC;EACzD,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAClE,GAAG;EACH,CAAC;;ECRM,MAAM,sBAAsB,SAAS,cAAc,CAAC;EAC3D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,GAAG;EACH,CAAC;;ECRM,MAAM,sBAAsB,SAAS,cAAc,CAAC;EAC3D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACpG,GAAG;EACH,CAAC;;ECRM,MAAM,oBAAoB,SAAS,cAAc,CAAC;EACzD,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAClE,GAAG;EACH,CAAC;;ECRM,MAAM,sBAAsB,SAAS,cAAc,CAAC;EAC3D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,GAAG;EACH,CAAC;;ECRM,MAAM,sBAAsB,SAAS,cAAc,CAAC;EAC3D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACpG,GAAG;EACH,CAAC;;ECRM,MAAM,gBAAgB,SAAS,cAAc,CAAC;EACrD,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACnF,GAAG;EACH,CAAC;;ECRM,MAAM,gBAAgB,SAAS,cAAc,CAAC;EACrD,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACnG,GAAG;EACH,CAAC;;ECRM,MAAM,wBAAwB,SAAS,cAAc,CAAC;EAC7D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAC;EAC/C,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,yBAAyB,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAChF,GAAG;EACH,CAAC;;ECRM,MAAM,0BAA0B,SAAS,cAAc,CAAC;EAC/D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAC;EAC/C,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,2BAA2B,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAClG,GAAG;EACH,CAAC;;ECRM,MAAM,0BAA0B,SAAS,cAAc,CAAC;EAC/D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAC;EAC/C,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,2BAA2B,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAClH,GAAG;EACH,CAAC;;ECRM,MAAM,iBAAiB,SAAS,OAAO,CAAC;EAC/C,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;EAChC,GAAG;EACH,EAAE,eAAe,GAAG;EACpB,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAI,MAAM,WAAW,GAAG,EAAE,CAAC,iBAAiB,EAAE,CAAC;EAC/C,IAAI,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;EACpD,IAAI,EAAE,CAAC,oBAAoB;EAC3B,MAAM,EAAE,CAAC,WAAW;EACpB,MAAM,EAAE,CAAC,iBAAiB;EAC1B,MAAM,EAAE,CAAC,UAAU;EACnB,MAAM,IAAI,CAAC,OAAO;EAClB,MAAM,CAAC;EACP,KAAK,CAAC;EACN,IAAI,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;EACnE,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;EACvF,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,YAAY,GAAG;EACjB,IAAI,OAAO,IAAI,YAAY,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,MAAM,CAAC,CAAC;EAC3D,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACvE,GAAG;EACH,CAAC;;EC1BM,MAAM,mBAAmB,SAAS,iBAAiB,CAAC;EAC3D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;EAChC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACzF,GAAG;EACH,CAAC;;ECRM,MAAM,mBAAmB,SAAS,iBAAiB,CAAC;EAC3D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;EAChC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACzG,GAAG;EACH,CAAC;;ECTM,MAAM,kBAAkB,SAAS,iBAAiB,CAAC;EAC1D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAO,IAAI,CAAC,YAAY,EAAE,CAAC;EAC/B,GAAG;EACH,CAAC;;ECgBM,MAAM,QAAQ,SAAS,MAAM,CAAC;EACrC,EAAE,WAAW,IAAI,GAAG;EACpB,IAAI,OAAO,KAAK,CAAC;EACjB,GAAG;EAEH,EAAE,OAAO,cAAc,GAAG;EAC1B,IAAI,MAAM,YAAY,GAAG,CAAC;;KAErB,CAAC,CAAC;EACP,IAAI,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,YAAY,EAAE;EAC1C,MAAM,OAAO,EAAE,IAAI,CAAC,WAAW;EAC/B,MAAM,MAAM,EAAE,IAAI,CAAC,UAAU;EAC7B,MAAM,QAAQ,EAAE,KAAK;EACrB,MAAM,MAAM,EAAE,CAAC,CAAC,CAAC;EACjB,MAAM,SAAS,EAAE,QAAQ;EACzB,MAAM,UAAU,EAAE,QAAQ;EAC1B,MAAM,MAAM,EAAE,OAAO;EACrB,KAAK,CAAC,CAAC;EACP,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;EACnB,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC;EACjB,IAAI,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;EACzC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EACzB,IAAI,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;EAC3B,GAAG;EAEH,EAAE,OAAO,4BAA4B,GAAG;EACxC,IAAI,SAAS,cAAc,CAAC,EAAE,EAAE,EAAE,EAAE;EACpC,MAAM,OAAO,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;EACnD,KAAK;EACL,IAAI,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,EAAE;EACvD,MAAM,OAAO,EAAE,IAAI,CAAC,WAAW;EAC/B,MAAM,MAAM,EAAE,IAAI,CAAC,UAAU;EAC7B,MAAM,QAAQ,EAAE,KAAK;EACrB,MAAM,MAAM,EAAE,CAAC,CAAC,CAAC;EACjB,MAAM,UAAU,EAAE,QAAQ;EAC1B,MAAM,SAAS,EAAE,UAAU;EAC3B,MAAM,MAAM,EAAE,OAAO;EACrB,KAAK,CAAC,CAAC;EACP,IAAI,MAAM,IAAI,GAAG;EACjB,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC;EAClB,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC;EACf,KAAK,CAAC;EACN,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;EACrC,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;EACnC,IAAI,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;EACzC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EAGzB,IAAI,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;EACjD,GAAG;EAKH,EAAE,WAAW,UAAU,GAAG;EAC1B,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,4BAA4B,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAClE,GAAG;EAKH,EAAE,WAAW,WAAW,GAAG;EAC3B,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,6BAA6B,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACnE,GAAG;EAKH,EAAE,WAAW,QAAQ,GAAG;EACxB,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,0BAA0B,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAChE,GAAG;EAKH,EAAE,OAAO,kBAAkB,GAAG;EAC9B,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oCAAoC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC1E,GAAG;EAMH,EAAE,6BAA6B,CAAC,GAAG,EAAE;EACrC,IAAI,IAAI,CAAC,0BAA0B,GAAG,GAAG,CAAC;EAC1C,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAMH,EAAE,YAAY,CAAC,IAAI,EAAE;EACrB,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAC1B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,gBAAgB,CAAC,IAAI,EAAE;EACzB,IAAIA,OAAK,CAAC,cAAc,CAAC,QAAQ,EAAE,kBAAkB,EAAE,wBAAwB,CAAC,CAAC;EACjF,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;EAC9B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,OAAO,uBAAuB,CAAC,MAAM,EAAE;EACzC,IAAI,MAAM,aAAa,GAAG,EAAE,CAAC;EAC7B,IAAI,MAAM,aAAa,GAAG,EAAE,CAAC;EAC7B,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,MAAM,sBAAsB,GAAG,YAAY,CAAC;EAChD,IAAI,MAAM,cAAc,GAAG,cAAc,CAAC;EAC1C,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;EACd,IAAI,IAAI,YAAY,GAAG,IAAI,CAAC;EAC5B,IAAI,IAAI,YAAY,GAAG,IAAI,CAAC;EAC5B,IAAI,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE;EAC9B,MAAM,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;EAC7B,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;EACrC,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC;EAGzE,MAAM,IAAI,KAAK,KAAK,oBAAoB,IAAI,IAAI,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,EAAE;EAC9E,QAAQ,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;EAC1C,QAAQ,CAAC,IAAI,CAAC,CAAC;EACf,QAAQ,SAAS;EACjB,OAAO,MAAM,IAAI,KAAK,KAAK,oBAAoB,IAAI,IAAI,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,EAAE;EACrF,QAAQ,MAAM,CAAC,GAAG,EAAE,CAAC;EACrB,QAAQ,CAAC,IAAI,CAAC,CAAC;EACf,QAAQ,SAAS;EACjB,OAAO;EAIP,WAAW,IAAI,KAAK,KAAK,oBAAoB,IAAI,IAAI,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,EAAE;EACnF,QAAQ,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EAC/B,QAAQ,CAAC,IAAI,CAAC,CAAC;EACf,QAAQ,SAAS;EACjB,OAAO,MAAM,IAAI,KAAK,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,EAAE;EACvD,QAAQ,MAAM,CAAC,GAAG,EAAE,CAAC;EACrB,QAAQ,CAAC,EAAE,CAAC;EACZ,QAAQ,SAAS;EACjB,OAAO;EAIP,WAAW,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI,KAAK,GAAG,EAAE;EAC/C,QAAQ,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;EAC1C,QAAQ,CAAC,EAAE,CAAC;EACZ,QAAQ,SAAS;EACjB,OAAO,MAAM,IAAI,KAAK,KAAK,oBAAoB,EAAE;EACjD,QAAQ,IAAI,IAAI,KAAK,GAAG,EAAE;EAC1B,UAAU,MAAM,CAAC,GAAG,EAAE,CAAC;EACvB,UAAU,MAAM;EAChB,SAAS;EACT,QAAQ,IAAI,IAAI,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE;EAClJ,UAAU,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;EAC1C,UAAU,YAAY,GAAG,OAAO,CAAC;EACjC,UAAU,YAAY,GAAG,EAAE,CAAC;EAC5B,UAAU,CAAC,IAAI,CAAC,CAAC;EACjB,UAAU,SAAS;EACnB,SAAS,MAAM,IAAI,IAAI,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE;EACvG,UAAU,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;EAC1C,UAAU,YAAY,GAAG,KAAK,CAAC;EAC/B,UAAU,YAAY,GAAG,EAAE,CAAC;EAC5B,UAAU,CAAC,IAAI,CAAC,CAAC;EACjB,UAAU,SAAS;EACnB,SAAS,MAAM,IAAI,IAAI,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE;EAChI,UAAU,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;EAC1C,UAAU,YAAY,GAAG,MAAM,CAAC;EAChC,UAAU,YAAY,GAAG,EAAE,CAAC;EAC5B,UAAU,CAAC,IAAI,CAAC,CAAC;EACjB,UAAU,SAAS;EACnB,SAAS,MAAM,IAAI,IAAI,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE;EAChI,UAAU,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;EAC1C,UAAU,YAAY,GAAG,MAAM,CAAC;EAChC,UAAU,YAAY,GAAG,EAAE,CAAC;EAC5B,UAAU,CAAC,IAAI,CAAC,CAAC;EACjB,UAAU,SAAS;EACnB,SAAS,MAAM,IAAI,IAAI,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE;EAChI,UAAU,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;EAC1C,UAAU,YAAY,GAAG,MAAM,CAAC;EAChC,UAAU,YAAY,GAAG,EAAE,CAAC;EAC5B,UAAU,CAAC,IAAI,CAAC,CAAC;EACjB,UAAU,SAAS;EACnB,SAAS;EACT,OAAO;EAIP,WAAW,IAAI,KAAK,KAAK,kBAAkB,EAAE;EAC7C,QAAQ,IAAI,YAAY,KAAK,EAAE,EAAE;EACjC,UAAU,IAAI,IAAI,KAAK,GAAG,EAAE;EAC5B,YAAY,CAAC,EAAE,CAAC;EAChB,YAAY,SAAS;EACrB,WAAW;EACX,UAAU,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;EAClD,YAAY,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;EACpE,WAAW;EACX,SAAS;EACT,QAAQ,YAAY,IAAI,IAAI,CAAC;EAC7B,QAAQ,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;EAC5C,UAAU,MAAM,CAAC,GAAG,EAAE,CAAC;EACvB,UAAU,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAC3C,UAAU,aAAa,CAAC,IAAI,CAACE,SAAO,CAAC,YAAY,CAAC,CAAC,CAAC;EACpD,SAAS;EACT,OAAO;EAIP,MAAM,CAAC,EAAE,CAAC;EACV,KAAK;EACL,IAAI,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;EAC3B,MAAM,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;EACxD,KAAK;EACL,IAAI,OAAO;EACX,MAAM,aAAa;EACnB,MAAM,aAAa;EACnB,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,OAAO,wBAAwB,CAAC,MAAM,EAAE;EAC1C,IAAI,OAAOA,SAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1D,GAAG;EAEH,EAAE,OAAO,cAAc,CAAC,cAAc,EAAE,UAAU,EAAE;EACpD,IAAI,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;EAC1C,IAAI,MAAM;EACV,MAAM,OAAO;EACb,MAAM,OAAO;EACb,MAAM,SAAS;EACf,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC;EAC3B,IAAI,IAAI,MAAM,CAAC;EACf,IAAI,IAAI,UAAU,CAAC,SAAS,KAAK,QAAQ,EAAE;EAC3C,MAAM,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EAC3B,MAAM,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;EAC1C,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;EAC/C,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC9E,KAAK,MAAM;EACX,MAAM,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;EAChE,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;EACnG,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;EAC9C,KAAK;EAEL,IAAI,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;EAE5E,IAAI,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;EACxC,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;EAC/C,MAAM,OAAOF,OAAK,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAC5D,KAAK,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;EAC/C,MAAM,MAAM,IAAI,GAAGA,OAAK,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACzF,MAAM,OAAO,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;EAClC,QAAQ,OAAOA,OAAK,CAAC,UAAU,CAAC,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACzD,OAAO,CAAC,CAAC;EACT,KAAK;EACL,GAAG;EAEH,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE;EAChC,IAAI,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;EAC5B,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;EAC/B,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;EAC7B,IAAI,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;EACnC,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;EAC7B,IAAI,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;EAChC,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;EACxB,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;EACjC,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;EAC/B,IAAI,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC;EACvC,IAAI,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;EACrC,GAAG;EAEH,EAAE,gBAAgB,GAAG;EACrB,IAAI,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC;EAC1C,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,cAAc,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,cAAc,EAAE;EAChG,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,qDAAqD,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;EACxL,KAAK;EACL,GAAG;EAEH,EAAE,eAAe,GAAG;EACpB,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,iCAAiC,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EACjF,GAAG;EAOH,EAAE,kBAAkB,CAAC,IAAI,EAAE;EAC3B,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,4BAA4B,CAAC;EAC/D,MAAM,IAAI,CAAC,cAAc,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC;EAC/C,MAAM,IAAI,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;EACnD,MAAM,OAAO,IAAI,CAAC;EAClB,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,UAAU,EAAE;EACvC,MAAM,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,4BAA4B,CAAC;EAC/D,MAAM,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,8BAA8B,CAAC;EAChE,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE;EACzB,QAAQ,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC;EAC/C,QAAQ,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;EACtC,UAAU,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,uBAAuB,CAAC;EAC5D,SAAS;EACT,QAAQ,QAAQ,IAAI,CAAC,UAAU;EAC/B,UAAU,KAAK,gBAAgB,CAAC;EAChC,UAAU,KAAK,OAAO,CAAC;EACvB,UAAU,KAAK,QAAQ,CAAC;EACxB,UAAU,KAAK,SAAS;EACxB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,mBAAmB,CAAC;EAC5D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,mBAAmB,CAAC;EAC5D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,iBAAiB,CAAC;EAC1D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,kBAAkB,CAAC;EACtE,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU,CAAC;EAC1B,UAAU,KAAK,UAAU,CAAC;EAC1B,UAAU,KAAK,UAAU;EACzB,YAAY,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC9C,SAAS;EACT,OAAO,MAAM;EACb,QAAQ,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;EACtC,UAAU,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,qBAAqB,CAAC;EAC1D,SAAS;EACT,QAAQ,QAAQ,IAAI,CAAC,UAAU;EAC/B,UAAU,KAAK,gBAAgB,CAAC;EAChC,UAAU,KAAK,OAAO,CAAC;EACvB,UAAU,KAAK,QAAQ,CAAC;EACxB,UAAU,KAAK,SAAS;EACxB,YAAY,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;EAClD,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,mBAAmB,CAAC;EAC5D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,kBAAkB,CAAC;EAC3D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,mBAAmB,CAAC;EAC5D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,kBAAkB,CAAC;EAC3D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,iBAAiB,CAAC;EAC1D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,kBAAkB,CAAC;EACtE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,gBAAgB,CAAC;EACzD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EAEb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU,CAAC;EAC1B,UAAU,KAAK,UAAU,CAAC;EAC1B,UAAU,KAAK,UAAU;EACzB,YAAY,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC9C,SAAS;EACT,OAAO;EACP,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE;EAC5C,MAAM,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,6BAA6B,CAAC;EAChE,MAAM,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,6BAA6B,CAAC;EAC/D,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE;EACzB,QAAQ,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,YAAY,CAAC;EAC1D,QAAQ,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC;EAC/C,QAAQ,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;EACtC,UAAU,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,uBAAuB,CAAC;EAC5D,SAAS;EACT,QAAQ,QAAQ,IAAI,CAAC,UAAU;EAC/B,UAAU,KAAK,gBAAgB,CAAC;EAChC,UAAU,KAAK,OAAO,CAAC;EACvB,UAAU,KAAK,QAAQ,CAAC;EACxB,UAAU,KAAK,SAAS;EACxB,YAAY,IAAI,IAAI,CAAC,mBAAmB,EAAE;EAC1C,cAAc,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACtC,gBAAgB,IAAI,CAAC,kBAAkB,GAAG,0BAA0B,CAAC;EACrE,gBAAgB,OAAO,IAAI,CAAC;EAC5B,eAAe,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC7C,gBAAgB,IAAI,CAAC,kBAAkB,GAAG,0BAA0B,CAAC;EACrE,gBAAgB,OAAO,IAAI,CAAC;EAC5B,eAAe,MAAM;EACrB,gBAAgB,IAAI,CAAC,kBAAkB,GAAG,wBAAwB,CAAC;EACnE,gBAAgB,OAAO,IAAI,CAAC;EAC5B,eAAe;EACf,aAAa,MAAM;EACnB,cAAc,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACtC,gBAAgB,IAAI,CAAC,kBAAkB,GAAG,gBAAgB,CAAC;EAC3D,gBAAgB,OAAO,IAAI,CAAC;EAC5B,eAAe,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC7C,gBAAgB,IAAI,CAAC,kBAAkB,GAAG,gBAAgB,CAAC;EAC3D,gBAAgB,OAAO,IAAI,CAAC;EAC5B,eAAe,MAAM;EACrB,gBAAgB,IAAI,CAAC,kBAAkB,GAAG,cAAc,CAAC;EACzD,gBAAgB,OAAO,IAAI,CAAC;EAC5B,eAAe;EACf,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,oBAAoB,CAAC;EAC7D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,oBAAoB,CAAC;EAC7D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,oBAAoB,CAAC;EAC7D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,SAAS;EACT,OAAO;EACP,MAAM,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;EAC5C,MAAM,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;EACpC,QAAQ,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,qBAAqB,CAAC;EACxD,OAAO;EACP,MAAM,IAAI,IAAI,CAAC,mBAAmB,EAAE;EACpC,QAAQ,QAAQ,IAAI,CAAC,UAAU;EAC/B,UAAU,KAAK,gBAAgB,CAAC;EAChC,UAAU,KAAK,OAAO,CAAC;EACvB,UAAU,KAAK,QAAQ,CAAC;EACxB,UAAU,KAAK,SAAS;EACxB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,0BAA0B,CAAC;EACnE,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,iDAAiD,CAAC;EACrG,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,2BAA2B,CAAC;EACpE,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,0BAA0B,CAAC;EACnE,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,iDAAiD,CAAC;EACrG,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,2BAA2B,CAAC;EACpE,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,wBAAwB,CAAC;EACjE,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,+CAA+C,CAAC;EACnG,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,yBAAyB,CAAC;EAClE,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,oBAAoB,CAAC;EAC7D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,kBAAkB,CAAC;EACtE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,WAAW,CAAC;EACpD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,oBAAoB,CAAC;EAC7D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,kBAAkB,CAAC;EACtE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,WAAW,CAAC;EACpD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,oBAAoB,CAAC;EAC7D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,kBAAkB,CAAC;EACtE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,WAAW,CAAC;EACpD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,SAAS;EACT,OAAO,MAAM;EACb,QAAQ,QAAQ,IAAI,CAAC,UAAU;EAC/B,UAAU,KAAK,gBAAgB,CAAC;EAChC,UAAU,KAAK,OAAO,CAAC;EACvB,UAAU,KAAK,QAAQ,CAAC;EACxB,UAAU,KAAK,SAAS;EACxB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,gBAAgB,CAAC;EACzD,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,mBAAmB,CAAC;EACvE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,YAAY,CAAC;EACrD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,gBAAgB,CAAC;EACzD,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,mBAAmB,CAAC;EACvE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,YAAY,CAAC;EACrD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,cAAc,CAAC;EACvD,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,iBAAiB,CAAC;EACrE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,UAAU,CAAC;EACnD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,oBAAoB,CAAC;EAC7D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,kBAAkB,CAAC;EACtE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,WAAW,CAAC;EACpD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,oBAAoB,CAAC;EAC7D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,kBAAkB,CAAC;EACtE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,WAAW,CAAC;EACpD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,oBAAoB,CAAC;EAC7D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,kBAAkB,CAAC;EACtE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,WAAW,CAAC;EACpD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,SAAS;EACT,OAAO;EACP,KAAK,MAAM;EACX,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,wBAAwB,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;EACpE,KAAK;EAEL,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;EAClE,GAAG;EAMH,EAAE,eAAe,GAAG;EACpB,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAEH,EAAE,oBAAoB,GAAG;EACzB,IAAI,QAAQ,IAAI,CAAC,UAAU;EAC3B,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,OAAO,CAAC;EACnB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,QAAQ;EACnB,QAAQ,OAAO,IAAI,CAAC,0BAA0B,EAAE,CAAC;EACjD,MAAM,KAAK,UAAU;EACrB,QAAQ,OAAO,IAAI,CAAC,0BAA0B,EAAE,CAAC;EACjD,MAAM,KAAK,UAAU;EACrB,QAAQ,OAAO,IAAI,CAAC,0BAA0B,EAAE,CAAC;EACjD,MAAM,KAAK,UAAU;EACrB,QAAQ,OAAO,IAAI,CAAC,0BAA0B,EAAE,CAAC;EACjD,MAAM;EACN,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,0BAA0B,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;EAC1E,KAAK;EACL,GAAG;EAMH,EAAE,gCAAgC,GAAG;EACrC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAKH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAKH,EAAE,gCAAgC,GAAG;EACrC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAKH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAKH,EAAE,gCAAgC,GAAG;EACrC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAKH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAKH,EAAE,gCAAgC,GAAG;EACrC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAKH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAKH,EAAE,sBAAsB,GAAG;EAC3B,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAKH,EAAE,kCAAkC,GAAG;EACvC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAKH,EAAE,yBAAyB,GAAG;EAC9B,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAEH,EAAE,mBAAmB,GAAG;EACxB,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,OAAO,IAAI,CAAC,sBAAsB,EAAE,CAAC;EAC3C,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE;EAC5C,MAAM,IAAI,IAAI,CAAC,mBAAmB,EAAE;EACpC,QAAQ,OAAO,IAAI,CAAC,kCAAkC,EAAE,CAAC;EACzD,OAAO;EACP,MAAM,OAAO,IAAI,CAAC,oBAAoB,EAAE,CAAC;EACzC,KAAK,MAAM;EACX,MAAM,OAAO,IAAI,CAAC,yBAAyB,EAAE,CAAC;EAC9C,KAAK;EACL,GAAG;EAEH,EAAE,0BAA0B,GAAG;EAC/B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,gCAAgC,EAAE,CAAC;EACvE,MAAMA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,mCAAmC,EAAE,CAAC,CAAC;EACtE,GAAG;EAEH,EAAE,0BAA0B,GAAG;EAC/B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,gCAAgC,EAAE,CAAC;EACvE,MAAMA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,mCAAmC,EAAE,CAAC,CAAC;EACtE,GAAG;EAEH,EAAE,0BAA0B,GAAG;EAC/B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,gCAAgC,EAAE,CAAC;EACvE,MAAMA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,mCAAmC,EAAE,CAAC,CAAC;EACtE,GAAG;EAEH,EAAE,0BAA0B,GAAG;EAC/B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,gCAAgC,EAAE,CAAC;EACvE,MAAMA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,mCAAmC,EAAE,CAAC,CAAC;EACtE,GAAG;EAMH,EAAE,yBAAyB,GAAG;EAC9B,IAAI,QAAQ,IAAI,CAAC,MAAM;EACvB,MAAM,KAAK,OAAO;EAClB,QAAQ,OAAO,yBAAyB,CAAC;EACzC,MAAM,KAAK,aAAa;EACxB,QAAQ,OAAO,0BAA0B,CAAC;EAC1C,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM;EACN,QAAQ,OAAO,4BAA4B,CAAC;EAC5C,KAAK;EACL,GAAG;EAMH,EAAE,uBAAuB,GAAG;EAC5B,IAAI,QAAQ,IAAI,CAAC,MAAM;EACvB,MAAM,KAAK,OAAO;EAClB,QAAQ,OAAO,uBAAuB,CAAC;EACvC,MAAM,KAAK,aAAa;EACxB,QAAQ,OAAO,wBAAwB,CAAC;EACxC,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM;EACN,QAAQ,OAAO,0BAA0B,CAAC;EAC1C,KAAK;EACL,GAAG;EAMH,EAAE,6BAA6B,GAAG;EAClC,IAAI,QAAQ,IAAI,CAAC,MAAM;EACvB,MAAM,KAAK,OAAO;EAClB,QAAQ,OAAO,6BAA6B,CAAC;EAC7C,MAAM,KAAK,aAAa;EACxB,QAAQ,OAAO,8BAA8B,CAAC;EAC9C,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM;EACN,QAAQ,OAAO,gCAAgC,CAAC;EAChD,KAAK;EACL,GAAG;EAEH,EAAE,kCAAkC,GAAG;EACvC,IAAI,QAAQ,IAAI,CAAC,MAAM;EACvB,MAAM,KAAK,OAAO;EAClB,QAAQ,OAAO,kCAAkC,CAAC;EAClD,MAAM,KAAK,aAAa;EACxB,QAAQ,OAAO,mCAAmC,CAAC;EACnD,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM;EACN,QAAQ,OAAO,qCAAqC,CAAC;EACrD,KAAK;EACL,GAAG;EAEH,EAAE,aAAa,GAAG;EAClB,IAAI,OAAO,IAAI,IAAI,CAAC,kBAAkB,CAAC;EACvC,MAAM,OAAO,EAAE,IAAI,CAAC,aAAa;EACjC,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO;EACxB,MAAM,UAAU,EAAE,IAAI,CAAC,SAAS;EAChC,MAAM,MAAM,EAAE,IAAI,CAAC,MAAM;EACzB,MAAM,OAAO,EAAE,IAAI,CAAC,OAAO;EAC3B,KAAK,CAAC,CAAC;EACP,GAAG;EACH,EAAE,4BAA4B,GAAG;EACjC,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,UAAU,EAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;EACnG,IAAI,MAAM;EACV,MAAM,OAAO;EACb,MAAM,OAAO,EAAE,EAAE;EACjB,KAAK,GAAG,IAAI,CAAC;EACb,IAAI,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;EAC/D,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;EACnF,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,8BAA8B,GAAG;EACnC,IAAI,OAAO,IAAI,YAAY,CAAC,IAAI,CAAC,4BAA4B,EAAE,CAAC,MAAM,CAAC,CAAC;EACxE,GAAG;EAEH,EAAE,6BAA6B,GAAG;EAClC,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;EAC/F,IAAI,MAAM;EACV,MAAM,OAAO;EACb,MAAM,OAAO,EAAE,EAAE;EACjB,KAAK,GAAG,IAAI,CAAC;EACb,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EACzB,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EACzB,IAAI,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;EAC/C,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACzD,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,4CAA4C,GAAG;EACjD,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;EAC/F,IAAI,MAAM;EACV,MAAM,OAAO;EACb,MAAM,OAAO,EAAE,EAAE;EACjB,KAAK,GAAG,IAAI,CAAC;EACb,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EACzB,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EACzB,IAAI,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;EAC/C,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACzD,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAOH,EAAE,SAAS,CAAC,IAAI,EAAE;EAClB,IAAI,MAAM;EACV,MAAM,OAAO,EAAE,EAAE;EACjB,MAAM,MAAM;EACZ,KAAK,GAAG,IAAI,CAAC;EACb,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC;EACnC,IAAI,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;EACtD,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;EAE1E,IAAI,OAAO,IAAI,iBAAiB,CAAC,CAAC,IAAI,GAAG,MAAM,GAAGA,OAAK,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;EACnG,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,MAAM,MAAM,GAAG;EACnB,MAAM,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE;EACjC,KAAK,CAAC;EACN,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,IAAI,IAAI,CAAC,kBAAkB,CAAC;EACxE,QAAQ,OAAO,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC;EAChD,QAAQ,IAAI,EAAE,IAAI,CAAC,OAAO;EAC1B,QAAQ,UAAU,EAAE,IAAI,CAAC,SAAS;EAClC,QAAQ,MAAM,EAAE,IAAI,CAAC,MAAM;EAC3B,QAAQ,OAAO,EAAE,IAAI,CAAC,OAAO;EAC7B,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC;EACnB,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,uBAAuB,GAAG;EAC5B,IAAI,MAAM,MAAM,GAAG;EACnB,MAAM,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE;EACjC,KAAK,CAAC;EACN,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,IAAI,IAAI,CAAC,kBAAkB,CAAC;EACxE,QAAQ,OAAO,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC;EAChD,QAAQ,IAAI,EAAE,IAAI,CAAC,OAAO;EAC1B,QAAQ,UAAU,EAAE,IAAI,CAAC,SAAS;EAClC,QAAQ,MAAM,EAAE,IAAI,CAAC,MAAM;EAC3B,QAAQ,OAAO,EAAE,IAAI,CAAC,OAAO;EAC7B,OAAO,CAAC,CAAC;EACT,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,SAAS,CAAC,MAAM,EAAE;EACpB,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;EAC5B,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE;EACtB,MAAM,IAAI,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EAClF,MAAM,IAAI,CAAC,OAAO,GAAGA,OAAK,CAAC,oBAAoB,CAAC;EAChD,QAAQ,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;EACrD,QAAQ,SAAS,EAAE,IAAI,CAAC,SAAS;EACjC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACtB,MAAM,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACnC,MAAM,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC3D,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;EAC9B,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;EAC/C,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;EAChD,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1E,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC7C,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC9C,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;EACjC,MAAM,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;EACzD,QAAQ,IAAI,CAAC,uBAAuB,EAAE,CAAC;EACvC,OAAO;EACP,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EACH,EAAE,YAAY,GAAG;EACjB,IAAI,OAAO,IAAI,CAAC,YAAY;EAC5B,MAAM,IAAI,CAAC,cAAc,EAAE;EAC3B,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;EACpB,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;EACpB,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;EACpB,KAAK,CAAC;EACN,GAAG;EACH,CAAC;AAED,EAAO,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;EAC5C,EAAE,uBAAuB,EAAE,MAAM,CAAC,yBAAyB,CAAC;EAC5D,EAAE,kBAAkB,EAAE,MAAM,CAAC,oBAAoB,CAAC;EAClD,EAAE,oBAAoB,EAAE,MAAM,CAAC,sBAAsB,CAAC;EACtD,EAAE,oBAAoB,EAAE,MAAM,CAAC,sBAAsB,CAAC;EACtD,EAAE,aAAa,EAAE,MAAM,CAAC,eAAe,CAAC;EACxC,EAAE,wBAAwB,EAAE,MAAM,CAAC,0BAA0B,CAAC;EAC9D,EAAE,iBAAiB,EAAE,MAAM,CAAC,mBAAmB,CAAC;EAChD,EAAE,mBAAmB,EAAE,MAAM,CAAC,qBAAqB,CAAC;EACpD,EAAE,mBAAmB,EAAE,MAAM,CAAC,qBAAqB,CAAC;EACpD,EAAE,kBAAkB,EAAE,MAAM,CAAC,oBAAoB,CAAC;EAClD,EAAE,oBAAoB,EAAE,MAAM,CAAC,sBAAsB,CAAC;EACtD,EAAE,oBAAoB,EAAE,MAAM,CAAC,sBAAsB,CAAC;EACtD,EAAE,kBAAkB,EAAE,MAAM,CAAC,oBAAoB,CAAC;EAClD,EAAE,oBAAoB,EAAE,MAAM,CAAC,sBAAsB,CAAC;EACtD,EAAE,oBAAoB,EAAE,MAAM,CAAC,sBAAsB,CAAC;EACtD,EAAE,kBAAkB,EAAE,MAAM,CAAC,oBAAoB,CAAC;EAClD,EAAE,oBAAoB,EAAE,MAAM,CAAC,sBAAsB,CAAC;EACtD,EAAE,oBAAoB,EAAE,MAAM,CAAC,sBAAsB,CAAC;EACtD,EAAE,YAAY,EAAE,MAAM,CAAC,cAAc,CAAC;EACtC,EAAE,+CAA+C,EAAE,MAAM,CAAC,kCAAkC,CAAC;EAC7F,EAAE,iDAAiD,EAAE,MAAM,CAAC,oCAAoC,CAAC;EACjG,EAAE,iDAAiD,EAAE,MAAM,CAAC,oCAAoC,CAAC;EACjG,CAAC,CAAC,CAAC;EAEH,MAAME,SAAO,GAAG;EAChB,EAAE,GAAG,EAAE,SAAS;EAChB,EAAE,KAAK,EAAE,QAAQ;EACjB,EAAE,IAAI,EAAE,UAAU;EAClB,EAAE,IAAI,EAAE,UAAU;EAClB,EAAE,IAAI,EAAE,UAAU;EAClB,CAAC,CAAC;;ECt9BK,MAAM,iBAAiB,SAAS,YAAY,CAAC;EACpD,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE;EAChC,IAAI,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;EAC5B,IAAI,IAAI,QAAQ,IAAI,QAAQ,CAAC,cAAc,CAAC,4BAA4B,CAAC,EAAE;EAC3E,MAAM,IAAI,CAAC,0BAA0B,GAAG,QAAQ,CAAC,0BAA0B,CAAC;EAC5E,KAAK;EACL,GAAG;EAQH,EAAE,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE;EAE3B,IAAI,IAAI,IAAI,CAAC,YAAY,EAAE;EAC3B,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC1B,KAAK,MAAM;AAEX,EACA,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;EAC5B,QAAQ,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;EACjD,QAAQ,IAAI,UAAU,EAAE;EACxB,UAAU,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EACnD,UAAU,IAAI,IAAI,CAAC,UAAU,KAAK,gBAAgB,EAAE;EACpD,YAAY,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC;EACvC,WAAW;EACX,SAAS;EACT,OAAO;EAEP,MAAM,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;EAClC,MAAM,IAAI,CAAC,UAAU,EAAE;EACvB,QAAQ,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC5B,OAAO,MAAM;EACb,QAAQ,MAAM,IAAI,GAAGA,SAAO,CAAC,UAAU,CAAC,CAAC;EACzC,QAAQ,IAAI,CAAC,IAAI,EAAE;EACnB,UAAU,MAAM,IAAI,KAAK,CAAC,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;EACxD,SAAS;EACT,QAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC1B,OAAO;EACP,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC3B,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAErB,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;EAE5B,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EAC1D,QAAQ,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;EAEnD,QAAQ,IAAI,CAAC,GAAG,CAAC,EAAE;EACnB,UAAU,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC5B,SAAS;EACT,QAAQ,IAAI,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;EAExF,QAAQ,IAAI,CAAC,YAAY,EAAE;EAC3B,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,iBAAiB,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;EAClF,SAAS;EACT,QAAQ,IAAI,YAAY,KAAK,gBAAgB,EAAE;EAC/C,UAAU,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,YAAY,GAAG,QAAQ,CAAC;EAC1D,SAAS;EACT,QAAQ,MAAM,IAAI,GAAGA,SAAO,CAAC,YAAY,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,IAAI,EAAE;EACnB,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EAClE,SAAS;EACT,QAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC1B,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC7B,QAAQ,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAClC,OAAO;EACP,KAAK;EAGL,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAGzB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACnD,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EAChD,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EACxB,KAAK;EAGL,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACvB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE;EAClC,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,cAAc,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;EACrF,IAAI,IAAI,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC;EAC9C,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC5C,IAAI,IAAI,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC;EAE7C,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EAEtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;EAC1B,MAAM,IAAI,IAAI,KAAK,gBAAgB,IAAI,IAAI,KAAK,SAAS,EAAE;EAC3D,QAAQ,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC;EACnC,OAAO,MAAM;EACb,QAAQ,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EAC/B,OAAO;EACP,KAAK;EAEL,IAAI,QAAQ,IAAI,CAAC,UAAU;EAC3B,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,OAAO;EAClB,QAAQ,QAAQ,IAAI;EACpB,UAAU,KAAK,SAAS;EACxB,YAAY,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;EAClC,YAAY,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAClD,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,YAAY,MAAM;EAClB,UAAU,KAAK,gBAAgB;EAC/B,YAAY,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAI1D,YAAY,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE;EACjD,cAAc,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EACvC,cAAc,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC/B,aAAa;EACb,YAAY,MAAM;EAClB,UAAU;EACV,YAAY,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAClD,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,SAAS;EACpB,QAAQ,QAAQ,IAAI;EACpB,UAAU,KAAK,OAAO,CAAC;EACvB,UAAU,KAAK,QAAQ;EACvB,YAAY,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC1D,YAAY,MAAM;EAClB,UAAU,KAAK,gBAAgB;EAC/B,YAAY,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC5D,YAAY,MAAM;EAClB,UAAU;EACV,YAAY,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAClD,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,OAAO;EAClB,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC9C,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,sBAAsB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;EACnF,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,YAAY,EAAE;EAC3B,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;EAC1D,MAAM,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EAC7B,KAAK,MAAM,IAAI,IAAI,CAAC,WAAW,EAAE;EACjC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,gBAAgB,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;EAC5E,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,uBAAuB,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;EAC5D,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;EAClD,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAUH,EAAE,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE;EAE1B,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;EAC1B,MAAM,MAAM,IAAI,CAAC,cAAc;EAC/B,QAAQ,sCAAsC,GAAG,GAAG,CAAC,KAAK;EAC1D,QAAQ,GAAG;EACX,OAAO,CAAC;EACR,KAAK;EAEL,IAAI,MAAM,GAAG,GAAG,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;EAC1C,IAAI,IAAI,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;EACrC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;EACtH,QAAQ,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;EAC3C,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;EACpC,OAAO,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE;EACrF,QAAQ,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;EAC1C,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;EACtC,OAAO,MAAM;EACb,QAAQ,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;EAC1C,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;EACtC,OAAO;EACP,KAAK,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;EACvF,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;EACzC,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;EACzC,KAAK,MAAM;EACX,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;EACxC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;EAClC,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE;EACnC,IAAI,IAAI,IAAI,CAAC,yBAAyB,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE;EACrD,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,0BAA0B,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,EAAE;EACjE,MAAM,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;EACzC,MAAM,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;EACvC,MAAM,QAAQ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;EACpC,QAAQ,KAAK,SAAS;EACtB,UAAU,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAClD,UAAU,MAAM;EAChB,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EACpD,UAAU,MAAM;EAChB,QAAQ;EACR,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,OAAO;EACP,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EACxB,MAAM,QAAQ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;EACrC,QAAQ,KAAK,SAAS;EACtB,UAAU,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACnD,UAAU,MAAM;EAChB,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACrD,UAAU,MAAM;EAChB,QAAQ;EACR,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC7C,OAAO;EACP,MAAM,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;EACtC,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK;EAEL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC;EACxD,IAAI,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC;EAC1D,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS,EAAE;EACjC,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,2BAA2B,CAAC,EAAE,GAAG,CAAC,CAAC;EACpE,KAAK;EACL,IAAI,MAAM,GAAG,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;EAC7C,IAAI,QAAQ,GAAG;EACf,MAAM,KAAK,mBAAmB;EAC9B,QAAQ,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,QAAQ,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EAC1C,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,eAAe,CAAC;EAC3B,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;EACzC,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,QAAQ,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;EACxC,QAAQ,MAAM;EACd,MAAM,KAAK,iCAAiC;EAC5C,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;EACpF,UAAU,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EAC7C,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,UAAU,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EACjE,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC7C,UAAU,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EAC5C,SAAS,MAAM;EACf,UAAU,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;EAC3C,UAAU,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EACpD,UAAU,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EACjE,UAAU,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACrD,UAAU,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;EAC1C,SAAS;EACT,QAAQ,MAAM;EAEd,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,kBAAkB;EAC7B,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE;EAE1F,UAAU,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;EAClD,YAAY,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;EAC7C,YAAY,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EACpD,YAAY,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EACnE,YAAY,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;EAC5C,YAAY,MAAM;EAClB,WAAW;EACX,SAAS;EACT,QAAQ,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,QAAQ,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,QAAQ,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;EAC7C,QAAQ,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE;EAC1C,UAAU,MAAM,aAAa,GAAG,EAAE,CAAC;EACnC,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;EACpD,UAAU,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;EACtD,UAAU,IAAI,WAAW,KAAK,SAAS,EAAE;EACzC,YAAY,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;EAChD,WAAW,MAAM;EACjB,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,wCAAwC,CAAC,EAAE,GAAG,CAAC,CAAC;EACvF,WAAW;EACX,SAAS,MAAM;EACf,UAAU,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC9B,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC7C,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,SAAS;EACT,QAAQ,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC;EAC5C,QAAQ,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EAC1C,QAAQ,MAAM;EACd,MAAM,KAAK,0BAA0B;EACrC,QAAQ,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,QAAQ,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,QAAQ,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACrD,QAAQ,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EAC1C,QAAQ,MAAM;EAEd,MAAM,KAAK,kBAAkB;EAC7B,QAAQ,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;EACzC,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,QAAQ,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,QAAQ,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACjD,QAAQ,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;EACxC,QAAQ,MAAM;EACd,MAAM,KAAK,wBAAwB,CAAC;EACpC,MAAM,KAAK,yBAAyB;EACpC,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;EAC9C,UAAU,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EAC7C,UAAU,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC9B,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,UAAU,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EACjE,UAAU,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACvD,UAAU,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EAC5C,SAAS,MAAM;EACf,UAAU,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;EAC3C,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,UAAU,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EACjE,UAAU,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACrD,UAAU,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;EAC1C,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,wBAAwB,CAAC;EACpC,MAAM,KAAK,yBAAyB;EACpC,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE;EACxH,UAAU,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EAC7C,UAAU,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EACtD,UAAU,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EACjE,UAAU,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACrD,UAAU,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EAC5C,SAAS,MAAM;EACf,UAAU,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;EAC3C,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,UAAU,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EACjE,UAAU,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EAC7C,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC7C,UAAU,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EAC5C,UAAU,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;EAC1C,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,0BAA0B;EACrC,QAAQ,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EACpD,QAAQ,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EAC1C,QAAQ,MAAM;EAEd,MAAM,KAAK,mBAAmB;EAC9B,QAAQ,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,QAAQ,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EAC1C,QAAQ,MAAM;EAEd,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;EACzC,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,QAAQ,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,QAAQ,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACjD,QAAQ,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;EACxC,QAAQ,MAAM;EAEd,MAAM;EACN,QAAQ,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,oCAAoC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;EACrF,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAErB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE;EACzC,IAAI,MAAM,aAAa,GAAG,IAAI,CAAC,iCAAiC,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EAC9E,IAAI,IAAI,aAAa,EAAE;EACvB,MAAM,OAAO,aAAa,CAAC;EAC3B,KAAK;EACL,IAAI,MAAM,sBAAsB,GAAG;EACnC,MAAM,GAAG,EAAE,KAAK;EAChB,MAAM,IAAI,EAAE,KAAK;EACjB,KAAK,CAAC;EACN,IAAI,MAAM,aAAa,GAAG,sBAAsB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,IAAI,IAAI,CAAC,aAAa,EAAE,OAAO,IAAI,CAAC;EACpC,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EAC/B,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,QAAQ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;EAClC,MAAM,KAAK,SAAS;EACpB,QAAQ,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAChD,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAClD,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,QAAQ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;EACnC,MAAM,KAAK,SAAS;EACpB,QAAQ,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACjD,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACnD,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC3C,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,iCAAiC,CAAC,GAAG,EAAE,MAAM,EAAE;EACjD,IAAI,MAAM,sBAAsB,GAAG;EACnC,MAAM,GAAG,EAAE,YAAY;EACvB,MAAM,GAAG,EAAE,WAAW;EACtB,MAAM,GAAG,EAAE,YAAY;EACvB,MAAM,IAAI,EAAE,0BAA0B;EACtC,MAAM,IAAI,EAAE,yBAAyB;EACrC,MAAM,KAAK,EAAE,2BAA2B;EACxC,KAAK,CAAC;EACN,IAAI,MAAM,aAAa,GAAG,sBAAsB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,IAAI,IAAI,CAAC,aAAa,EAAE,OAAO,IAAI,CAAC;EACpC,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EAC/B,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC5C,IAAI,QAAQ,QAAQ;EACpB,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,OAAO;EAClB,QAAQ,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAClD,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EACpD,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;EAC9C,IAAI,QAAQ,SAAS;EACrB,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,OAAO;EAClB,QAAQ,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACnD,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACrD,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC3C,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,6BAA6B,CAAC,GAAG,EAAE,MAAM,EAAE;EAC7C,IAAI,MAAM,sBAAsB,GAAG;EACnC,MAAM,GAAG,EAAE,YAAY;EACvB,KAAK,CAAC;EACN,IAAI,MAAM,aAAa,GAAG,sBAAsB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,IAAI,IAAI,CAAC,aAAa,EAAE,OAAO,IAAI,CAAC;EACpC,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EAC/B,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,QAAQ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;EACtC,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,OAAO;EAClB,QAAQ,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EACtD,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EACxD,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC9C,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE;EACpC,IAAI,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;EACzC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACjC,IAAI,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC;EACxC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE;EAClC,IAAI,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EACvC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACjC,IAAI,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EACtC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE;EAClC,IAAI,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;EACzC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACxB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACjC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC;EACxC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE;EAChC,IAAI,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EACvC,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC1B,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACjC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EACtC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE;EAC3C,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,EAAE;EACvC,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,0CAA0C,EAAE,OAAO,CAAC,CAAC;EACrF,KAAK;EAEL,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;EAEvC,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE;EAErC,MAAM,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EACrC,KAAK,MAAM,IAAI,IAAI,KAAK,SAAS,EAAE;EACnC,MAAM,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE;EACzD,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAClD,OAAO,MAAM;EACb,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC5C,OAAO;EACP,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC1C,KAAK;EAEL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE;EACnC,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,cAAc,EAAE;EACzC,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;EAClE,KAAK;EAEL,IAAI,MAAM,OAAO,GAAG,EAAE,CAAC;EACvB,IAAI,MAAM,OAAO,GAAG,EAAE,CAAC;EACvB,IAAI,MAAM,SAAS,GAAG,EAAE,CAAC;EACzB,IAAI,MAAM,OAAO,GAAG,EAAE,CAAC;EACvB,IAAI,IAAI,MAAM,GAAG,IAAI,CAAC;EAEtB,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE;EACtB,MAAM,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EACzC,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;EAC7C,MAAM,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;EAC5C,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACpD,QAAQ,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE;EAC7E,UAAU,MAAM,GAAG,KAAK,CAAC;EACzB,SAAS;EACT,OAAO;EACP,MAAM,IAAI,MAAM,EAAE;EAClB,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACjD,UAAU,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;EAC/D,YAAY,MAAM,GAAG,KAAK,CAAC;EAC3B,WAAW;EACX,SAAS;EACT,OAAO;EACP,MAAM,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EACxC,KAAK,MAAM;EACX,MAAM,MAAM,GAAG,KAAK,CAAC;EACrB,KAAK;EAEL,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE;EACtB,MAAM,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EACzC,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;EAC7C,MAAM,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EACxC,KAAK,MAAM;EACX,MAAM,MAAM,GAAG,KAAK,CAAC;EACrB,KAAK;EAEL,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE;EACxB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;EACjD,KAAK,MAAM;EACX,MAAM,MAAM,GAAG,KAAK,CAAC;EACrB,KAAK;EAEL,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE;EACtB,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;EAClC,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;EAC7C,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;EACjC,KAAK;EAGL,IAAI,IAAI,MAAM,KAAK,IAAI,EAAE;EACzB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EACtE,KAAK;EAEL,IAAI,IAAI,MAAM,EAAE;EAChB,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EAC5F,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;EACpC,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,KAAK,MAAM;EACX,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;EAClE,MAAM,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;EAC9B,QAAQ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;EAC7C,OAAO;EACP,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,aAAa,CAAC,GAAG,EAAE,aAAa,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;EAClG,MAAM,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;EAC9B,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;EAC1D,OAAO;EACP,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;EACpC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC9C,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE;EACvC,IAAI,IAAI,SAAS,CAAC,IAAI,KAAK,gBAAgB,EAAE;EAC7C,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,yBAAyB,EAAE,SAAS,CAAC,CAAC;EACtE,KAAK;EAEL,IAAI,MAAM,aAAa,GAAG,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;EAChE,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,aAAa,CAAC,GAAG,EAAE,aAAa,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;EAChG,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACzB,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAC9B,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EAEvB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE;EAC3C,IAAI,IAAI,WAAW,CAAC,IAAI,KAAK,kBAAkB,EAAE;EACjD,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,yBAAyB,EAAE,WAAW,CAAC,CAAC;EACxE,KAAK;EAEL,IAAI,MAAM,aAAa,GAAG,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;EAChE,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,aAAa,CAAC,GAAG,EAAE,aAAa,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACzB,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAC9B,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EAEvB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EASH,EAAE,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE;EAE3C,IAAI,IAAI,OAAO,CAAC,QAAQ,KAAK,IAAI,EAAE;EACnC,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC1B,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC7C,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,KAAK,MAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,KAAK,EAAE;EAC3C,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC1B,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC7C,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,KAAK,MAAM;EACX,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EAClD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;EACpD,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EACpC,MAAM,IAAI,QAAQ,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS,EAAE;EAC7D,QAAQ,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC9B,QAAQ,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC/C,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,OAAO,MAAM;EACb,QAAQ,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC/C,OAAO;EACP,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK;EACL,GAAG;EAQH,EAAE,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE;EACnC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;EACnC,MAAM,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;EACnC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,QAAQ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EAC/C,OAAO;EACP,MAAM,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;EAClC,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,QAAQ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EAC/C,OAAO;EACP,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE;EAC7C,IAAI,IAAI,UAAU,CAAC,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,YAAY,EAAE;EACxD,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;EACrB,KAAK;EACL,IAAI,MAAM,YAAY,GAAG,UAAU,CAAC,YAAY,CAAC;EACjD,IAAI,IAAI,CAAC,YAAY,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;EACpE,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,UAAU,CAAC,CAAC;EACrE,KAAK;EACL,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,QAAQ,GAAG,IAAI,CAAC;EACxB,IAAI,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;EAC3D,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,MAAM,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;EAC1C,MAAM,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC;EACpC,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;EACvD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;EACvC,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;EACxD,MAAM,IAAI,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;EAC3C,MAAM,IAAI,IAAI,GAAG,aAAa,GAAG,SAAS,GAAG,UAAU,CAAC;EACxD,MAAM,IAAI,IAAI,KAAK,gBAAgB,EAAE;EAErC,QAAQ,IAAI,GAAG,QAAQ,CAAC;EACxB,OAAO;EACP,MAAM,MAAM,UAAU,GAAGA,SAAO,CAAC,IAAI,CAAC,CAAC;EACvC,MAAM,IAAI,CAAC,UAAU,EAAE;EACvB,QAAQ,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,YAAY,GAAG,UAAU,EAAE,YAAY,CAAC,EAAE,UAAU,CAAC,CAAC;EACzF,OAAO;EACP,MAAM,MAAM,iBAAiB,GAAG,EAAE,CAAC;EACnC,MAAM,IAAI,UAAU,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,aAAa,EAAE;EAE5E,QAAQ,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;EAClC,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,QAAQ,KAAK,IAAI,EAAE;EAC1C,UAAU,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC3C,SAAS,MAAM,IAAI,IAAI,KAAK,QAAQ,EAAE;EACtC,UAAU,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;EACnD,SAAS,MAAM;EACf,UAAU,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACtC,SAAS;EACT,QAAQ,QAAQ,GAAG,IAAI,CAAC;EACxB,QAAQ,iBAAiB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/D,QAAQ,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;EACzC,QAAQ,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;EACjD,QAAQ,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACpC,OAAO,MAAM;EAEb,QAAQ,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAC9B,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,QAAQ,KAAK,IAAI,EAAE;EAC1C,UAAU,iBAAiB,CAAC,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;EACnD,SAAS,MAAM,IAAI,IAAI,KAAK,QAAQ,EAAE;EACtC,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,UAAU,iBAAiB,CAAC,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;EACnD,SAAS,MAAM;EACf,UAAU,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACtC,SAAS;EACT,QAAQ,QAAQ,GAAG,IAAI,CAAC;EACxB,QAAQ,iBAAiB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/D,QAAQ,IAAI,UAAU,KAAK,QAAQ,IAAI,IAAI,KAAK,SAAS,EAAE;EAC3D,UAAU,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE;EACzD,YAAY,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;EACrD,WAAW,MAAM;EACjB,YAAY,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3C,YAAY,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;EACrD,YAAY,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACxC,WAAW;EACX,SAAS,MAAM;EACf,UAAU,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;EACnD,SAAS;EACT,OAAO;EACP,MAAM,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;EAC9C,KAAK;EAEL,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;EACjC,IAAI,IAAI,CAAC,aAAa,EAAE;EACxB,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE;EACjC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACxB,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EACzC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,KAAK,gBAAgB,EAAE;EACrD,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;EACjD,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC1B,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;EACjD,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC3B,KAAK;EAEL,IAAI,IAAI,MAAM,CAAC,SAAS,EAAE;EAC1B,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC3B,MAAM,IAAI,MAAM,CAAC,SAAS,CAAC,IAAI,KAAK,gBAAgB,EAAE;EACtD,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAClD,OAAO,MAAM;EACb,QAAQ,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC5B,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAClD,QAAQ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC7B,OAAO;EACP,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE;EAClC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,iBAAiB,EAAE;EACxC,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;EACjE,KAAK;EACL,IAAI,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC;EACxC,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;EAC5C,IAAI,MAAM,OAAO,GAAG,CAAC,kBAAkB,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;EAChE,IAAI,QAAQ,IAAI;EAChB,MAAM,KAAK,OAAO,CAAC;EACnB,MAAM,KAAK,QAAQ;EACnB,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;EAC9C,QAAQ,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EAC3B,QAAQ,MAAM;EACd,MAAM,KAAK,SAAS;EACpB,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;EACzC,QAAQ,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;EAC9C,QAAQ,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EAC3B,QAAQ,MAAM;EACd,KAAK;EAEL,IAAI,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;EAC9C,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;EACnD,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK;EAGL,IAAI,IAAI,cAAc,GAAG,KAAK,CAAC;EAC/B,IAAI,IAAI,aAAa,GAAG,EAAE,CAAC;EAC3B,IAAI,IAAI,kBAAkB,GAAG,KAAK,CAAC;EACnC,IAAI,IAAI,WAAW,GAAG,KAAK,CAAC;EAC5B,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAE3C,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;EAC1B,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,EAAE;EAClC,UAAU,kBAAkB,GAAG,IAAI,CAAC;EACpC,UAAU,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;EAC9D,UAAU,SAAS;EACnB,SAAS,MAAM;EACf,UAAU,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;EACnC,SAAS;EACT,OAAO,MAAM;EAEb,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE;EACrC,UAAU,WAAW,GAAG,IAAI,CAAC;EAC7B,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;EAC5C,SAAS,MAAM;EACf,UAAU,IAAI,cAAc,EAAE;EAC9B,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;EAC1C,YAAY,cAAc,GAAG,KAAK,CAAC;EACnC,WAAW,MAAM;EACjB,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;EACpD,WAAW;EACX,SAAS;EACT,QAAQ,IAAI,IAAI,KAAK,SAAS,EAAE;EAChC,UAAU,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EACvD,UAAU,QAAQ,QAAQ;EAC1B,YAAY,KAAK,QAAQ,CAAC;EAC1B,YAAY,KAAK,OAAO;EACxB,cAAc,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC7D,cAAc,MAAM;EACpB,YAAY,KAAK,gBAAgB;EACjC,cAAc,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC/D,cAAc,MAAM;EACpB,WAAW;EACX,SAAS,MAAM,IAAI,IAAI,KAAK,OAAO,EAAE;EACrC,UAAU,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EACvD,UAAU,QAAQ,QAAQ;EAC1B,YAAY,KAAK,gBAAgB;EACjC,cAAc,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC7D,cAAc,MAAM;EACpB,YAAY,KAAK,SAAS;EAC1B,cAAc,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC3D,cAAc,MAAM;EACpB,WAAW;EACX,SAAS,MAAM;EACf,UAAU,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC;EACvC,SAAS;EACT,QAAQ,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE;EACtE,UAAU,cAAc,GAAG,IAAI,CAAC;EAChC,UAAU,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC9B,UAAU,SAAS;EACnB,SAAS;EACT,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;EAC7B,OAAO;EACP,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;EACnD,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,KAAK;EACL,IAAI,IAAI,kBAAkB,EAAE;EAC5B,MAAM,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EAC7B,MAAM,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;EAC1C,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE;EACnC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACxB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE;EACrC,IAAI,MAAM;EACV,MAAM,QAAQ;EACd,MAAM,IAAI;EACV,MAAM,SAAS;EACf,MAAM,MAAM;EACZ,MAAM,IAAI;EACV,MAAM,SAAS;EACf,MAAM,SAAS;EACf,MAAM,SAAS;EACf,KAAK,GAAG,IAAI,CAAC,0BAA0B,CAAC,KAAK,CAAC,CAAC;EAC/C,IAAI,QAAQ,SAAS;EACrB,MAAM,KAAK,oBAAoB,CAAC;EAChC,MAAM,KAAK,mBAAmB;EAC9B,QAAQ,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,EAAE;EAC1D,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,sFAAsF,EAAE,KAAK,CAAC,CAAC;EACnI,SAAS;EACT,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;EACxC,QAAQ,OAAO,MAAM,CAAC;EACtB,MAAM,KAAK,mBAAmB;EAC9B,QAAQ,IAAI,IAAI,CAAC,aAAa,EAAE;EAChC,UAAU,QAAQ,IAAI;EACtB,YAAY,KAAK,GAAG;EACpB,cAAc,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;EACpD,gBAAgB,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;EACnD,eAAe,MAAM;EACrB,gBAAgB,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;EAC5C,eAAe;EACf,cAAc,MAAM;EACpB,YAAY,KAAK,GAAG;EACpB,cAAc,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;EACpD,gBAAgB,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;EACnD,eAAe,MAAM;EACrB,gBAAgB,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;EAC5C,eAAe;EACf,cAAc,MAAM;EACpB,YAAY,KAAK,GAAG;EACpB,cAAc,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;EACpD,gBAAgB,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;EACnD,eAAe,MAAM;EACrB,gBAAgB,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;EAC5C,eAAe;EACf,cAAc,MAAM;EACpB,YAAY;EACZ,cAAc,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;EACxE,WAAW;EACX,SAAS,MAAM;EACf,UAAU,QAAQ,IAAI;EACtB,YAAY,KAAK,GAAG;EACpB,cAAc,IAAI,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE;EACtD,gBAAgB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAC5C,eAAe,MAAM;EACrB,gBAAgB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;EAClD,eAAe;EACf,cAAc,MAAM;EACpB,YAAY,KAAK,GAAG;EACpB,cAAc,IAAI,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE;EACtD,gBAAgB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAC5C,eAAe,MAAM;EACrB,gBAAgB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;EAClD,eAAe;EACf,cAAc,MAAM;EACpB,YAAY,KAAK,GAAG;EACpB,cAAc,IAAI,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE;EACtD,gBAAgB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAC5C,eAAe,MAAM;EACrB,gBAAgB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;EAClD,eAAe;EACf,cAAc,MAAM;EACpB,YAAY;EACZ,cAAc,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;EACxE,WAAW;EACX,SAAS;EACT,QAAQ,OAAO,MAAM,CAAC;EACtB,MAAM,KAAK,OAAO;EAClB,QAAQ,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;EAClE,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,WAAW,CAAC;EACvB,MAAM,KAAK,aAAa,CAAC;EACzB,MAAM,KAAK,eAAe,CAAC;EAC3B,MAAM,KAAK,aAAa;EACxB,QAAQ,IAAI,MAAM,KAAK,MAAM,EAAE;EAC/B,UAAU,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EAClC,UAAU,OAAO,MAAM,CAAC;EACxB,SAAS;EACT,QAAQ,QAAQ,QAAQ;EACxB,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;EAC5C,YAAY,OAAO,MAAM,CAAC;EAC1B,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;EAC5C,YAAY,OAAO,MAAM,CAAC;EAC1B,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;EAC5C,YAAY,OAAO,MAAM,CAAC;EAC1B,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;EAC5C,YAAY,OAAO,MAAM,CAAC;EAC1B,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,sBAAsB;EACjC,QAAQ,IAAI,OAAO,SAAS,KAAK,WAAW,EAAE;EAC9C,UAAU,QAAQ,IAAI;EACtB,YAAY,KAAK,UAAU,CAAC;EAC5B,YAAY,KAAK,UAAU,CAAC;EAC5B,YAAY,KAAK,UAAU;EAC3B,cAAc,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;EACjD,cAAc,OAAO,MAAM,CAAC;EAC5B,WAAW;EACX,SAAS;EACT,QAAQ,KAAK,wBAAwB,CAAC;EACtC,QAAQ,KAAK,0BAA0B,CAAC;EACxC,QAAQ,KAAK,4BAA4B,CAAC;EAC1C,QAAQ,KAAK,8BAA8B;EAC3C,UAAU,MAAM;EAChB,QAAQ,KAAK,QAAQ;EACrB,UAAU,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;EACvD,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,UAAU,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,8BAA8B,CAAC,QAAQ,CAAC,CAAC,CAAC;EACrE,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,UAAU,OAAO,MAAM,CAAC;EACxB,QAAQ,KAAK,MAAM;EACnB,UAAU,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;EACxD,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,UAAU,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,8BAA8B,CAAC,QAAQ,CAAC,CAAC,CAAC;EACrE,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,UAAU,OAAO,MAAM,CAAC;EACxB,QAAQ;EACR,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;EACpE,KAAK;EAEL,IAAI,IAAI,KAAK,CAAC,QAAQ,KAAK,KAAK,EAAE;EAElC,MAAM,QAAQ,IAAI;EAClB,QAAQ,KAAK,QAAQ,CAAC;EACtB,QAAQ,KAAK,SAAS,CAAC;EACvB,QAAQ,KAAK,OAAO,CAAC;EACrB,QAAQ,KAAK,SAAS;EACtB,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;EAC3C,UAAU,OAAO,MAAM,CAAC;EACxB,OAAO;EACP,KAAK;EAIL,IAAI,MAAM,UAAU,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;EAE3C,IAAI,QAAQ,IAAI;EAChB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU;EAErB,QAAQ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;EAC9C,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,8BAA8B,CAAC,SAAS,CAAC,CAAC,CAAC;EACpE,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,GAAG,UAAU,EAAE,EAAE,GAAG,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;EAC7F,QAAQ,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC1E,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM;EACd,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,sBAAsB,GAAG,UAAU,EAAE,EAAE,GAAG,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;EACxG,QAAQ,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC1E,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM;EACd,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY;EACvB,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,uBAAuB,GAAG,UAAU,EAAE,EAAE,GAAG,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;EACzG,QAAQ,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC1E,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM;EACd,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,qBAAqB,GAAG,UAAU,EAAE,EAAE,GAAG,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;EACvG,QAAQ,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC1E,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM;EACd,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY;EACvB,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,uBAAuB,GAAG,UAAU,EAAE,EAAE,GAAG,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;EACzG,QAAQ,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC1E,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM;EACd,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,qBAAqB,GAAG,UAAU,EAAE,EAAE,GAAG,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;EACvG,QAAQ,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC1E,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM;EACd,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY;EACvB,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,uBAAuB,GAAG,UAAU,EAAE,EAAE,GAAG,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;EACzG,QAAQ,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC1E,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM;EACd,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,WAAW,CAAC;EACvB,MAAM,KAAK,WAAW;EACtB,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,qBAAqB,GAAG,UAAU,EAAE,EAAE,GAAG,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;EACvG,QAAQ,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC1E,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM;EACd,MAAM,KAAK,eAAe,CAAC;EAC3B,MAAM,KAAK,OAAO,CAAC;EACnB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,OAAO,CAAC;EACnB,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,OAAO,CAAC;EACnB,MAAM,KAAK,SAAS;EACpB,QAAQ,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE;EAGzC,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,qBAAqB,EAAE,UAAU,CAAC,EAAE,EAAE,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;EACnG,UAAU,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC5E,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,SAAS,MAAM;EACf,UAAU,MAAM,QAAQ,IAAI,MAAM,KAAK,MAAM;EAC7C,YAAY,IAAI,CAAC,8BAA8B,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;EAChE,YAAY,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;EACxC,WAAW,CAAC;EACZ,UAAU,QAAQ,QAAQ;EAC1B,YAAY,KAAK,CAAC;EAClB,cAAc,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,EAAE,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;EACvF,cAAc,MAAM;EACpB,YAAY,KAAK,CAAC;EAClB,cAAc,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,EAAE,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;EACxF,cAAc,MAAM;EACpB,YAAY,KAAK,CAAC,CAAC;EACnB,YAAY,KAAK,CAAC;EAClB,cAAc,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,EAAE,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;EACxF,cAAc,MAAM;EACpB,YAAY;EACZ,cAAc,MAAM,IAAI,KAAK,CAAC,CAAC,uBAAuB,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;EACpE,WAAW;EACX,UAAU,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC5E,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,8BAA8B;EACzC,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,qBAAqB,GAAG,UAAU,EAAE,EAAE,GAAG,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;EACvG,QAAQ,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC1E,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,6BAA6B,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;EACnE,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE;EACjC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE;EACrB,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;EAC/D,KAAK;EAEL,IAAI,IAAI,YAAY,GAAG,IAAI,CAAC;EAC5B,IAAI,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;EAGvD,IAAI,IAAI,cAAc,KAAK,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,gBAAgB,CAAC,EAAE;EAC9F,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;EAC9C,KAAK;EAEL,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,oBAAoB,IAAI,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAChJ,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;EAC7D,KAAK,MAAM;EACX,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;EACrC,KAAK;EAEL,IAAI,IAAI,CAAC,YAAY,EAAE;EACvB,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,sCAAsC,CAAC,EAAE,GAAG,CAAC,CAAC;EAC/E,KAAK;EAGL,IAAI,IAAI,YAAY,KAAK,OAAO,EAAE;EAClC,MAAM,YAAY,GAAG,MAAM,CAAC;EAC5B,KAAK;EAGL,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE;EACxD,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAC9C,KAAK;EAEL,IAAI,IAAI,YAAY,KAAK,QAAQ,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;EAC9E,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACpD,QAAQ,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;EACvC,QAAQ,IAAI,MAAM,CAAC,aAAa,KAAK,eAAe,IAAI,MAAM,CAAC,eAAe,EAAE;EAChF,UAAU,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;EAC9C,UAAU,OAAO,MAAM,CAAC;EACxB,SAAS;EACT,OAAO;EACP,KAAK;EAGL,IAAI,IAAI,IAAI,CAAC,cAAc,EAAE;EAC7B,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;EAClE,KAAK;EAGL,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAG9B,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAGrB,IAAI,IAAI,cAAc,EAAE;EACxB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACrD,QAAQ,MAAM,QAAQ,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;EAC1C,QAAQ,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EACpD,QAAQ,IAAI,CAAC,GAAG,CAAC,EAAE;EACnB,UAAU,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC5B,SAAS;EAET,QAAQ,QAAQ,YAAY;EAC5B,UAAU,KAAK,SAAS;EACxB,YAAY,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EACpD,YAAY,MAAM;EAClB,UAAU;EACV,YAAY,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC9C,YAAY,MAAM;EAClB,SAAS;EACT,OAAO;EACP,KAAK,MAAM;EACX,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,2BAA2B,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;EAC/E,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACrD,QAAQ,MAAM,QAAQ,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;EAC1C,QAAQ,IAAI,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;EACxC,QAAQ,IAAI,CAAC,GAAG,CAAC,EAAE;EACnB,UAAU,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC5B,SAAS;EACT,QAAQ,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EACpD,QAAQ,IAAI,CAAC,UAAU,EAAE;EACzB,UAAU,IAAI,CAAC,wBAAwB,CAAC,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;EAC7E,UAAU,UAAU,GAAG,YAAY,CAAC;EACpC,SAAS;EACT,QAAQ,QAAQ,YAAY;EAC5B,UAAU,KAAK,QAAQ,CAAC;EACxB,UAAU,KAAK,OAAO;EACtB,YAAY,IAAI,UAAU,KAAK,SAAS,EAAE;EAC1C,cAAc,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAClC,cAAc,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAChD,cAAc,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC/B,cAAc,SAAS;EACvB,aAAa,MAAM,IAAI,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,OAAO,EAAE;EAC1E,cAAc,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAChD,cAAc,SAAS;EACvB,aAAa,MAAM,IAAI,UAAU,KAAK,gBAAgB,EAAE;EACxD,cAAc,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EACxD,cAAc,SAAS;EACvB,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,SAAS;EACxB,YAAY,IAAI,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,OAAO,EAAE;EACnE,cAAc,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;EACpC,cAAc,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAChD,cAAc,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC/B,cAAc,SAAS;EACvB,aAAa,MAAM,IAAI,UAAU,KAAK,SAAS,EAAE;EACjD,cAAc,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAChD,cAAc,SAAS;EACvB,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,gBAAgB;EAC/B,YAAY,IAAI,UAAU,KAAK,SAAS,EAAE;EAC1C,cAAc,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC1D,cAAc,SAAS;EACvB,aAAa,MAAM,IAAI,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,OAAO,EAAE;EAC1E,cAAc,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EACxD,cAAc,SAAS;EACvB,aAAa,MAAM,IAAI,UAAU,KAAK,gBAAgB,EAAE;EACxD,cAAc,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAChD,cAAc,SAAS;EACvB,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU,CAAC;EAC1B,UAAU,KAAK,UAAU,CAAC;EAC1B,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,UAAU,KAAK,YAAY,EAAE;EAC7C,cAAc,IAAI,QAAQ,CAAC,IAAI,KAAK,YAAY,EAAE,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,wBAAwB,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;EAC/H,cAAc,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;EAC3F,cAAc,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EACnD,cAAc,SAAS;EACvB,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,WAAW,CAAC;EAC3B,UAAU,KAAK,gBAAgB,CAAC;EAChC,UAAU,KAAK,WAAW,CAAC;EAC3B,UAAU,KAAK,iBAAiB,CAAC;EACjC,UAAU,KAAK,iBAAiB,CAAC;EACjC,UAAU,KAAK,iBAAiB,CAAC;EACjC,UAAU,KAAK,iBAAiB,CAAC;EACjC,UAAU,KAAK,OAAO,CAAC;EACvB,UAAU,KAAK,OAAO;EACtB,YAAY,IAAI,UAAU,KAAK,YAAY,EAAE;EAC7C,cAAc,IAAI,QAAQ,CAAC,IAAI,KAAK,YAAY,EAAE,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,wBAAwB,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;EAC/H,cAAc,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;EAC3F,cAAc,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;EACtG,cAAc,SAAS;EACvB,aAAa;EACb,YAAY,MAAM;EAClB,SAAS;EACT,QAAQ,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,kCAAkC,GAAG,YAAY,EAAE,KAAK,GAAG,UAAU,EAAE,qBAAqB,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;EAC1J,OAAO;EACP,KAAK;EAEL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAErB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE;EACtC,IAAI,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;EAE3C,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,MAAM,GAAG,GAAG,CAAC,CAAC;EACtC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,EAAE,CAAC,EAAE;EACrC,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE;EACjB,QAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC1B,OAAO;EACP,MAAM,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;EAC1C,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAC;EACtC,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAErB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE;EACvC,IAAI,IAAI,CAAC,EAAE;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;EAChE,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,KAAK;EACL,IAAI,IAAI,CAAC,EAAE;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;EAChE,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC,CAAC,CAAC,CAAC;EACxD,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,8BAA8B,CAAC,QAAQ,EAAE;EAC3C,IAAI,IAAI,CAAC,QAAQ,EAAE;EACnB,MAAM,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;EAC1C,KAAK;EACL,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EACxC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,QAAQ,IAAI;EAChB,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,OAAO;EAClB,QAAQ,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAClD,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EACpD,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC1C,KAAK;EACL,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3B,GAAG;EACH,CAAC;EAED,MAAMA,SAAO,GAAG;EAChB,EAAE,OAAO,EAAE,WAAW;EACtB,EAAE,UAAU,EAAE,MAAM;EACpB,EAAE,UAAU,EAAE,MAAM;EACpB,EAAE,UAAU,EAAE,MAAM;EACpB,EAAE,SAAS,EAAE,WAAW;EACxB,EAAE,SAAS,EAAE,WAAW;EACxB,EAAE,SAAS,EAAE,MAAM;EACnB,EAAE,OAAO,EAAE,OAAO;EAClB,EAAE,OAAO,EAAE,WAAW;EACtB,EAAE,SAAS,EAAE,KAAK;EAClB,EAAE,QAAQ,EAAE,OAAO;EACnB,EAAE,gBAAgB,EAAE,OAAO;EAC3B,EAAE,eAAe,EAAE,WAAW;EAC9B,EAAE,8BAA8B,EAAE,WAAW;EAC7C,EAAE,iBAAiB,EAAE,WAAW;EAChC,EAAE,iBAAiB,EAAE,WAAW;EAChC,EAAE,iBAAiB,EAAE,WAAW;EAChC,EAAE,iBAAiB,EAAE,WAAW;EAChC,EAAE,WAAW,EAAE,WAAW;EAC1B,EAAE,WAAW,EAAE,WAAW;EAC1B,EAAE,gBAAgB,EAAE,gBAAgB;EACpC,CAAC,CAAC;EAEF,MAAM,WAAW,GAAG;EACpB,EAAE,KAAK,EAAE,IAAI;EACb,EAAE,KAAK,EAAE,IAAI;EACb,CAAC,CAAC;;ECz/CF,MAAM,MAAM,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2Bf,CAAC,CAAC;EAEH,MAAMC,MAAI,GAAG,sBAAsB,CAAC;EAEpC,MAAM,aAAa,GAAG,eAAe,CAAC;EAEtC,MAAM,eAAe,GAAG,mBAAmB,CAAC;EAE5C,MAAM,kBAAkB,GAAG,QAAQ,CAAC;EAEpC,MAAM,WAAW,GAAG,CAAC,MAAM,KAAK;EAChC,EAAE,MAAM,CAAC,YAAY,CAAC,qBAAqB,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;EAC5D,CAAC,CAAC;AAKF,sBAAe;EACf,QAAEA,MAAI;EACN,EAAE,WAAW;EACb,EAAE,aAAa;EACf,EAAE,eAAe;EACjB,EAAE,kBAAkB;EACpB,EAAE,MAAM;EACR,CAAC,CAAC;;EClDK,MAAM,cAAc,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiZ9B,CAAC,CAAC;;ECjZI,MAAM,YAAY,GAAG,CAAC;;;;;;;;;;;;;CAa5B,CAAC,CAAC;;;;;;;ECRH,SAAS,SAAS,CAAC,EAAE,EAAE,OAAO,GAAG,EAAE,EAAE;IACnC,MAAM;MACJ,WAAW,GAAG,IAAI;MAClB,aAAa;MACb,sBAAsB;MACtB,cAAc;MACd,SAAS,GAAG,EAAE;MACd,SAAS,GAAG,EAAE;MACd,YAAY;MACZ,4BAA4B;KAC7B,GAAG,OAAO,CAAC;IACZ,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7C,MAAM,gBAAgB,GAAG,EAAE,CAAC;IAC5B,MAAM,WAAW,GAAG,EAAE,CAAC;IACvB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,sBAAsB,CAAC;IAC3B,OAAO,KAAK,CAAC;IACb,SAAS,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE;MAC7B,QAAQ,QAAQ;QACd,KAAK,YAAY,EAAE,OAAO,UAAU,CAAC;QACrC,KAAK,iBAAiB,EAAE,OAAO,eAAe,CAAC;QAC/C,KAAK,2BAA2B,EAAE,OAAO,sBAAsB,CAAC;QAChE,KAAK,gBAAgB,EAAE,OAAO,cAAc,CAAC;QAC7C,KAAK,OAAO,EAAE,OAAO,KAAK,CAAC;QAC3B,KAAK,WAAW,EAAE,OAAO,SAAS,CAAC;QACnC,KAAK,UAAU,EAAE,OAAO,QAAQ,CAAC;QACjC,KAAK,wBAAwB,EAAE,OAAO,sBAAsB,CAAC;OAC9D;MACD,IAAI,OAAO,EAAE,CAAC,QAAQ,CAAC,KAAK,UAAU,EAAE;QACtC,OAAO,WAAW;UAChB,QAAQ,QAAQ;YACd,KAAK,UAAU;cACb,IAAI,aAAa,EAAE;gBACjB,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,gBAAgB,EAAE,WAAW,CAAC,gCAAgC,CAAC,CAAC,CAAC;eAC7G,MAAM;gBACL,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC;eACvD;cACD,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC;YACvB,KAAK,cAAc,EAAE;cACnB,MAAM,YAAY,GAAG,CAAC,EAAE,WAAW,CAAC,SAAS,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;cACzE,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,EAAE,WAAW,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;cACnG,MAAM,SAAS,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;cAChD,IAAI,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE;gBAC9C,MAAM,eAAe,GAAG,kBAAkB,CAAC,SAAS,EAAE;kBACpD,SAAS;kBACT,sBAAsB;kBACtB,SAAS;kBACT,WAAW,EAAE,YAAY;kBACzB,gBAAgB;kBAChB,SAAS;kBACT,MAAM;kBACN,4BAA4B;iBAC7B,CAAC,CAAC;gBACH,gBAAgB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;gBACvC,OAAO,eAAe,CAAC;eACxB,MAAM;gBACL,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;eAC7B;cACD,OAAO,SAAS,CAAC;aAClB;YACD,KAAK,YAAY;cACf,MAAM,CAAC,GAAG,gBAAgB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;cACjD,IAAI,kBAAkB,CAAC;cACvB,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE;gBACZ,MAAM,YAAY,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;gBACnD,IAAI,YAAY,EAAE;kBAChB,kBAAkB,GAAG,YAAY,CAAC;kBAClC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;iBAC5C,MAAM;kBACL,kBAAkB,GAAG,CAAC,EAAE,WAAW,CAAC,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;kBACxE,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;kBACpC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;iBACxH;eACF,MAAM;gBACL,kBAAkB,GAAG,CAAC,EAAE,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;eACnD;cACD,sBAAsB,GAAG,kBAAkB,CAAC;cAC5C,MAAM,iBAAiB,GAAG;gBACxB,SAAS,CAAC,CAAC,CAAC;gBACZ,SAAS,CAAC,CAAC,CAAC;gBACZ,SAAS,CAAC,CAAC,CAAC;gBACZ,SAAS,CAAC,CAAC,CAAC;gBACZ,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;gBACvB,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;gBACvB,kBAAkB;eACnB,CAAC;cACF,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,CAAC,YAAY,EAAE,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;cACvF,IAAI,cAAc,EAAE;gBAClB,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;eACtC;cACD,IAAI,YAAY,EAAE;gBAChB,YAAY,CAAC,kBAAkB,EAAE,iBAAiB,CAAC,CAAC;eACrD;cACD,OAAO,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;YAC5C,KAAK,aAAa;cAChB,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,CAAC,cAAc,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,4BAA4B,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;cAClM,OAAO,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;WACvC;UACD,IAAI,MAAM,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;UAC/C,QAAQ,OAAO,MAAM;YACnB,KAAK,WAAW;cACd,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;cACvE,OAAO;YACT,KAAK,QAAQ,CAAC;YACd,KAAK,SAAS;cACZ,IAAI,sBAAsB,IAAI,gBAAgB,CAAC,OAAO,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;gBACzF,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,EAAE,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAChI,gBAAgB,CAAC,IAAI,CAAC,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC3D,MAAM;eACP;YACH;cACE,IAAI,MAAM,KAAK,IAAI,EAAE;gBACnB,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;eAC/D,MAAM;gBACL,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,EAAE,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;eACjI;cAED,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;WACjC;UACD,OAAO,MAAM,CAAC;SACf;OACF;MACD,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,GAAG,QAAQ,CAAC;MACrC,OAAO,EAAE,CAAC,QAAQ,CAAC,CAAC;KACrB;IACD,SAAS,QAAQ,GAAG;MAClB,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAC7B;IACD,SAAS,KAAK,GAAG;MACf,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;QAC3B,SAAS,CAAC,GAAG,EAAE,CAAC;OACjB;KACF;IACD,SAAS,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE;MACnC,SAAS,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;KACzB;IACD,SAAS,SAAS,CAAC,KAAK,EAAE;MACxB,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;MAChC,IAAI,IAAI,EAAE;QACR,OAAO,WAAW,GAAG,GAAG,GAAG,IAAI,CAAC;OACjC;MACD,OAAO,KAAK,CAAC;KACd;IACD,SAAS,SAAS,CAAC,MAAM,EAAE;MACzB,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;KAC7B;IACD,SAAS,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE;MAClC,MAAM,YAAY,GAAG,CAAC,EAAE,WAAW,CAAC,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;MACxE,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;MAC9D,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;MAC7B,OAAO,YAAY,CAAC;KACrB;IACD,SAAS,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE;MAC/B,MAAM,cAAc,GAAG,CAAC,EAAE,WAAW,CAAC,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;MAC1E,MAAM,aAAa,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;MAChD,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,YAAY,EAAE,cAAc,CAAC,UAAU,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC;MACvI,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,oBAAoB,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC,CAAC;MAClF,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,aAAa,CAAC,IAAI,EAAE,cAAc,CAAC,YAAY,EAAE,cAAc,CAAC,gBAAgB,EAAE,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC;MAC/I,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;MAC7B,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,qCAAqC,CAAC,CAAC,CAAC;MACjE,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,iCAAiC,EAAE,cAAc,CAAC,OAAO,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC;MACvG,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;MAC7B,UAAU,EAAE,CAAC;KACd;IACD,SAAS,UAAU,CAAC,KAAK,EAAE;MACzB,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;KACxC;IACD,SAAS,eAAe,GAAG;MACzB,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC;AAC7B,EAAE,MAAM,CAAC,cAAc,EAAE,WAAW,CAAC;AACrC,EAAE,MAAM,CAAC,cAAc,EAAE,WAAW,CAAC;AACrC,EAAE,MAAM,CAAC;AACT,EAAE,MAAM,CAAC;AACT,EAAE,MAAM,CAAC;AACT,EAAE,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC;AAC/B,EAAE,MAAM,CAAC,uBAAuB,EAAE,WAAW,CAAC;AAC9C,EAAE,MAAM,CAAC;AACT,EAAE,MAAM,CAAC;AACT,EAAE,MAAM,CAAC;AACT,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;KACd;IACD,SAAS,kBAAkB,CAAC,MAAM,EAAE,IAAI,EAAE;MACxC,OAAO,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,iBAAiB,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,4BAA4B,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;KACnK;IAED,SAAS,eAAe,CAAC,KAAK,EAAE;MAC9B,IAAI,SAAS,EAAE;QACb,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE;UAC5B,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,KAAK,EAAE;YAC7B,OAAO,IAAI,CAAC;WACb;SACF;OACF;MACD,OAAO,IAAI,CAAC;KACb;IAED,SAAS,sBAAsB,CAAC,KAAK,EAAE;MACrC,MAAM,CAAC,GAAG,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;MAC1C,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE;QACZ,OAAO,CAAC,EAAE,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;OACrC;MACD,OAAO,IAAI,CAAC;KACb;GACF;EAQD,SAAS,kBAAkB,CAAC,SAAS,EAAE,OAAO,EAAE;IAC9C,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;IACpD,MAAM,oBAAoB,GAAG,EAAE,CAAC;IAChC,MAAM;MACJ,WAAW;MACX,gBAAgB;MAChB,SAAS;MACT,sBAAsB;MACtB,SAAS;MACT,SAAS;MACT,MAAM;MACN,4BAA4B;KAC7B,GAAG,OAAO,CAAC;IACZ,OAAO,KAAK,CAAC;IACb,SAAS,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE;MAC7B,IAAI,OAAO,GAAG,CAAC,QAAQ,CAAC,KAAK,UAAU,EAAE;QACvC,OAAO,WAAW;UAChB,QAAQ,QAAQ;YACd,KAAK,kBAAkB;cACrB,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,CAAC,mBAAmB,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,kBAAkB,EAAE,WAAW,EAAE,SAAS,EAAE,4BAA4B,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;cAC1N,OAAO,SAAS,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;WACnD;UACD,IAAI,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;UAC7D,QAAQ,OAAO,MAAM;YACnB,KAAK,WAAW;cACd,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;cACvE,OAAO;YACT,KAAK,QAAQ,CAAC;YACd,KAAK,SAAS;cACZ,IAAI,sBAAsB,IAAI,gBAAgB,CAAC,OAAO,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;gBACzF,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,EAAE,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAChI,gBAAgB,CAAC,IAAI,CAAC,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;eAC5D,MAAM;gBACL,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,EAAE,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAChI,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;eAC/B;cACD,MAAM;YACR;cACE,IAAI,MAAM,KAAK,IAAI,EAAE;gBACnB,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;eAC/D,MAAM;gBACL,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,EAAE,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;eACjI;cACD,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;WACjC;UACD,OAAO,MAAM,CAAC;SACf,CAAC;OACH;MACD,oBAAoB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,GAAG,QAAQ,CAAC;MACrD,OAAO,SAAS,CAAC,QAAQ,CAAC,CAAC;KAC5B;IAED,SAAS,kBAAkB,CAAC,KAAK,EAAE;MACjC,IAAI,oBAAoB,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE;QAC9C,OAAO,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;OACxD;MACD,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;KACzB;IAED,SAAS,kBAAkB,CAAC,MAAM,EAAE,IAAI,EAAE;MACxC,OAAO,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,iBAAiB,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,kBAAkB,EAAE,WAAW,EAAE,SAAS,EAAE,4BAA4B,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;KACvL;IAED,SAAS,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE;MAClC,MAAM,YAAY,GAAG,CAAC,EAAE,WAAW,CAAC,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;MACxE,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;MAC7B,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;MAC9D,OAAO,YAAY,CAAC;KACrB;GACF;EAED,SAAS,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE;IACxC,MAAM,EAAE,SAAS,EAAE,4BAA4B,EAAE,GAAG,OAAO,CAAC;IAC5D,QAAQ,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK;MACpC,MAAM,YAAY,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;MAC1C,IAAI,YAAY,EAAE;QAChB,OAAO,YAAY,CAAC;OACrB;MACD,OAAO,gBAAgB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;KACvC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;IAEf,SAAS,eAAe,CAAC,KAAK,EAAE;MAC9B,IAAI,SAAS,EAAE;QACb,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE;UAC5B,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,SAAS;UAC9C,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,KAAK,EAAE;YAC7B,OAAO,IAAI,CAAC;WACb;SACF;OACF;MACD,IAAI,4BAA4B,EAAE;QAChC,OAAO,4BAA4B,CAAC,KAAK,CAAC,CAAC;OAC5C;MACD,OAAO,IAAI,CAAC;KACb;GACF;EAED,SAAS,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE;IACtC,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,WAAW,EAAE,4BAA4B,EAAE,GAAG,OAAO,CAAC;IACxG,IAAI,OAAO,GAAG,KAAK,WAAW,EAAE;MAC9B,OAAO,WAAW,CAAC;KACpB;IACD,IAAI,GAAG,KAAK,IAAI,EAAE;MAChB,OAAO,MAAM,CAAC;KACf;IACD,MAAM,CAAC,GAAG,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE;MACV,OAAO,CAAC,EAAE,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;KACrC;IACD,QAAQ,GAAG,CAAC,WAAW,CAAC,IAAI;MAC1B,KAAK,QAAQ;QACX,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,eAAe,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,eAAe,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,QAAQ,EAAE;UACZ,OAAO,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;SACxB,MAAM,IAAI,eAAe,IAAI,CAAC,eAAe,EAAE;UAC9C,OAAO,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;SACxB,MAAM,IAAI,CAAC,eAAe,IAAI,eAAe,EAAE;UAC9C,OAAO,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;SACxB,MAAM;UACL,OAAO,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC;SAC1B;MACH,KAAK,QAAQ,EAAE,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;MACrC,KAAK,SAAS,EAAE,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;MACtC,KAAK,OAAO;QACV,OAAO,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;MACzF,KAAK,cAAc,CAAC;MACpB,KAAK,YAAY,CAAC;MAClB,KAAK,aAAa,CAAC;MACnB,KAAK,YAAY;QACf,OAAO,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;MAC7F;QACE,IAAI,4BAA4B,EAAE;UAChC,MAAM,mBAAmB,GAAG,4BAA4B,CAAC,GAAG,CAAC,CAAC;UAC9D,IAAI,mBAAmB,EAAE;YACvB,OAAO,mBAAmB,CAAC;WAC5B;SACF;QACD,MAAM,IAAI,KAAK,CAAC,CAAC,2BAA2B,EAAE,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACzE;GACF;EAED,SAAS,kBAAkB,CAAC,KAAK,EAAE;IAEjC,OAAO,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;GACrC;AAED,EAAmC;IACjC,cAAc,GAAG,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC;GACpD;EAED,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;IACjC,SAAS,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;IAClD,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC;GAC9B;;;;;EClXD,SAAS,oBAAoB,CAAC,EAAE,EAAE;EAClC,EAAE,OAAO,EAAE,CAAC,QAAQ,EAAE;EACtB,KAAK,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;EACtB,KAAK,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;EAC9B,KAAK,OAAO,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;EACxC,CAAC;AAWD,EAAO,SAAS,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,kBAAkB,EAAE,oBAAoB,EAAE;EACrG,EAAE,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI;EAC5C,IAAI,QAAQ,OAAO,GAAG;EACtB,MAAM,KAAK,SAAS;EACpB,QAAQ,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;EAChC,MAAM,KAAK,QAAQ;EACnB,QAAQ,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;EAC/B,MAAM;EACN,QAAQ,OAAO,GAAG,CAAC;EACnB,KAAK;EACL,GAAG,CAAC,GAAG,IAAI,CAAC;AACZ,EACA,EAAE,MAAM,UAAU,GAAG,EAAE,CAAC;EACxB,EAAE,MAAM,OAAO,GAAGC,WAAS,CAAC,YAAY,CAAC,OAAO,EAAE;EAClD,IAAI,sBAAsB,EAAE,IAAI;EAChC,IAAI,YAAY,EAAE,CAAC,UAAU,KAAK;EAClC,MAAM,IAAI,MAAM,CAAC,UAAU,EAAE;EAC7B,QAAQ,IAAI,CAAC,6BAA6B,EAAE;EAC5C,UAAU,UAAU,CAAC,IAAI,CAAC,CAAC,6BAA6B,EAAE,eAAe,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;EACpG,UAAU,6BAA6B,GAAG,IAAI,CAAC;EAC/C,SAAS,MAAM;EACf,UAAU,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,qBAAqB,EAAE,CAAC,CAAC,QAAQ,CAAC;EAC/E,UAAU,UAAU,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,GAAG,GAAG,QAAQ,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,eAAe,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACvI,SAAS;EACT,QAAQ,IAAI,qBAAqB,KAAK,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE;EAChE,UAAU,UAAU,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;EAChD,SAAS;EACT,QAAQ,OAAO;EACf,OAAO;EACP,MAAM,IAAI,UAAU,EAAE;EACtB,QAAQ,UAAU,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,eAAe,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC9E,OAAO,MAAM;EACb,QAAQ,UAAU,CAAC,IAAI,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC;EAC5C,OAAO;EACP,KAAK;EACL,IAAI,4BAA4B,EAAE,CAAC,QAAQ,KAAK;EAChD,MAAM,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,eAAe,EAAE,EAAE,EAAE,OAAO,AAAgB,CAAC,CAAC;EAC1G,MAAM,IAAI,YAAY,EAAE;EACxB,QAAQ,OAAO,YAAY,CAAC;EAC5B,OAAO;EACP,MAAM,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,eAAe,EAAE,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,OAAO,AAAgB,CAAC,CAAC;EAC1K,MAAM,IAAI,YAAY,EAAE;EACxB,QAAQ,OAAO,YAAY,CAAC;EAC5B,OAAO;EACP,MAAM,OAAO,IAAI,CAAC;EAClB,KAAK;EACL,GAAG,CAAC,CAAC;EACL,EAAE,IAAI,6BAA6B,GAAG,KAAK,CAAC;EAC5C,EAAE,IAAI,qBAAqB,GAAG,CAAC,CAAC;EAChC,EAAE,MAAM;EACR,IAAI,MAAM;EACV,IAAI,MAAM;EACV,IAAI,MAAM;EACV,IAAI,QAAQ;EACZ,IAAI,SAAS;EACb,IAAI,iBAAiB;EACrB,IAAI,SAAS;EACb,IAAI,mBAAmB;EACvB,IAAI,SAAS;EACb,IAAI,0BAA0B;EAC9B,IAAI,SAAS;EACb,IAAI,eAAe;EACnB,IAAI,UAAU;EACd,IAAI,SAAS;EACb,IAAI,aAAa;EACjB,IAAI,aAAa;EACjB,IAAI,eAAe;EACnB,IAAI,eAAe;EACnB,GAAG,GAAG,YAAY,CAAC;EACnB,EAAE,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE;EACpC,IAAI,MAAM;EACV,IAAI,OAAO;EACX,IAAI,YAAY,EAAE,KAAK;EACvB,IAAI,MAAM;EACV,IAAI,QAAQ;EACZ,IAAI,SAAS;EACb,IAAI,iBAAiB;EACrB,IAAI,SAAS;EACb,IAAI,mBAAmB;EACvB,IAAI,SAAS;EACb,IAAI,0BAA0B;EAC9B,IAAI,SAAS;EACb,IAAI,eAAe;EACnB,IAAI,UAAU;EACd,IAAI,SAAS;EACb,IAAI,aAAa;EACjB,IAAI,aAAa;EACjB,GAAG,CAAC,CAAC;EACL,EAAE,IAAI,MAAM,GAAG,EAAE,CAAC;EAClB,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;EACvB,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;EACnC,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;EAClC,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;EAElB,EAAE,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,cAAc,EAAE,CAAC,KAAK;EACxD,IAAI,QAAQ,cAAc,CAAC,IAAI;EAE/B,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,OAAO,CAAC;EAEnB,MAAM,KAAK,OAAO,CAAC;EACnB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,WAAW,CAAC;EACvB,MAAM,KAAK,WAAW;EACtB,QAAQ,OAAO,CAAC,cAAc,CAAC,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC;EACjG,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,KAAK,IAAI,UAAU,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE;EAC5E,UAAU,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;EAC9B,UAAU,OAAO,CAAC,cAAc,CAAC,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;EACvG,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,OAAO;EAClB,QAAQ,OAAO,CAAC,cAAc,CAAC,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC;EACjG,QAAQ,MAAM;EACd,MAAM,KAAK,8BAA8B,CAAC;EAC1C,MAAM,KAAK,eAAe,CAAC;EAC3B,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,OAAO,CAAC,cAAc,CAAC,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;EACtF,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,6DAA6D,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK;EACL,GAAG,CAAC,CAAC;EACL,EAAE,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;EACrD,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,oBAAoB,CAACJ,OAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;EACnE,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,oBAAoB,CAACA,OAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1E,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,oBAAoB,CAACA,OAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1E,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,oBAAoB,CAACA,OAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1E,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,oBAAoB,CAACA,OAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;EACjE,EAAE,IAAI,MAAM,CAAC,YAAY,KAAK,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC,YAAY,EAAE;EAC3E,IAAI,MAAM,CAAC,IAAI;EACf,MAAM,CAAC,gCAAgC,EAAE,oBAAoB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;EACrF,KAAK,CAAC;EACN,GAAG;EACH,EAAE,MAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;EACnD,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,gCAAgC,EAAE,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,cAAc,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;EACvI,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;EACvB,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;EACjC,EAAE,IAAI,MAAM,CAAC,aAAa,EAAE;EAC5B,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;EAC3B,GAAG,MAAM,IAAI,MAAM,CAAC,YAAY,EAAE;EAClC,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;EAC1B,GAAG;EACH,EAAE,MAAM,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;EACnE,EAAE,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,cAAc,IAAI;EACnD,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;EAC5F,GAAG,CAAC,CAAC;EACL,EAAE,MAAM,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;EACjE,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;EAClC,EAAE,IAAI,MAAM,CAAC,YAAY,KAAK,MAAM,CAAC,aAAa,EAAE;EACpD,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;EACpB,IAAI,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;EAC3C,IAAI,MAAM,WAAW,GAAG,OAAO,CAAC,sBAAsB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;EAC7E,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;;iBAEA,GAAG,WAAW,EAAE;eAClB,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE;iBACtB,GAAG,gBAAgB,CAAC,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE;QAC3D,CAAC,CAAC,CAAC;EACX,IAAI,MAAM,EAAE,UAAU,EAAE,uBAAuB,EAAE,GAAG,MAAM,CAAC;EAC3D,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAChD,MAAM,MAAM,OAAO,GAAG,uBAAuB,CAAC,CAAC,CAAC,CAAC;EACjD,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;EACtC,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;EAC1D,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;EAC3E,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;MACb,EAAE,SAAS,CAAC,QAAQ,CAAC;iBACV,GAAG,oBAAoB,EAAE;eAC3B,GAAG,eAAe,CAAC,IAAI,EAAE;iBACvB,GAAG,gBAAgB,CAAC,eAAe,EAAE,oBAAoB,CAAC,EAAE;QACrE,CAAC,CAAC,CAAC;EACX,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;EAC1B,GAAG;EACH,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI,GAAG,oBAAoB,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;EACxF,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EACrC,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACtB,EAAE,IAAI,MAAM,CAAC,SAAS,EAAE;EACxB,IAAI,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;EAC5C,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,oCAAoC,CAAC,CAAC,CAAC;EACxD,GAAG;EACH,EAAE,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;EAEvC,EAAE,IAAI,eAAe,GAAG,EAAE,CAAC;EAC3B,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC,cAAc,KAAK;EAC9C,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,IAAI,cAAc,CAAC,qBAAqB,EAAE,CAAC,CAAC,CAAC,CAAC;EACxE,GAAG,CAAC,CAAC;EACL,EAAE,OAAO,CAAC;;EAER,EAAE,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3B,EAAE,kBAAkB,GAAG,kBAAkB,GAAG,EAAE,CAAC;AACjD,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;CACnB,CAAC,CAAC;EACH,CAAC;EAED,SAAS,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE;EAC7C,EAAE,MAAM,aAAa,GAAG,MAAM,CAAC,SAAS,KAAK,QAAQ,GAAG,UAAU,GAAG,CAAC,iBAAiB,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;EAC9G,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;EACxB,IAAI,OAAO,CAAC,aAAa,EAAE,aAAa,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC3G,GAAG;EACH,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;EACxB,IAAI,OAAO,CAAC,aAAa,EAAE,aAAa,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACtF,GAAG;EAEH,EAAE,OAAO,CAAC,aAAa,EAAE,aAAa,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/D,CAAC;EAED,SAAS,kBAAkB,CAAC,MAAM,EAAE;EACpC,EAAE,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;EAChD,EAAE,MAAM,kBAAkB,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EAC1D,EAAE,OAAOA,OAAK,CAAC,uBAAuB,CAAC,CAAC,EAAE,kBAAkB,GAAG,WAAW,GAAG,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE;EACjG,IAAI,cAAc,EAAE,CAAC,MAAM,EAAE,IAAI,KAAK;EACtC,MAAM,IAAI,MAAM,KAAK,OAAO,EAAE;EAC9B,QAAQ,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAEA,OAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;EAC5D,OAAO;EACP,MAAM,OAAO,IAAI,CAAC;EAClB,KAAK;EACL,IAAI,UAAU,EAAE,CAAC,QAAQ,KAAK;EAC9B,MAAM,IAAI,QAAQ,KAAK,SAAS,EAAE;EAClC,QAAQ,OAAO,IAAI,CAAC;EACpB,OAAO;EACP,MAAM,IAAI,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE;EAC3C,QAAQ,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;EAChD,OAAO;EACP,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,qBAAqB,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC;EAC5D,KAAK;EACL,GAAG,CAAC,CAAC;EACL,CAAC;EAED,SAAS,gBAAgB,CAAC,YAAY,EAAE,WAAW,EAAE;EACrD,EAAE,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;EAClD,EAAE,MAAM,kBAAkB,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACxD,EAAE,MAAM,kBAAkB,GAAGA,OAAK,CAAC,uBAAuB,CAAC,CAAC,EAAE,kBAAkB,GAAG,WAAW,GAAG,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE;EACnH,IAAI,cAAc,EAAE,CAAC,MAAM,EAAE,IAAI,KAAK;EACtC,MAAM,IAAI,MAAM,KAAK,OAAO,EAAE;EAC9B,QAAQ,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAEA,OAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;EAC5D,OAAO,MAAM,IAAI,MAAM,KAAK,MAAM,EAAE;EACpC,QAAQ,OAAO,CAAC,EAAE,kBAAkB,GAAG,WAAW,GAAG,EAAE,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;EAC1F,OAAO,MAAM;EACb,QAAQ,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;EAChD,OAAO;EACP,KAAK;EACL,IAAI,UAAU,EAAE,CAAC,QAAQ,KAAK;EAC9B,MAAM,IAAI,QAAQ,KAAK,SAAS,EAAE;EAClC,QAAQ,OAAO,WAAW,CAAC;EAC3B,OAAO;EACP,MAAM,IAAI,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE;EACjD,QAAQ,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;EACtD,OAAO;EACP,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,qBAAqB,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC;EAC5D,KAAK;EACL,GAAG,CAAC,CAAC;EACL,EAAE,OAAO,CAAC;EACR,EAAE,kBAAkB,CAAC;;GAEpB,CAAC,CAAC;EACL,CAAC;EAWD,SAAS,eAAe,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE;EAClF,EAAE,IAAI,QAAQ,KAAK,IAAI,EAAE,OAAO,IAAI,CAAC;EACrC,EAAE,QAAQ,OAAO,QAAQ;EACzB,IAAI,KAAK,SAAS,CAAC;EACnB,IAAI,KAAK,QAAQ;EACjB,MAAM,OAAO,IAAI,CAAC;EAClB,GAAG;EACH,EAAE;EACF,IAAI,OAAO,gBAAgB,KAAK,WAAW;EAC3C,IAAI,QAAQ,YAAY,gBAAgB;EACxC,IAAI;EACJ,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,MAAM,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;EAC1C,MAAM,IAAI,WAAW,CAAC,IAAI,KAAK,gBAAgB,EAAE,SAAS;EAC1D,MAAM,IAAI,WAAW,CAAC,WAAW,KAAK,QAAQ,EAAE,SAAS;EAEzD,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EACxD,MAAM,IAAI,aAAa,KAAK,CAAC,CAAC,EAAE,SAAS;EACzC,MAAM,MAAM,YAAY,GAAG,CAAC,YAAY,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;EAC/E,MAAM,OAAO,CAAC,cAAc,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;EACrD,MAAM,OAAO,YAAY,CAAC;EAC1B,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAChD,IAAI,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;EACxC,IAAI,IAAI,QAAQ,KAAK,WAAW,CAAC,WAAW,EAAE,SAAS;EACvD,IAAI,MAAM,QAAQ,GAAG,CAAC,YAAY,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;EACvD,IAAI,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;EAClD,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,OAAO,IAAI,CAAC;EACd,CAAC;;EC7UM,MAAM,WAAW,CAAC;EAMzB,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,MAAM;EACV,MAAM,IAAI;EACV,MAAM,MAAM;EACZ,MAAM,OAAO;EACb,MAAM,YAAY;EAClB,MAAM,sBAAsB;EAC5B,MAAM,qBAAqB;EAC3B,MAAM,MAAM;EACZ,MAAM,cAAc;EACpB,MAAM,IAAI;EACV,MAAM,MAAM;EACZ,KAAK,GAAG,QAAQ,CAAC;EACjB,IAAI,IAAI,CAAC,IAAI,EAAE;EACf,MAAM,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;EACtC,KAAK;EACL,IAAI,IAAI,CAAC,IAAI,EAAE;EACf,MAAM,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;EACtC,KAAK;EACL,IAAI,IAAI,CAAC,MAAM,EAAE;EACjB,MAAM,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;EACxC,KAAK;EACL,IAAI,IAAI,CAAC,MAAM,EAAE;EACjB,MAAM,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;EACxC,KAAK;EACL,IAAI,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,WAAW,EAAE;EACrD,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,+CAA+C,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;EACrF,KAAK;EACL,IAAI,IAAI,CAAC,sBAAsB,EAAE;EACjC,MAAM,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;EAC3D,KAAK;EACL,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;EACrB,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;EACzB,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;EACzB,IAAI,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;EACvC,IAAI,IAAI,CAAC,OAAO,GAAG,MAAM,KAAK,WAAW,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;EACvE,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;EACzB,IAAI,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;EAEzC,IAAI,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC;EACnC,IAAI,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC;EACnC,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;EACtB,IAAI,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;EAC3B,IAAI,IAAI,CAAC,YAAY,GAAG,YAAY,KAAK,IAAI,IAAI,YAAY,KAAK,SAAS,GAAG,YAAY,GAAG,IAAI,CAAC;EAClG,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;EAC9B,IAAI,IAAI,CAAC,sBAAsB,GAAG,sBAAsB,CAAC;EACzD,IAAI,IAAI,CAAC,qBAAqB,GAAG,qBAAqB,CAAC;EACvD,IAAI,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;EACnC,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,2BAA2B,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC7E,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,6BAA6B,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC/E,GAAG;EACH,CAAC;;EC9DM,MAAM,gBAAgB,SAAS,WAAW,CAAC;EAKlD,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;EAC7B,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;EACvB,IAAI,IAAI,CAAC,uBAAuB,GAAG,KAAK,CAAC,WAAW,CAAC;EACrD,IAAI,IAAI,CAAC,gBAAgB,GAAG,QAAQ,CAAC,gBAAgB,CAAC;EACtD,IAAI,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC,cAAc,CAAC;EAClD,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;EAC5B,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;EAC5B,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;EACzB,GAAG;EAOH,EAAE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE;EAC3B,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO;EACtC,IAAI,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC;EAChE,IAAI,IAAI,KAAK,GAAG,cAAc,IAAI,MAAM,GAAG,cAAc,EAAE;EAC3D,MAAM,IAAI,KAAK,GAAG,MAAM,EAAE;EAC1B,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,kBAAkB,EAAE,KAAK,CAAC,6BAA6B,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC,CAAC;EACjH,OAAO,MAAM;EACb,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,mBAAmB,EAAE,MAAM,CAAC,6BAA6B,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC,CAAC;EACnH,OAAO;EACP,KAAK;EACL,GAAG;EAEH,EAAE,cAAc,GAAG;EACnB,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;EAC3C,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;EACxB,GAAG;EAEH,EAAE,YAAY,GAAG;EACjB,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,sBAAsB,EAAE,CAAC;EACvD,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;EACvC,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC;EACxC,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC;EACnC,GAAG;EAEH,EAAE,oBAAoB,CAAC,KAAK,EAAE;EAC9B,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;EACjC,MAAM,OAAO,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;EACjD,KAAK;EACL,IAAI,QAAQ,KAAK,CAAC,WAAW;EAC7B,MAAM,KAAK,KAAK,CAAC;EACjB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,SAAS;EACpB,QAAQ,OAAO,YAAY,CAAC;EAC5B,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,WAAW,CAAC;EACvB,MAAM,KAAK,WAAW,CAAC;EACvB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY;EACvB,QAAQ,OAAO,KAAK,CAAC,WAAW,CAAC;EACjC,KAAK;EACL,IAAI,OAAO,CAAC,IAAI,CAAC,wGAAwG,CAAC,CAAC;EAC3H,IAAI,OAAO,KAAK,CAAC,WAAW,CAAC;EAC7B,GAAG;EAUH,EAAE,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE;EAC3C,IAAI,IAAIA,OAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,mBAAmB,EAAE;EAE7D,MAAM,MAAM,UAAU,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;EAClD,MAAMA,OAAK,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;EACzC,MAAM,OAAO,UAAU,CAAC;EACxB,KAAK,MAAM;EACX,MAAM,QAAQ,KAAK,CAAC,WAAW;EAC/B,QAAQ,KAAK,iBAAiB,CAAC;EAC/B,QAAQ,KAAK,UAAU,CAAC;EACxB,QAAQ,KAAK,SAAS,CAAC;EACvB,QAAQ,KAAK,WAAW,CAAC;EACzB,QAAQ,KAAK,UAAU,CAAC;EACxB,QAAQ,KAAK,YAAY,CAAC;EAC1B,QAAQ,KAAK,UAAU,EAAE;EACzB,UAAU,MAAM,UAAU,GAAG,IAAI,IAAI,IAAI,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;EACpE,UAAUA,OAAK,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;EAC7C,UAAU,OAAO,UAAU,CAAC;EAC5B,SAAS;EACT,QAAQ,SAAS;EACjB,UAAU,MAAM,UAAU,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;EACtD,UAAUA,OAAK,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;EAC7C,UAAU,OAAO,UAAU,CAAC;EAC5B,SAAS;EACT,OAAO;EACP,KAAK;EACL,GAAG;EAOH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;EACjC,MAAM,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;EACxC,KAAK,MAAM,IAAI,KAAK,CAAC,WAAW,KAAK,KAAK,EAAE;EAC5C,MAAM,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;EAC3C,KAAK;EACL,IAAI,QAAQ,KAAK,CAAC,WAAW;EAC7B,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,SAAS;EACpB,QAAQ,OAAO,CAAC,CAAC;EACjB,MAAM,KAAK,WAAW,CAAC;EACvB,MAAM,KAAK,UAAU;EACrB,QAAQ,OAAO,CAAC,CAAC;EACjB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM;EACN,QAAQ,OAAO,CAAC,CAAC;EACjB,KAAK;EACL,GAAG;EAKH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,2CAA2C,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC3F,GAAG;EAEH,EAAE,0BAA0B,GAAG;EAC/B,IAAI,QAAQ,IAAI,CAAC,MAAM;EACvB,MAAM,KAAK,OAAO;EAClB,QAAQ,OAAO,MAAM,CAAC;EACtB,MAAM,KAAK,aAAa;EACxB,QAAQ,OAAO,OAAO,CAAC;EACvB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM;EACN,QAAQ,OAAO,SAAS,CAAC;EACzB,KAAK;EACL,GAAG;EACH,CAAC;;ECrJM,MAAM,uBAAuB,SAAS,gBAAgB,CAAC;EAC9D,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;EAC7B,GAAG;EACH,EAAE,SAAS,CAAC,KAAK,EAAE;EACnB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE;EACrC,MAAM,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;EACnD,KAAK;EACL,IAAI,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;EACjE,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,OAAO;EAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC;EAChE,GAAG;EACH,CAAC;;ECpBM,MAAM,qBAAqB,SAAS,gBAAgB,CAAC;EAC5D,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;EAC7B,GAAG;EACH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;EACjE,GAAG;EACH,EAAE,SAAS,CAAC,KAAK,EAAE;EACnB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE;EACrC,MAAM,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;EACnC,QAAQ,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;EACxD,OAAO;EACP,MAAM,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;EACpD,KAAK;EACL,IAAI,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;EACzC,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,OAAO;EAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC;EAChE,GAAG;EACH,CAAC;;ECtBM,MAAM,uBAAuB,SAAS,gBAAgB,CAAC;EAC9D,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;EAC7B,GAAG;EACH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;EACjE,GAAG;EACH,EAAE,SAAS,CAAC,KAAK,EAAE;EACnB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE;EACrC,MAAM,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;EAC9D,KAAK;EACL,IAAI,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;EACvC,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,OAAO;EAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC;EAChE,GAAG;EACH,CAAC;;ECnBM,MAAM,yBAAyB,SAAS,gBAAgB,CAAC;EAChE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;EACpC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,UAAU,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;EACzC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACvC,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;EAC7B,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;EACjE,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,UAAU,EAAE;EAC1B,IAAI,IAAI,UAAU,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EACjE,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;EACjD,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC,CAAC;EACvG,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;ECvCM,MAAM,gCAAgC,SAAS,yBAAyB,CAAC;EAChF,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;EACpC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,UAAU,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;EACzC,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACvC,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECnBM,MAAM,yBAAyB,SAAS,yBAAyB,CAAC,EAAE;;ECApE,MAAM,gCAAgC,SAAS,gCAAgC,CAAC,EAAE;;ECClF,MAAM,2BAA2B,SAAS,gBAAgB,CAAC;EAClE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;EACtB,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;EAC/B,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC/D,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,kCAAkC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;EACvF,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAChE,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EAClE,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EACnD,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC/H,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;EC5CM,MAAM,kCAAkC,SAAS,2BAA2B,CAAC;EACpF,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;EAC/B,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC/D,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,kCAAkC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;EACvF,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAChE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECpBM,MAAM,6BAA6B,SAAS,gBAAgB,CAAC;EACpE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC5C,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;EACjC,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC/D,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,mCAAmC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EACjG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;EACzG,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;EACnE,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAC5E,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;EAClE,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,qBAAqB,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;EACxG,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,iCAAiC,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;EAC3F,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,uBAAuB,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EACrE,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;EACtD,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EACvI,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;EC/CM,MAAM,oCAAoC,SAAS,6BAA6B,CAAC;EACxF,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;EAC/B,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC/D,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,mCAAmC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EACjG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;EACzG,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;EACxD,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAC3D,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECtBM,MAAM,4CAA4C,SAAS,gBAAgB,CAAC;EACnF,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;EACvC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;EACxB,IAAI,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;EACvC,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC;EAClC,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC;EACrC,IAAI,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;EACnC,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;EACzE,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,YAAY,EAAE;EAC5B,IAAI,IAAI,YAAY,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EACnE,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,EAAE;EACpE,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,2BAA2B,CAAC,CAAC,CAAC;EACtF,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,WAAW,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;EAC3E,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;ECrCM,MAAM,mDAAmD,SAAS,4CAA4C,CAAC;EACtH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,YAAY,EAAE;EAC5B,IAAI,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/D,IAAI,IAAI,CAAC,UAAU,GAAG,YAAY,CAAC,UAAU,CAAC;EAC9C,IAAI,IAAI,CAAC,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC;EACzC,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;EACpC,GAAG;EACH,CAAC;;ECjBM,MAAM,6BAA6B,SAAS,gBAAgB,CAAC;EACpE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;EACvC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;EACxB,IAAI,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;EACpD,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC5C,IAAI,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;EACjC,IAAI,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;EACnC,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC;EACrC,IAAI,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;EACnC,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;EACzE,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,YAAY,EAAE;EAC5B,IAAI,IAAI,YAAY,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EACnE,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,EAAE;EACpE,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC;EACrF,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,WAAW,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;EAC3E,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;ECvCM,MAAM,oCAAoC,SAAS,6BAA6B,CAAC;EACxF,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;EACvC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EACjD,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC;EAClC,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECjBM,MAAM,2BAA2B,SAAS,gBAAgB,CAAC;EAClE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;EACtB,IAAI,IAAI,CAAC,UAAU,GAAGA,OAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACvD,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,kCAAkC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;EACvF,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAChE,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EAC5D,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7C,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC/H,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;EC3CM,MAAM,kCAAkC,SAAS,2BAA2B,CAAC;EACpF,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,UAAU,GAAGA,OAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACvD,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,kCAAkC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;EACvF,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAChE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECnBM,MAAM,8BAA8B,SAAS,gBAAgB,CAAC;EACrE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;EACtB,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;EACzB,GAAG;EAEH,EAAE,QAAQ,CAAC,KAAK,EAAE;EAClB,IAAI,MAAM,eAAe,GAAGA,OAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EAC7D,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,kCAAkC,CAAC,eAAe,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;EACjE,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;EACvF,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAChE,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EAC5D,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EACpD,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC/H,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;EChDM,MAAM,qCAAqC,SAAS,8BAA8B,CAAC;EAC1F,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;EACzB,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECfM,MAAM,8BAA8B,SAAS,gBAAgB,CAAC;EACrE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;EACtB,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;EACzB,GAAG;EAEH,EAAE,QAAQ,CAAC,KAAK,EAAE;EAClB,IAAI,MAAM,eAAe,GAAGA,OAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EAC7D,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,kCAAkC,CAAC,eAAe,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;EAClF,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;EACvF,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAChE,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EAC5D,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EACpD,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC/H,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;EChDM,MAAM,qCAAqC,SAAS,8BAA8B,CAAC;EAC1F,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;EACzB,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECfM,MAAM,8BAA8B,SAAS,gBAAgB,CAAC;EACrE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;EACtB,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;EACzB,GAAG;EAEH,EAAE,QAAQ,CAAC,KAAK,EAAE;EAClB,IAAI,MAAM,eAAe,GAAGA,OAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EAC7D,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,kCAAkC,CAAC,eAAe,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACnG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;EACvF,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAChE,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EAC5D,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EACpD,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC/H,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;EChDM,MAAM,qCAAqC,SAAS,8BAA8B,CAAC;EAC1F,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;EACzB,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECfM,MAAM,4BAA4B,SAAS,gBAAgB,CAAC;EACnE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;EAC7B,GAAG;EACH,EAAE,SAAS,CAAC,KAAK,EAAE;EACnB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE;EACrC,MAAM,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EACxE,KAAK;EACL,IAAI,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAE1B,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,OAAO,EAAE,CAAC;EAC/C,IAAI,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;EACjE,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,OAAO;EAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC;EACjE,GAAG;EACH,CAAC;;ECtBM,MAAM,4BAA4B,SAAS,gBAAgB,CAAC;EACnE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;EAC7B,GAAG;EACH,EAAE,SAAS,CAAC,KAAK,EAAE;EACnB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE;EACrC,MAAM,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EACpF,KAAK;EACL,IAAI,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAE1B,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,OAAO,EAAE,CAAC;EAC/C,IAAI,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;EACjE,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,OAAO;EAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC;EACjE,GAAG;EACH,CAAC;;ECtBM,MAAM,4BAA4B,SAAS,gBAAgB,CAAC;EACnE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;EAC7B,GAAG;EACH,EAAE,SAAS,CAAC,KAAK,EAAE;EACnB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE;EACrC,MAAM,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EAChG,KAAK;EACL,IAAI,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAE1B,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,OAAO,EAAE,CAAC;EAC/C,IAAI,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;EACjE,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,OAAO;EAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC;EACjE,GAAG;EACH,CAAC;;ECtBM,MAAM,6BAA6B,SAAS,gBAAgB,CAAC;EACpE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC5C,IAAI,IAAI,CAAC,UAAU,GAAGA,OAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACvD,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,mCAAmC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EACjG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;EACzG,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;EAC7D,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAC5E,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;EAClE,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,qBAAqB,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;EACxG,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,iCAAiC,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;EAC3F,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EAC/D,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EACvI,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;EC9CM,MAAM,oCAAoC,SAAS,6BAA6B,CAAC;EACxF,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,UAAU,GAAGA,OAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACvD,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,mCAAmC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EACjG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;EACzG,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;EAClD,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAC3D,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECiBM,MAAM,eAAe,GAAG;EAC/B,EAAE,QAAQ,EAAE;EACZ,IAAI,OAAO,EAAE;EACb,MAAM,SAAS,EAAE,uBAAuB;EACxC,MAAM,SAAS,EAAE,uBAAuB;EACxC,MAAM,OAAO,EAAE,qBAAqB;EACpC,MAAM,OAAO,EAAE,oCAAoC;EACnD,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,OAAO,EAAE,oCAAoC;EACnD,MAAM,eAAe,EAAE,oCAAoC;EAC3D,MAAM,iBAAiB,EAAE,oCAAoC;EAC7D,MAAM,iBAAiB,EAAE,oCAAoC;EAC7D,MAAM,iBAAiB,EAAE,oCAAoC;EAC7D,MAAM,iBAAiB,EAAE,oCAAoC;EAC7D,MAAM,8BAA8B,EAAE,4CAA4C;EAClF,MAAM,WAAW,EAAE,gCAAgC;EACnD,MAAM,gBAAgB,EAAE,KAAK;EAC7B,MAAM,WAAW,EAAE,gCAAgC;EACnD,KAAK;EACL,IAAI,MAAM,EAAE;EACZ,MAAM,SAAS,EAAE,uBAAuB;EACxC,MAAM,OAAO,EAAE,qBAAqB;EACpC,MAAM,SAAS,EAAE,uBAAuB;EACxC,MAAM,OAAO,EAAE,6BAA6B;EAC5C,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,OAAO,EAAE,6BAA6B;EAC5C,MAAM,eAAe,EAAE,6BAA6B;EACpD,MAAM,iBAAiB,EAAE,6BAA6B;EACtD,MAAM,iBAAiB,EAAE,6BAA6B;EACtD,MAAM,iBAAiB,EAAE,6BAA6B;EACtD,MAAM,iBAAiB,EAAE,6BAA6B;EACtD,MAAM,8BAA8B,EAAE,mDAAmD;EACzF,MAAM,WAAW,EAAE,yBAAyB;EAC5C,MAAM,gBAAgB,EAAE,KAAK;EAC7B,MAAM,WAAW,EAAE,yBAAyB;EAC5C,KAAK;EACL,GAAG;EACH,EAAE,MAAM,EAAE;EACV,IAAI,OAAO,EAAE;EACb,MAAM,SAAS,EAAE,uBAAuB;EACxC,MAAM,SAAS,EAAE,uBAAuB;EACxC,MAAM,OAAO,EAAE,qBAAqB;EACpC,MAAM,OAAO,EAAE,kCAAkC;EACjD,MAAM,UAAU,EAAE,4BAA4B;EAC9C,MAAM,UAAU,EAAE,4BAA4B;EAC9C,MAAM,UAAU,EAAE,4BAA4B;EAC9C,MAAM,YAAY,EAAE,qCAAqC;EACzD,MAAM,YAAY,EAAE,qCAAqC;EACzD,MAAM,YAAY,EAAE,qCAAqC;EACzD,MAAM,YAAY,EAAE,qCAAqC;EACzD,MAAM,YAAY,EAAE,qCAAqC;EACzD,MAAM,YAAY,EAAE,qCAAqC;EACzD,MAAM,YAAY,EAAE,qCAAqC;EACzD,MAAM,YAAY,EAAE,qCAAqC;EACzD,MAAM,YAAY,EAAE,qCAAqC;EACzD,MAAM,OAAO,EAAE,kCAAkC;EACjD,MAAM,eAAe,EAAE,oCAAoC;EAC3D,MAAM,iBAAiB,EAAE,oCAAoC;EAC7D,MAAM,iBAAiB,EAAE,oCAAoC;EAC7D,MAAM,iBAAiB,EAAE,oCAAoC;EAC7D,MAAM,iBAAiB,EAAE,oCAAoC;EAC7D,MAAM,8BAA8B,EAAE,mDAAmD;EACzF,MAAM,WAAW,EAAE,gCAAgC;EACnD,MAAM,gBAAgB,EAAE,KAAK;EAC7B,MAAM,WAAW,EAAE,gCAAgC;EACnD,KAAK;EACL,IAAI,MAAM,EAAE;EACZ,MAAM,SAAS,EAAE,uBAAuB;EACxC,MAAM,OAAO,EAAE,qBAAqB;EACpC,MAAM,SAAS,EAAE,uBAAuB;EACxC,MAAM,OAAO,EAAE,2BAA2B;EAC1C,MAAM,UAAU,EAAE,4BAA4B;EAC9C,MAAM,UAAU,EAAE,4BAA4B;EAC9C,MAAM,UAAU,EAAE,4BAA4B;EAC9C,MAAM,YAAY,EAAE,8BAA8B;EAClD,MAAM,YAAY,EAAE,8BAA8B;EAClD,MAAM,YAAY,EAAE,8BAA8B;EAClD,MAAM,YAAY,EAAE,8BAA8B;EAClD,MAAM,YAAY,EAAE,8BAA8B;EAClD,MAAM,YAAY,EAAE,8BAA8B;EAClD,MAAM,YAAY,EAAE,8BAA8B;EAClD,MAAM,YAAY,EAAE,8BAA8B;EAClD,MAAM,YAAY,EAAE,8BAA8B;EAClD,MAAM,OAAO,EAAE,2BAA2B;EAC1C,MAAM,eAAe,EAAE,6BAA6B;EACpD,MAAM,iBAAiB,EAAE,6BAA6B;EACtD,MAAM,iBAAiB,EAAE,6BAA6B;EACtD,MAAM,iBAAiB,EAAE,6BAA6B;EACtD,MAAM,iBAAiB,EAAE,6BAA6B;EACtD,MAAM,8BAA8B,EAAE,4CAA4C;EAClF,MAAM,WAAW,EAAE,yBAAyB;EAC5C,MAAM,gBAAgB,EAAE,KAAK;EAC7B,MAAM,WAAW,EAAE,yBAAyB;EAC5C,KAAK;EACL,GAAG;EACH,CAAC,CAAC;AAEF,EAAO,SAAS,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE;EACvE,EAAE,IAAI,CAAC,IAAI,EAAE;EACb,IAAI,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;EACpC,GAAG;EACH,EAAE,IAAI,CAAC,OAAO,EAAE;EAChB,IAAI,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;EACvC,GAAG;EACH,EAAE,IAAI,CAAC,SAAS,EAAE;EAClB,IAAI,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;EACzC,GAAG;EACH,EAAE,IAAI,KAAK,CAAC,IAAI,EAAE;EAClB,IAAI,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;EACtB,GAAG;EACH,EAAE,MAAM,KAAK,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC;EACpD,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,EAAE;EAC7B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,SAAS,EAAE;EACxC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,iCAAiC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;EAClE,GAAG;EACH,EAAE,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC;EACrB,CAAC;;EC1KD,IAAI,WAAW,GAAG,IAAI,CAAC;EACvB,IAAI,UAAU,GAAG,IAAI,CAAC;EACtB,IAAI,WAAW,GAAG,IAAI,CAAC;EACvB,IAAI,cAAc,GAAG,IAAI,CAAC;EAC1B,IAAI,QAAQ,GAAG,IAAI,CAAC;EAEpB,MAAM,OAAO,GAAG,CAAC,aAAa,CAAC,CAAC;EAChC,MAAM,QAAQ,GAAG,EAAE,CAAC;EACpB,MAAM,WAAW,GAAG,EAAE,CAAC;AAqBvB,EAAO,MAAM,WAAW,SAAS,QAAQ,CAAC;EAC1C,EAAE,WAAW,WAAW,GAAG;EAC3B,IAAI,IAAI,WAAW,KAAK,IAAI,EAAE;EAC9B,MAAM,OAAO,WAAW,CAAC;EACzB,KAAK;EACL,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;EAC9B,IAAI,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;EACnD,IAAI,OAAO,WAAW,CAAC;EACvB,GAAG;EAEH,EAAE,OAAO,kBAAkB,GAAG;EAC9B,IAAI,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;EACzC,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;EACpD,KAAK,MAAM,IAAI,OAAO,eAAe,KAAK,WAAW,EAAE;EACvD,MAAM,UAAU,GAAG,IAAI,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;EAC7C,KAAK;EACL,IAAI,IAAI,CAAC,UAAU,EAAE,OAAO;EAC5B,IAAI,WAAW,GAAG,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,OAAO;EAC1D,IAAI,cAAc,GAAG;EACrB,MAAM,iBAAiB,EAAE,WAAW,CAAC,YAAY,CAAC,mBAAmB,CAAC;EACtE,MAAM,wBAAwB,EAAE,WAAW,CAAC,YAAY,CAAC,0BAA0B,CAAC;EACpF,MAAM,sBAAsB,EAAE,WAAW,CAAC,YAAY,CAAC,wBAAwB,CAAC;EAChF,MAAM,kBAAkB,EAAE,WAAW,CAAC,YAAY,CAAC,oBAAoB,CAAC;EACxE,KAAK,CAAC;EACN,IAAI,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;EAClC,GAAG;EAEH,EAAE,OAAO,cAAc,CAAC,OAAO,EAAE;EACjC,IAAI,IAAI,OAAO,qBAAqB,KAAK,WAAW,EAAE;EACtD,MAAM,OAAO,OAAO,YAAY,qBAAqB,CAAC;EACtD,KAAK;EACL,IAAI,OAAO,KAAK,CAAC;EACjB,GAAG;EAEH,EAAE,OAAO,WAAW,GAAG;EACvB,IAAI,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;EAClD,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC;EACzB,MAAM,WAAW,EAAE,IAAI,CAAC,cAAc,EAAE;EACxC,MAAM,yBAAyB,EAAE,IAAI,CAAC,4BAA4B,EAAE;EACpE,MAAM,cAAc,EAAE,IAAI,CAAC,iBAAiB,EAAE;EAC9C,MAAM,aAAa;EACnB,MAAM,SAAS,EAAE,aAAa;EAC9B,MAAM,YAAY,EAAE,IAAI,CAAC,eAAe,EAAE;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,OAAO,iBAAiB,GAAG;EAC7B,IAAI,OAAO,OAAO,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;EACrD,GAAG;EAEH,EAAE,OAAO,gBAAgB,GAAG;EAC5B,IAAI,OAAO,OAAO,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC;EACtD,GAAG;EAEH,EAAE,OAAO,eAAe,GAAG;EAC3B,IAAI,OAAO,cAAc,CAAC,kBAAkB;EAC5C,MAAM,WAAW,CAAC,YAAY,CAAC,cAAc,CAAC,kBAAkB,CAAC,sBAAsB,CAAC;EACxF,MAAM,CAAC,CAAC;EACR,GAAG;EAEH,EAAE,OAAO,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE;EAChE,IAAI,OAAO,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;EAClE,GAAG;EAEH,EAAE,WAAW,UAAU,GAAG;EAC1B,IAAI,OAAO,UAAU,CAAC;EACtB,GAAG;EAEH,EAAE,WAAW,WAAW,GAAG;EAC3B,IAAI,OAAO,WAAW,CAAC;EACvB,GAAG;EAEH,EAAE,WAAW,QAAQ,GAAG;EACxB,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EAEH,EAAE,WAAW,cAAc,GAAG;EAC9B,IAAI,OAAO,cAAc,CAAC;EAC1B,GAAG;EAEH,EAAE,WAAW,YAAY,GAAG;EAC5B,IAAI,OAAO,YAAY,CAAC;EACxB,GAAG;EAOH,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE;EAChC,IAAI,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;EAC5B,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;EACxB,IAAI,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC;EACtC,IAAI,IAAI,CAAC,UAAU,GAAGA,OAAK,CAAC,gBAAgB,EAAE,CAAC;EAC/C,IAAI,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;EACzB,IAAI,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC;EACxC,IAAI,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;EAChC,IAAI,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC;EACvC,IAAI,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;EACrC,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EAC3B,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EAC3B,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;EAC/B,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;EAM9B,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EAC3B,IAAI,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;EAClC,IAAI,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;EAEtC,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC;EAMpD,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAC1B,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;EAC5B,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;EACvB,IAAI,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;EAC3B,IAAI,IAAI,CAAC,2BAA2B,GAAG,EAAE,CAAC;EAC1C,IAAI,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;EAC7B,IAAI,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;EAC7B,IAAI,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;EAC7B,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,GAAG;EAEH,EAAE,UAAU,GAAG;EACf,IAAI,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;EACzC,MAAM,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;EAEtD,MAAM,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;EACvB,MAAM,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;EACxB,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK,MAAM,IAAI,OAAO,eAAe,KAAK,WAAW,EAAE;EACvD,MAAM,OAAO,IAAI,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;EACvC,KAAK;EACL,GAAG;EAEH,EAAE,WAAW,GAAG;EAChB,IAAI,MAAM,QAAQ,GAAG;EACrB,MAAM,KAAK,EAAE,KAAK;EAClB,MAAM,KAAK,EAAE,KAAK;EAClB,MAAM,SAAS,EAAE,KAAK;EACtB,KAAK,CAAC;EACN,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAC;EAC/G,GAAG;EAEH,EAAE,WAAW,CAAC,QAAQ,EAAE;EAExB,IAAI,MAAM,YAAY,GAAG,EAAE,CAAC;EAC5B,IAAI,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;EAC5B,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;EACpC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC/C,QAAQ,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EAClC,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE;EAChD,UAAU,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,SAAS;EACT,OAAO;EACP,KAAK,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;EAE3C,MAAM,IAAI,QAAQ,CAAC,WAAW,EAAE;EAChC,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACjD,UAAU,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EACpC,UAAU,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,IAAI,UAAU,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC;EAChG,UAAU,IAAI,SAAS,EAAE;EACzB,YAAY,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACtC,WAAW;EACX,SAAS;EACT,OAAO;EACP,KAAK;EACL,IAAI,OAAO,YAAY,CAAC;EACxB,GAAG;EAEH,EAAE,cAAc,GAAG;EACnB,IAAI,IAAI,CAAC,UAAU,GAAG;EACtB,MAAM,iBAAiB,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,mBAAmB,CAAC;EACvE,MAAM,wBAAwB,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,0BAA0B,CAAC;EACrF,MAAM,sBAAsB,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,wBAAwB,CAAC;EACjF,MAAM,kBAAkB,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,oBAAoB,CAAC;EACzE,MAAM,wBAAwB,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,0BAA0B,CAAC;EACrF,KAAK,CAAC;EACN,GAAG;EAMH,EAAE,gBAAgB,CAAC,IAAI,EAAE;EACzB,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;EACxB,MAAM,IAAI,CAAC,OAAO,GAAGA,OAAK,CAAC,oBAAoB,CAAC;EAChD,QAAQ,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;EACrD,QAAQ,SAAS,EAAE,IAAI,CAAC,SAAS;EACjC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACtB,MAAM,OAAO;EACb,KAAK;EAEL,IAAI,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC;EAC1C,IAAI,IAAI,IAAI,CAAC,mBAAmB,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE;EACvE,MAAM,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;EAC1D,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE;EACrE,MAAM,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;EACxD,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,QAAQ,CAAC,cAAc,EAAE;EACtF,MAAM,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC;EACpE,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,kBAAkB,EAAE;EAC9F,MAAM,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;EACtE,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,0BAA0B,KAAK,IAAI,EAAE;EAClD,MAAM,IAAI,CAAC,0BAA0B,GAAG,CAAC,QAAQ,CAAC,yBAAyB,CAAC;EAC5E,KAAK,MAAM,IAAI,IAAI,CAAC,0BAA0B,IAAI,QAAQ,CAAC,yBAAyB,EAAE;EACtF,MAAM,IAAI,CAAC,0BAA0B,GAAG,KAAK,CAAC;EAC9C,KAAK;EAEL,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;EAEvB,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;EAClD,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;EAC7B,QAAQ,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;EACtF,OAAO;EAEP,MAAM,MAAM,OAAO,GAAGA,OAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;EAC1E,MAAM,IAAI,OAAO,KAAK,OAAO,EAAE;EAC/B,QAAQ,IAAI,CAAC,MAAM,GAAGA,OAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;EACnD,OAAO,MAAM,IAAI,OAAO,KAAK,eAAe,IAAI,OAAO,KAAK,iBAAiB,EAAE;EAC/E,QAAQ,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;EACrC,OAAO,MAAM;EACb,QAAQ,MAAM,IAAI,KAAK,CAAC,4CAA4C,GAAG,OAAO,CAAC,CAAC;EAChF,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;EACpC,QAAQ,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;EAC3E,OAAO;EAEP,MAAM,IAAI,IAAI,CAAC,SAAS,KAAK,WAAW,EAAE;EAC1C,QAAQ,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC;EACpC,QAAQ,OAAO,CAAC,IAAI,CAAC,iEAAiE,CAAC,CAAC;EACxF,OAAO;EAEP,MAAM,IAAI,CAAC,OAAO,GAAGA,OAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC9C,MAAM,OAAO;EACb,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,QAAQ,CAAC,cAAc,EAAE;EACnE,MAAM,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;EAChC,KAAK;EAEL,IAAI,IAAI,CAAC,OAAO,GAAGA,OAAK,CAAC,oBAAoB,CAAC;EAC9C,MAAM,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;EACnD,MAAM,SAAS,EAAE,IAAI,CAAC,SAAS;EAC/B,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAEpB,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;EAC5B,GAAG;EAEH,EAAE,gBAAgB,GAAG;EACrB,IAAI,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;EACrC,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;EAClC,MAAM,IAAI,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;EACjD,MAAM,IAAI,WAAW,KAAK,CAAC,CAAC,EAAE;EAC9B,QAAQ,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC;EACtC,QAAQ,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC9B,QAAQ,WAAW,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;EAC5D,OAAO;EACP,MAAM,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;EACjD,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE;EACzC,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EACtC,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE;EACzC,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EACtC,KAAK;EACL,GAAG;EAGH,EAAE,mBAAmB,GAAG;EACxB,IAAI,MAAM,eAAe,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,iBAAiB,EAAE;EAChF,MAAM,0BAA0B,EAAE,IAAI,CAAC,0BAA0B;EACjE,KAAK,CAAC,CAAC;EAGP,IAAI,MAAM,gBAAgB,GAAG,eAAe,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;EAE1E,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;EAC1B,MAAM,IAAI,CAAC,UAAU,GAAG,eAAe,CAAC,mBAAmB,EAAE,CAAC;EAC9D,KAAK;EAEL,IAAI,IAAI,gBAAgB,GAAG,CAAC,CAAC;EAC7B,IAAI,MAAM,WAAW,GAAG,eAAe,CAAC,cAAc,EAAE,CAAC;EACzD,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACjD,MAAM,QAAQ,WAAW,CAAC,CAAC,CAAC;EAC5B,QAAQ,KAAK,OAAO,CAAC;EACrB,QAAQ,KAAK,QAAQ,CAAC;EACtB,QAAQ,KAAK,SAAS;EACtB,UAAU,gBAAgB,EAAE,CAAC;EAC7B,UAAU,MAAM;EAChB,QAAQ,KAAK,UAAU;EACvB,UAAU,gBAAgB,IAAI,CAAC,CAAC;EAChC,UAAU,MAAM;EAChB,QAAQ,KAAK,UAAU;EACvB,UAAU,gBAAgB,IAAI,CAAC,CAAC;EAChC,UAAU,MAAM;EAChB,QAAQ,KAAK,UAAU;EACvB,UAAU,gBAAgB,IAAI,CAAC,CAAC;EAChC,UAAU,MAAM;EAChB,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,QAAQ,IAAI,gBAAgB,GAAG,QAAQ,CAAC,YAAY,EAAE;EAC9D,MAAM,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;EAC5C,KAAK;EAEL,IAAI,OAAO,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;EACpD,GAAG;EAEH,EAAE,cAAc,CAAC,IAAI,EAAE;EACvB,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;EAClC,IAAI,MAAM,kBAAkB,GAAG,IAAI,CAAC,aAAa,KAAK,IAAI,CAAC;EAE3D,IAAI,IAAI,kBAAkB,EAAE;EAC5B,MAAM,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAC9B,KAAK;EACL,IAAI,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAC5B,IAAI,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;EAGhC,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE;EACjD,MAAM,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;EACzD,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE;EACxD,MAAM,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;EACvD,KAAK;EAEL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAI,IAAI,cAAc,GAAG,CAAC,CAAC;EAC3B,IAAI,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;EACtD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;EAChC,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;EAC7C,MAAM,IAAI,IAAI,CAAC;EACf,MAAM,IAAI,kBAAkB,EAAE;EAC9B,QAAQ,IAAI,GAAGA,OAAK,CAAC,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;EACjE,QAAQ,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EACtC,OAAO,MAAM;EACb,QAAQ,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;EACzC,OAAO;EACP,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,GAAG,SAAS,GAAG,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;EAClJ,MAAM,IAAI,WAAW,KAAK,IAAI,EAAE;EAChC,QAAQ,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC1C,OAAO;EACP,MAAM,MAAM,cAAc,GAAG,IAAI,WAAW,CAAC,KAAK,EAAE;EACpD,QAAQ,IAAI;EACZ,QAAQ,IAAI;EACZ,QAAQ,MAAM,EAAE,IAAI,CAAC,MAAM;EAC3B,QAAQ,MAAM,EAAE,MAAM;EACtB,QAAQ,OAAO,EAAE,EAAE;EACnB,QAAQ,YAAY,EAAE,IAAI,CAAC,YAAY;EACvC,QAAQ,MAAM,EAAE,IAAI;EACpB,QAAQ,cAAc,EAAE,IAAI,CAAC,cAAc;EAC3C,QAAQ,gBAAgB,EAAE,MAAM;EAChC,UAAU,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;EAC9C,SAAS;EACT,QAAQ,cAAc,EAAE,MAAM;EAC9B,UAAU,OAAO,cAAc,EAAE,CAAC;EAClC,SAAS;EACT,QAAQ,qBAAqB,EAAE,MAAM;EACrC,UAAU,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;EACvC,SAAS;EACT,QAAQ,sBAAsB,EAAE,MAAM;EACtC,UAAU,OAAO,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;EACvF,SAAS;EACT,OAAO,CAAC,CAAC;EACT,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;EAChD,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;EAC1D,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,GAAG,cAAc,CAAC,QAAQ,CAAC;EAC9D,KAAK;EACL,GAAG;EAEH,EAAE,cAAc,CAAC,IAAI,EAAE;EACvB,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,0BAA0B,GAAG,EAAE,CAAC;EACzC,IAAI,IAAI,kBAAkB,GAAG,IAAI,CAAC,aAAa,KAAK,IAAI,CAAC;EACzD,IAAI,IAAI,kBAAkB,EAAE;EAC5B,MAAM,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAC9B,KAAK;EACL,IAAI,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;EAChC,IAAI,IAAI,cAAc,GAAG,CAAC,CAAC;EAC3B,IAAI,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACvC,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;EACzC,MAAM,IAAI,IAAI,CAAC;EACf,MAAM,IAAI,kBAAkB,EAAE;EAC9B,QAAQ,IAAI,GAAGA,OAAK,CAAC,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;EACjE,QAAQ,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;EACxC,OAAO,MAAM;EACb,QAAQ,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;EACxC,OAAO;EACP,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,qBAAqB,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;EACxG,MAAM,IAAI,WAAW,KAAK,IAAI,EAAE;EAChC,QAAQ,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC1C,OAAO;EACP,MAAM,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,KAAK,EAAE;EACjD,QAAQ,IAAI;EACZ,QAAQ,IAAI;EACZ,QAAQ,MAAM,EAAE,IAAI,CAAC,MAAM;EAC3B,QAAQ,MAAM,EAAE,WAAW;EAC3B,QAAQ,OAAO,EAAE,IAAI,CAAC,OAAO;EAC7B,QAAQ,YAAY,EAAE,IAAI,CAAC,YAAY;EACvC,QAAQ,MAAM,EAAE,IAAI;EACpB,QAAQ,cAAc,EAAE,IAAI,CAAC,cAAc;EAC3C,QAAQ,gBAAgB,EAAE,MAAM;EAChC,UAAU,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;EAC9C,SAAS;EACT,QAAQ,cAAc,EAAE,MAAM;EAC9B,UAAU,OAAO,cAAc,EAAE,CAAC;EAClC,SAAS;EACT,QAAQ,sBAAsB,EAAE,MAAM;EACtC,UAAU,OAAO,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;EAC3D,SAAS;EACT,OAAO,CAAC,CAAC;EACT,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC;EAC1D,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7C,MAAM,IAAI,WAAW,CAAC,kBAAkB,EAAE;EAC1C,QAAQ,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;EAC1D,OAAO;EACP,KAAK;EACL,GAAG;EAEH,EAAE,KAAK,GAAG;EACV,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;EACrC,IAAI,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;EACnC,IAAI,IAAI,IAAI,CAAC,iBAAiB,EAAE,OAAO;EACvC,IAAI,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;EACnC,IAAI,IAAI,IAAI,CAAC,iBAAiB,EAAE,OAAO;EACvC,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;EAC5B,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;EAC3B,IAAI,MAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;EAC7D,IAAI,IAAI,aAAa,EAAE;EACvB,MAAM,OAAO,aAAa,CAAC;EAC3B,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;EAClD,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;EAC/B,IAAI,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE;EACtD,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;EAChE,MAAM,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EACxC,MAAM,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EACzC,KAAK,MAAM;EACX,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;EAChE,MAAM,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EACxC,MAAM,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EACzC,KAAK;EACL,IAAI,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC/D,IAAI,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;EACjC,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EACxB,KAAK;EAEL,IAAI,MAAM,oBAAoB,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;EACjE,IAAI,MAAM,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC;EACzD,IAAI,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;EACtD,IAAI,EAAE,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;EACjC,IAAI,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;EAEjC,IAAI,MAAM,sBAAsB,GAAG,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;EACrE,IAAI,MAAM,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC;EAC3D,IAAI,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,sBAAsB,CAAC,CAAC;EACxD,IAAI,EAAE,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;EACjC,IAAI,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;EAEjC,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE;EACpB,MAAM,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;EACzC,MAAM,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;EAC1C,KAAK;EAEL,IAAI,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE;EAC/D,MAAM,MAAM,IAAI,KAAK,CAAC,iCAAiC,GAAG,EAAE,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC;EAC3F,KAAK;EACL,IAAI,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE;EAC/D,MAAM,MAAM,IAAI,KAAK,CAAC,mCAAmC,GAAG,EAAE,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC;EAC7F,KAAK;EAEL,IAAI,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC,aAAa,EAAE,CAAC;EACtD,IAAI,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;EAC5B,IAAI,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,iBAAiB,EAAE,CAAC;EAC9C,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EACxC,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EAEzC,IAAI,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;EAC7C,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;EAClB,MAAM,CAAC,EAAE,CAAC;EACV,KAAK,CAAC,CAAC;EACP,IAAI,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC;EACvC,MAAM,CAAC,EAAE,CAAC;EACV,MAAM,CAAC,EAAE,CAAC;EACV,MAAM,CAAC,EAAE,CAAC;EACV,MAAM,CAAC,EAAE,CAAC;EACV,KAAK,CAAC,CAAC;EAEP,IAAI,MAAM,cAAc,GAAG,QAAQ,CAAC,UAAU,CAAC;EAE/C,IAAI,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;EAC7B,IAAI,IAAI,CAAC,MAAM,EAAE;EACjB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,YAAY,EAAE,CAAC;EAC/C,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;EAC7C,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,YAAY,EAAE,QAAQ,CAAC,UAAU,GAAG,SAAS,CAAC,UAAU,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC;EACjG,KAAK,MAAM;EACX,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;EAC7C,KAAK;EAEL,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;EACnD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,YAAY,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC;EAEjE,IAAI,MAAM,OAAO,GAAG,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;EAC/D,IAAI,EAAE,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;EACxC,IAAI,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;EAC9D,IAAI,MAAM,YAAY,GAAG,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,uBAAuB,CAAC,YAAY,CAAC,CAAC;EAC7C,IAAI,EAAE,CAAC,mBAAmB,CAAC,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,cAAc,CAAC,CAAC;EAChF,IAAI,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAEzD,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;EACd,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAChC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE;EAClC,MAAM,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/D,KAAK;EAEL,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;EACzB,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;EACjC,MAAM;EACN,QAAQ,IAAI,CAAC,UAAU,KAAK,IAAI;EAChC,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;EAClC,QAAQ;EACR,QAAQ,IAAI,CAAC,uBAAuB,EAAE,CAAC;EACvC,OAAO;EACP,KAAK;EACL,GAAG;EAEH,EAAE,eAAe,GAAG;EACpB,IAAI,MAAM,eAAe,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,iBAAiB,EAAE;EAChF,MAAM,0BAA0B,EAAE,IAAI,CAAC,0BAA0B;EACjE,KAAK,CAAC,CAAC;EACP,IAAI,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;EACzE,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;EAC7C,MAAM,IAAI,CAAC,UAAU,GAAG,eAAe,CAAC,mBAAmB,EAAE,CAAC;EAC9D,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;EACvD,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACvD,QAAQ,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC7C,QAAQ,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE;EACnC,UAAU,SAAS,CAAC,UAAU,GAAG,eAAe,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;EAC3E,SAAS;EACT,OAAO;EACP,KAAK;EACL,GAAG;EAEH,EAAE,GAAG,GAAG;EACR,IAAI,MAAM,EAAE,eAAe,EAAE,0BAA0B,EAAE,GAAG,IAAI,CAAC;EACjE,IAAI,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;EACjC,IAAI,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;EAE5B,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAChC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;EAE7C,IAAI,IAAI,IAAI,CAAC,aAAa,EAAE;EAC5B,MAAM,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;EACvE,MAAM,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;EAC9C,KAAK;EAEL,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;EAEjG,IAAI,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;EAClC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,0BAA0B,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAChE,MAAM,MAAM,QAAQ,GAAG,0BAA0B,CAAC,CAAC,CAAC,CAAC;EACrD,MAAM,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;EAC1D,MAAM,IAAI,IAAI,CAAC,gBAAgB,EAAE,OAAO;EACxC,KAAK;EACL,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,eAAe,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;EACnD,MAAM,IAAI,IAAI,CAAC,gBAAgB,EAAE,OAAO;EACxC,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE;EACtB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACpD,QAAQ,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;EACvC,QAAQ,IAAI,MAAM,CAAC,WAAW,EAAE;EAChC,UAAU,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;EACnC,SAAS;EACT,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE;EACzB,QAAQ,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;EACnD,QAAQ,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,QAAQ,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,SAAS,EAAE;EACnD,UAAU,IAAI,CAAC,mBAAmB,EAAE,CAAC;EACrC,SAAS;EACT,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;EAC/C,QAAQ,OAAO,IAAI,IAAI,CAAC,kBAAkB,CAAC;EAC3C,UAAU,OAAO,EAAE,IAAI,CAAC,aAAa;EACrC,UAAU,IAAI,EAAE,OAAO;EACvB,UAAU,UAAU,EAAE,IAAI,CAAC,SAAS;EACpC,UAAU,MAAM,EAAE,IAAI,CAAC,MAAM;EAC7B,UAAU,OAAO,EAAE,IAAI,CAAC,OAAO;EAC/B,SAAS,CAAC,CAAC;EACX,OAAO;EACP,MAAM,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;EACjD,MAAM,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;EAC/C,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;EAC7C,MAAM,OAAO;EACb,KAAK;EAEL,IAAI,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EACzD,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;EACjC,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;EAClC,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE;EAC1B,QAAQ,IAAI,CAAC,uBAAuB,EAAE,CAAC;EACvC,OAAO;EACP,MAAM,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;EAC/E,KAAK;EAEL,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;EAC3C,GAAG;EAMH,EAAE,gBAAgB,GAAG;EACrB,IAAI,OAAO,IAAI,CAAC,aAAa,CAAC;EAC9B,GAAG;EAKH,EAAE,mBAAmB,GAAG;EACxB,IAAI,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;EAC5B,IAAI,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;EACjC,IAAI,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;EACtE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,CAAC,CAAC;EAC1F,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;EAC3C,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EAMvE,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE;EACrC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE;EAEzB,QAAQ,QAAQ,IAAI,CAAC,UAAU;EAC/B,UAAU,KAAK,QAAQ,CAAC;EACxB,UAAU,KAAK,OAAO,CAAC;EACvB,UAAU,KAAK,SAAS;EACxB,YAAY,IAAI,IAAI,CAAC,mBAAmB,EAAE;EAC1C,cAAc,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EAC3G,aAAa,MAAM;EACnB,cAAc,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EAC3G,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACzG,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACzG,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACzG,YAAY,MAAM;EAClB,UAAU;EACV,YAAY,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;EACjC,cAAc,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;EACvD,aAAa;EACb,SAAS;EACT,OAAO,MAAM;EACb,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACrG,OAAO;EACP,KAAK,MAAM;EACX,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;EAC3G,KAAK;EACL,IAAI,EAAE,CAAC,oBAAoB,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,iBAAiB,EAAE,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;EAC7F,GAAG;EAKH,EAAE,uBAAuB,GAAG;EAC5B,IAAI,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;EAC5B,IAAI,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;EACjC,IAAI,IAAI,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC;EACjD,IAAI,IAAI,CAAC,uBAAuB,GAAG,EAAE,CAAC;EACtC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;EACnD,MAAM,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACjD,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,iBAAiB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;EAC7D,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC,CAAC;EAChG,MAAM,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;EAC7C,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EAC3E,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EAC3E,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACzE,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACzE,MAAM,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE;EACvC,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACrG,OAAO,MAAM;EACb,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;EAC7G,OAAO;EACP,MAAM,EAAE,CAAC,oBAAoB,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,iBAAiB,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;EACvG,KAAK;EACL,GAAG;EAOH,EAAE,eAAe,CAAC,IAAI,EAAE;EACxB,IAAI,IAAI,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EAChD,MAAM,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;EACrC,KAAK;EACL,IAAI,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;EAClE,GAAG;EAMH,EAAE,kBAAkB,CAAC,IAAI,EAAE;EAC3B,IAAI,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;EACnC,GAAG;EAEH,EAAE,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE;EAC5B,IAAI,IAAI,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EAClD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;EAC9C,MAAM,IAAI,KAAK,KAAK,KAAK,EAAE;EAC3B,QAAQ,OAAO;EACf,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;EACtC,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;EAC9C,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;EACvC,GAAG;EAEH,EAAE,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE;EAC5B,IAAI,IAAI,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EAClD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;EAC9C,MAAM,IAAI,KAAK,KAAK,KAAK,EAAE;EAC3B,QAAQ,OAAO;EACf,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;EACtC,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;EAC9C,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;EACvC,GAAG;EAEH,EAAE,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE;EACrC,IAAI,IAAI,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EAClD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;EAC9C,MAAM;EACN,QAAQ,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC;EAC3B,QAAQ,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC;EAC3B,QAAQ;EACR,QAAQ,OAAO;EACf,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;EACjD,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;EAC9C,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;EAChD,GAAG;EAEH,EAAE,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE;EAC7B,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EACnD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC/C,MAAM;EACN,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ;EACR,QAAQ,OAAO;EACf,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;EACvC,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;EAC9C,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE;EAC7B,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EACnD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC/C,MAAM;EACN,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ;EACR,QAAQ,OAAO;EACf,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;EACvC,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;EAC9C,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE;EAC7B,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EACnD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC/C,MAAM;EACN,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ;EACR,QAAQ,OAAO;EACf,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;EACvC,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;EAC9C,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE;EAC7B,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EACnD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC/C,MAAM;EACN,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ;EACR,QAAQ,OAAO;EACf,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;EACvC,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;EAC9C,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE;EAC7B,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EACnD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC/C,MAAM;EACN,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ;EACR,QAAQ,OAAO;EACf,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;EACvC,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;EAC9C,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE;EAC7B,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EACnD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC/C,MAAM;EACN,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ;EACR,QAAQ,OAAO;EACf,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;EACvC,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;EAC9C,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE;EAC7B,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EACnD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC/C,MAAM;EACN,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ;EACR,QAAQ,OAAO;EACf,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;EACvC,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;EAC9C,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;EACxC,GAAG;EAOH,EAAE,kBAAkB,CAAC,IAAI,EAAE;EAC3B,IAAI,IAAI,IAAI,CAAC,2BAA2B,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EAC/D,MAAM,OAAO,IAAI,CAAC,2BAA2B,CAAC,IAAI,CAAC,CAAC;EACpD,KAAK;EACL,IAAI,OAAO,IAAI,CAAC,2BAA2B,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;EACxG,GAAG;EASH,EAAE,yBAAyB,CAAC,IAAI,EAAE;EAClC,IAAI,OAAO;EACX,MAAM,MAAM,EAAE,IAAI,CAAC,gBAAgB,EAAE;EACrC,MAAM,QAAQ,EAAE,IAAI,CAAC,iBAAiB,EAAE;EACxC,MAAM,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE;EACvC,MAAM,SAAS,EAAE,IAAI,CAAC,mBAAmB,EAAE;EAC3C,MAAM,mBAAmB,EAAE,IAAI,CAAC,4BAA4B,EAAE;EAC9D,MAAM,mBAAmB,EAAE,IAAI,CAAC,4BAA4B,EAAE;EAC9D,MAAM,yBAAyB,EAAE,IAAI,CAAC,gCAAgC,EAAE;EACxE,MAAM,eAAe,EAAE,IAAI,CAAC,kBAAkB,EAAE;EAChD,MAAM,cAAc,EAAE,IAAI,CAAC,uBAAuB,EAAE;EACpD,MAAM,cAAc,EAAE,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC;EACxD,MAAM,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE;EACpC,MAAM,WAAW,EAAE,IAAI,CAAC,mBAAmB,EAAE;EAC7C,MAAM,wBAAwB,EAAE,IAAI,CAAC,yBAAyB,EAAE;EAChE,MAAM,sBAAsB,EAAE,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,6BAA6B,EAAE,IAAI,CAAC,6BAA6B,EAAE;EACzE,MAAM,mCAAmC,EAAE,IAAI,CAAC,kCAAkC,EAAE;EACpF,KAAK,CAAC;EACN,GAAG;EASH,EAAE,yBAAyB,CAAC,IAAI,EAAE;EAClC,IAAI,OAAO;EACX,MAAM,wBAAwB,EAAE,IAAI,CAAC,yBAAyB,EAAE;EAChE,MAAM,sBAAsB,EAAE,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,6BAA6B,EAAE,IAAI,CAAC,6BAA6B,EAAE;EACzE,MAAM,mCAAmC,EAAE,IAAI,CAAC,kCAAkC,EAAE;EACpF,KAAK,CAAC;EACN,GAAG;EAQH,EAAE,gBAAgB,GAAG;EACrB,IAAI;EACJ,MAAM,IAAI,CAAC,UAAU,KAAK,IAAI;EAC9B,MAAM,4CAA4C;EAClD,MAAM,EAAE;EACR,MAAM;EACN,GAAG;EAMH,EAAE,iBAAiB,GAAG;EACtB,IAAI;EACJ,MAAM,IAAI,CAAC,iBAAiB;EAC5B,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC;EAC/C,MAAM,UAAU;EAChB,MAAM;EACN,GAAG;EAEH,EAAE,iBAAiB,GAAG;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,IAAI,CAAC;EACnC,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAChI,GAAG;EAMH,EAAE,mBAAmB,GAAG;EACxB,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;EACxC,IAAI,IAAI,IAAI,CAAC,aAAa,EAAE;EAC5B,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,0BAA0B;EAClC,QAAQ,wBAAwB;EAChC,OAAO,CAAC;EACR,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,CAAC,yBAAyB,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACrF,QAAQ,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC9D,OAAO,CAAC;EACR,KAAK;EACL,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;EACvC,GAAG;EAMH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;EACvC,IAAI,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;EACtD,MAAM,OAAO,2BAA2B,CAAC;EACzC,KAAK,MAAM;EACX,MAAM,OAAO,uBAAuB,CAAC;EACrC,KAAK;EACL,GAAG;EAMH,EAAE,4BAA4B,GAAG;EACjC,IAAI;EACJ,MAAM,IAAI,CAAC,UAAU,KAAK,IAAI;EAC9B,MAAM,EAAE;EACR,MAAM,8BAA8B;EACpC,MAAM;EACN,GAAG;EAMH,EAAE,4BAA4B,GAAG;EACjC,IAAI;EACJ,MAAM,IAAI,CAAC,UAAU,KAAK,IAAI;EAC9B,MAAM,EAAE;EACR,MAAM,8BAA8B;EACpC,MAAM;EACN,GAAG;EAMH,EAAE,gCAAgC,GAAG;EACrC,IAAI,OAAO,IAAI,CAAC,0BAA0B;EAC1C,MAAM,CAAC;;;;;CAKN,CAAC;EACF,MAAM,EAAE,CAAC;EACT,GAAG;EAOH,EAAE,uBAAuB,CAAC,IAAI,EAAE;EAChC,IAAI,MAAM,OAAO,GAAG,EAAE,CAAC;EACvB,IAAI,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;EACnC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACnD,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/D,KAAK;EACL,IAAI,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EAC5B,GAAG;EAEH,EAAE,kBAAkB,GAAG;EACvB,IAAI,OAAO,IAAI,CAAC,cAAc,IAAI,EAAE,CAAC;EACrC,GAAG;EAEH,EAAE,uBAAuB,GAAG;EAC5B,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;EAC/B,IAAI,IAAI,SAAS,EAAE;EACnB,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;EAChB,MAAM,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE;EACpC,QAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC/E,OAAO;EACP,KAAK;EACL,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3B,GAAG;EAMH,EAAE,eAAe,GAAG;EACpB,IAAI,IAAI,uBAAuB,CAAC;EAChC,IAAI,QAAQ,IAAI,CAAC,UAAU;EAC3B,MAAM,KAAK,UAAU;EACrB,QAAQ,uBAAuB,GAAG,mBAAmB,CAAC;EACtD,QAAQ,MAAM;EACd,MAAM,KAAK,UAAU;EACrB,QAAQ,uBAAuB,GAAG,mBAAmB,CAAC;EACtD,QAAQ,MAAM;EACd,MAAM,KAAK,UAAU;EACrB,QAAQ,uBAAuB,GAAG,mBAAmB,CAAC;EACtD,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,OAAO,CAAC;EACnB,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,SAAS;EACpB,QAAQ,uBAAuB,GAAG,oBAAoB,CAAC;EACvD,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE;EAC5B,UAAU,uBAAuB,GAAG,oBAAoB,CAAC;EACzD,SAAS,MAAM;EACf,UAAU,MAAM,IAAI,KAAK,CAAC,CAAC,0BAA0B,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;EAC7E,SAAS;EACT,KAAK;EAEL,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;EACvC,IAAI,IAAI,UAAU,KAAK,IAAI,EAAE;EAC7B,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,uBAAuB;EAC/B,OAAO,CAAC;EACR,MAAM,QAAQ,IAAI,CAAC,UAAU;EAC7B,QAAQ,KAAK,QAAQ,CAAC;EACtB,QAAQ,KAAK,OAAO,CAAC;EACrB,QAAQ,KAAK,SAAS;EACtB,UAAU,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACtD,YAAY,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;EAC5C,YAAY,MAAM,CAAC,IAAI;EACvB,cAAc,SAAS,CAAC,UAAU,KAAK,SAAS;EAChD,cAAc,CAAC,oBAAoB,GAAG,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC;EAC3D,cAAc,CAAC,sBAAsB,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC;EAC/D,aAAa,CAAC;EACd,WAAW;EACX,UAAU,MAAM;EAChB,QAAQ,KAAK,UAAU;EACvB,UAAU,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACtD,YAAY,MAAM,CAAC,IAAI;EACvB,cAAc,CAAC,qBAAqB,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;EAC5D,aAAa,CAAC;EACd,WAAW;EACX,UAAU,MAAM;EAChB,QAAQ,KAAK,UAAU;EACvB,UAAU,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACtD,YAAY,MAAM,CAAC,IAAI;EACvB,cAAc,CAAC,qBAAqB,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;EAC5D,aAAa,CAAC;EACd,WAAW;EACX,UAAU,MAAM;EAChB,QAAQ,KAAK,UAAU;EACvB,UAAU,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACtD,YAAY,MAAM,CAAC,IAAI;EACvB,cAAc,CAAC,qBAAqB,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;EAC5D,aAAa,CAAC;EACd,WAAW;EACX,UAAU,MAAM;EAChB,OAAO;EACP,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,uBAAuB;EAC/B,OAAO,CAAC;EACR,KAAK;EAEL,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC;EAC/D,GAAG;EAEH,EAAE,sBAAsB,GAAG;EAC3B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,8BAA8B;EACpC,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,yBAAyB,GAAG;EAC9B,IAAI,QAAQ,IAAI,CAAC,UAAU;EAC3B,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,OAAO;EAClB,QAAQ,OAAO,IAAI,CAAC,+BAA+B,EAAE;EACrD,UAAU,IAAI,CAAC,kCAAkC,EAAE,CAAC;EACpD,MAAM;EACN,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,yCAAyC,EAAE,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;EAClG,KAAK;EACL,GAAG;EAKH,EAAE,+BAA+B,GAAG;EACpC,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,CAAC,mBAAmB,EAAE,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,GAAG,UAAU,CAAC,cAAc,CAAC;EACjG,KAAK,CAAC,CAAC;EACP,GAAG;EAKH,EAAE,kCAAkC,GAAG;EACvC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC;EACpC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC3C,MAAM,IAAI,SAAS,CAAC,UAAU,KAAK,SAAS,EAAE;EAC9C,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,GAAG,UAAU,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;EACjJ,SAAS,CAAC;EACV,OAAO,MAAM;EACb,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,GAAG,UAAU,CAAC,iBAAiB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EAC1I,SAAS,CAAC;EACV,OAAO;EACP,KAAK;EACL,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;EACvC,GAAG;EAEH,EAAE,kCAAkC,GAAG;EACvC,IAAI,MAAM,MAAM,GAAG;EACnB,MAAM,cAAc;EACpB,KAAK,CAAC;EAEN,IAAI,QAAQ,IAAI,CAAC,UAAU;EAC3B,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,OAAO;EAClB,QAAQ,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;EAC9C,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,UAAU,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;EACtC,UAAU,IAAI,CAAC,wCAAwC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;EACzE,UAAU,IAAI,CAAC,2CAA2C,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;EAC5E,UAAU,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE;EACvC,YAAY,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;EACxC,WAAW;EACX,SAAS;EACT,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,2CAA2C,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;EACnG,KAAK;EAEL,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;EACvC,GAAG;EAEH,EAAE,wCAAwC,CAAC,MAAM,EAAE,OAAO,EAAE;EAC5D,IAAI,MAAM,CAAC,IAAI;EACf,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,CAAC,iBAAiB,EAAE,OAAO,CAAC,eAAe,CAAC;EAClD,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,2CAA2C,CAAC,MAAM,EAAE,OAAO,EAAE;EAC/D,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,CAAC;EACxC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC3C,MAAM,IAAI,SAAS,CAAC,UAAU,KAAK,SAAS,EAAE;EAC9C,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,yBAAyB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EAClG,SAAS,CAAC;EACV,OAAO,MAAM;EACb,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,mBAAmB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EAC3F,SAAS,CAAC;EACV,OAAO;EACP,KAAK;EACL,GAAG;EAEH,EAAE,gCAAgC,GAAG;EACrC,IAAI,OAAO;EACX,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,oCAAoC;EAC1C,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,CAAC;EACxC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACrD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC3C,MAAM,IAAI,SAAS,CAAC,UAAU,KAAK,SAAS,EAAE;EAC9C,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,6BAA6B,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;EACjF,SAAS,CAAC;EACV,OAAO,MAAM;EACb,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;EAC1E,SAAS,CAAC;EACV,OAAO;EACP,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,gCAAgC,GAAG;EACrC,IAAI,OAAO;EACX,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,uCAAuC;EAC7C,MAAM,uCAAuC;EAC7C,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,CAAC;EACxC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACrD,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACpF,QAAQ,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACpF,OAAO,CAAC;EACR,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,gCAAgC,GAAG;EACrC,IAAI,OAAO;EACX,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,uCAAuC;EAC7C,MAAM,uCAAuC;EAC7C,MAAM,uCAAuC;EAC7C,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,CAAC;EACxC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACrD,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACpF,QAAQ,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACpF,QAAQ,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACpF,OAAO,CAAC;EACR,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,gCAAgC,GAAG;EACrC,IAAI,OAAO;EACX,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,iCAAiC;EACvC,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,CAAC;EACxC,IAAI,QAAQ,IAAI,CAAC,UAAU;EAC3B,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,OAAO,CAAC;EACnB,MAAM,KAAK,SAAS;EACpB,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACzD,UAAU,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC/C,UAAU,IAAI,SAAS,CAAC,UAAU,KAAK,SAAS,EAAE;EAClD,YAAY,MAAM,CAAC,IAAI;EACvB,cAAc,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,0BAA0B,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EAC3F,aAAa,CAAC;EACd,WAAW,MAAM;EACjB,YAAY,MAAM,CAAC,IAAI;EACvB,cAAc,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,oBAAoB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EACpF,aAAa,CAAC;EACd,WAAW;EACX,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,UAAU;EACrB,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACzD,UAAU,MAAM,CAAC,IAAI;EACrB,YAAY,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACxF,YAAY,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACxF,WAAW,CAAC;EACZ,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,UAAU;EACrB,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACzD,UAAU,MAAM,CAAC,IAAI;EACrB,YAAY,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACxF,YAAY,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACxF,YAAY,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACxF,WAAW,CAAC;EACZ,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,UAAU;EACrB,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACzD,UAAU,MAAM,CAAC,IAAI;EACrB,YAAY,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACxF,YAAY,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACxF,YAAY,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACxF,YAAY,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACxF,WAAW,CAAC;EACZ,SAAS;EACT,QAAQ,MAAM;EACd,KAAK;EAEL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAMH,EAAE,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE;EAC7B,IAAI,OAAO,GAAG,CAAC,OAAO,CAAC,+CAA+C,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK;EAC7F,MAAM,IAAI,GAAG,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE;EACxC,QAAQ,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC7B,OAAO;EACP,MAAM,MAAM,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC,CAAC;EAC7C,KAAK,CAAC,CAAC;EACP,GAAG;EAUH,EAAE,iBAAiB,CAAC,IAAI,EAAE;EAC1B,IAAI,IAAI,IAAI,CAAC,sBAAsB,KAAK,IAAI,EAAE;EAC9C,MAAM,OAAO,IAAI,CAAC,sBAAsB,CAAC;EACzC,KAAK;EACL,IAAI,OAAO,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC;EACtI,GAAG;EAOH,EAAE,eAAe,CAAC,IAAI,EAAE;EACxB,IAAI,IAAI,IAAI,CAAC,oBAAoB,KAAK,IAAI,EAAE;EAC5C,MAAM,OAAO,IAAI,CAAC,oBAAoB,CAAC;EACvC,KAAK;EACL,IAAI,OAAO,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC;EAClI,GAAG;EAKH,EAAE,QAAQ,GAAG;EACb,IAAI,MAAM,kBAAkB,GAAGA,OAAK,CAAC,aAAa,CAAC;EACnD,MAAM,CAAC,kBAAkB,CAAC;EAC1B,KAAK,CAAC,CAAC;EACP,IAAI,OAAO,cAAc,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,kBAAkB,CAAC,CAAC;EACjF,GAAG;EAEH,EAAE,OAAO,CAAC,sBAAsB,EAAE;EAClC,IAAI,IAAI,IAAI,CAAC,aAAa,EAAE;EAC5B,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACrD,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE;EACrB,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC7C,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE;EAC1B,MAAM,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;EACvD,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE;EACzB,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EACjD,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE;EACzB,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EACjD,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE;EACtB,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC/C,KAAK;EAEL,IAAI,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAEhD,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC1C,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;EAC3B,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;EAC1D,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,uBAAuB,EAAE;EACtC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACpE,QAAQ,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC;EACpE,OAAO;EACP,KAAK;EACL,IAAI,IAAI,sBAAsB,EAAE;EAChC,MAAM,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAChD,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE;EACpB,QAAQ,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;EAC7B,QAAQ,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;EAChC,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;EAC7B,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC;EACxB,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC;EACvB,GAAG;EAEH,EAAE,iBAAiB,GAAG;EACtB,IAAI,IAAI,CAAC,UAAU,CAAC,iBAAiB,GAAG,IAAI,CAAC;EAC7C,IAAI,IAAI,CAAC,UAAU,CAAC,wBAAwB,GAAG,IAAI,CAAC;EACpD,IAAI,IAAI,CAAC,UAAU,CAAC,sBAAsB,GAAG,IAAI,CAAC;EAClD,IAAI,IAAI,CAAC,UAAU,CAAC,kBAAkB,GAAG,IAAI,CAAC;EAC9C,GAAG;EAEH,EAAE,OAAO,cAAc,CAAC,OAAO,EAAE;EACjC,IAAI,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,oBAAoB,CAAC,CAAC;EACjE,IAAI,IAAI,SAAS,EAAE;EACnB,MAAM,SAAS,CAAC,WAAW,EAAE,CAAC;EAC9B,KAAK;EACL,GAAG;EAEH,EAAE,MAAM,GAAG;EACX,IAAI,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;EAChC,IAAI,IAAI,CAAC,aAAa,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC,MAAM,EAAE,CAAC;EACtF,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EACH,CAAC;;EC5gDM,MAAM,kBAAkB,SAAS,iBAAiB,CAAC;EAQ1D,EAAE,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE;EAC3C,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,EAAE;EACvC,MAAM,MAAM,IAAI,CAAC,cAAc;EAC/B,QAAQ,0CAA0C;EAClD,QAAQ,OAAO;EACf,OAAO,CAAC;EACR,KAAK;EAEL,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;EAEvC,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE;EACrC,MAAM,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;EAChD,KAAK,MAAM,IAAI,IAAI,KAAK,SAAS,EAAE;EACnC,MAAM,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE;EACzD,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAClD,OAAO,MAAM;EACb,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC5C,OAAO;EACP,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC1C,KAAK;EAEL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,CAAC;;ECvCM,MAAMK,gBAAc,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqY9B,CAAC,CAAC;;ECrYI,MAAMC,cAAY,GAAG,CAAC;;;;;;;;;;;;;;CAc5B,CAAC,CAAC;;ECbI,MAAM,wBAAwB,SAAS,uBAAuB,CAAC,EAAE;;ECAjE,MAAM,sBAAsB,SAAS,qBAAqB,CAAC,EAAE;;ECA7D,MAAM,wBAAwB,SAAS,uBAAuB,CAAC;EACtE,EAAE,SAAS,CAAC,KAAK,EAAE;EACnB,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE;EACrC,MAAM,OAAO,CAAC,MAAM,GAAG,iBAAiB,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;EACrF,KAAK;EACL,IAAI,OAAO,CAAC,QAAQ,GAAG,iBAAiB,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;EAC9D,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,OAAO;EAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC;EAChE,GAAG;EACH,CAAC;;ECZM,MAAM,0BAA0B,SAAS,yBAAyB,CAAC;EAC1E,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAON,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC3G,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACtI,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC;;ECTM,MAAM,iCAAiC,SAAS,gCAAgC,CAAC;EACxF,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC;;ECTM,MAAM,+BAA+B,SAAS,gBAAgB,CAAC;EACtE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;EACpD,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,UAAU,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;EACtE,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;EACzD,GAAG;EACH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;EACjE,GAAG;EACH,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,gBAAgB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAChE,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC3G,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACtI,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,MAAM,EAAE;EACtB,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,gBAAgB,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EACtD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,gBAAgB,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EAC7E,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,gBAAgB,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EAC7E,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;EAEjD,IAAI,EAAE,CAAC,UAAU;EACjB,MAAM,EAAE,CAAC,gBAAgB;EACzB,MAAM,CAAC;EACP,MAAM,EAAE,CAAC,IAAI;EACb,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;EACrB,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM;EACtB,MAAM,MAAM,CAAC,MAAM;EACnB,MAAM,CAAC;EACP,MAAM,EAAE,CAAC,IAAI;EACb,MAAM,EAAE,CAAC,aAAa;EACtB,MAAM,IAAI;EACV,KAAK,CAAC;EACN,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC5C,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC;EACxB,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC;EACxB,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC;EAC3B,MAAM,EAAE,CAAC,aAAa;EACtB,QAAQ,EAAE,CAAC,gBAAgB;EAC3B,QAAQ,CAAC;EACT,QAAQ,OAAO;EACf,QAAQ,OAAO;EACf,QAAQ,CAAC;EACT,QAAQ,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;EACvB,QAAQ,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM;EACxB,QAAQ,UAAU;EAClB,QAAQ,EAAE,CAAC,IAAI;EACf,QAAQ,EAAE,CAAC,aAAa;EACxB,QAAQ,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC;EACpC,OAAO,CAAC;EACR,KAAK;EACL,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;EC7DM,MAAM,sCAAsC,SAAS,+BAA+B,CAAC;EAC5F,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAO,KAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,gBAAgB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAChE,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,MAAM,EAAE;EACtB,IAAI,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;EACxC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,UAAU,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;EACrD,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACvC,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;EAC9B,GAAG;EACH,CAAC;;ECnBM,MAAM,0BAA0B,SAAS,0BAA0B,CAAC,EAAE;;ECAtE,MAAM,iCAAiC,SAAS,iCAAiC,CAAC,EAAE;;ECCpF,MAAM,4BAA4B,SAAS,2BAA2B,CAAC;EAC9E,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC3G,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACtI,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EACnD,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAClI,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;ECtBM,MAAM,mCAAmC,SAAS,4BAA4B,CAAC;EACtF,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;EAC/B,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC/D,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,kCAAkC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;EACvF,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAChE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECrBM,MAAM,8BAA8B,SAAS,6BAA6B,CAAC;EAClF,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC3G,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACtI,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC;;ECTM,MAAM,qCAAqC,SAAS,oCAAoC,CAAC;EAChG,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC;;ECTM,MAAM,6CAA6C,SAAS,4CAA4C,CAAC;EAChH,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;EACvE,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;EAC/B,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC5F,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,YAAY,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAClH,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC;;ECVM,MAAM,oDAAoD,SAAS,mDAAmD,CAAC;EAC9H,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC;;ECRM,MAAM,8BAA8B,SAAS,6BAA6B,CAAC;EAClF,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;EACvE,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC;EACtD,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC5F,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,YAAY,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAClH,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC;;ECVM,MAAM,qCAAqC,SAAS,oCAAoC,CAAC;EAChG,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC;;ECTM,MAAM,4BAA4B,SAAS,2BAA2B,CAAC;EAC9E,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC3G,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACtI,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7C,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAClI,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;EC1BM,MAAM,mCAAmC,SAAS,4BAA4B,CAAC;EACtF,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,UAAU,GAAGA,OAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACvD,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,kCAAkC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;EACvF,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAChE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECpBM,MAAM,+BAA+B,SAAS,8BAA8B,CAAC;EACpF,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7C,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAClI,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;ECjBM,MAAM,sCAAsC,SAAS,+BAA+B,CAAC;EAC5F,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;EACzB,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;EChBM,MAAM,+BAA+B,SAAS,8BAA8B,CAAC;EACpF,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7C,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAClI,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;ECjBM,MAAM,sCAAsC,SAAS,+BAA+B,CAAC;EAC5F,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;EACzB,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;EChBM,MAAM,+BAA+B,SAAS,8BAA8B,CAAC;EACpF,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7C,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAClI,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;ECjBM,MAAM,sCAAsC,SAAS,+BAA+B,CAAC;EAC5F,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;EACzB,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECjBM,MAAM,6BAA6B,SAAS,4BAA4B,CAAC,EAAE;;ECA3E,MAAM,6BAA6B,SAAS,4BAA4B,CAAC,EAAE;;ECA3E,MAAM,6BAA6B,SAAS,4BAA4B,CAAC,EAAE;;ECC3E,MAAM,8BAA8B,SAAS,6BAA6B,CAAC;EAClF,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC3G,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACtI,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC;;ECTM,MAAM,qCAAqC,SAAS,oCAAoC,CAAC;EAChG,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC;;ECgCM,MAAMO,iBAAe,GAAG;EAC/B,EAAE,QAAQ,EAAE;EACZ,IAAI,OAAO,EAAE;EACb,MAAM,SAAS,EAAE,wBAAwB;EACzC,MAAM,SAAS,EAAE,wBAAwB;EACzC,MAAM,OAAO,EAAE,sBAAsB;EACrC,MAAM,OAAO,EAAE,qCAAqC;EACpD,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,OAAO,EAAE,qCAAqC;EACpD,MAAM,eAAe,EAAE,qCAAqC;EAC5D,MAAM,iBAAiB,EAAE,qCAAqC;EAC9D,MAAM,iBAAiB,EAAE,qCAAqC;EAC9D,MAAM,iBAAiB,EAAE,qCAAqC;EAC9D,MAAM,iBAAiB,EAAE,qCAAqC;EAC9D,MAAM,8BAA8B,EAAE,oDAAoD;EAC1F,MAAM,WAAW,EAAE,iCAAiC;EACpD,MAAM,gBAAgB,EAAE,sCAAsC;EAC9D,MAAM,WAAW,EAAE,iCAAiC;EACpD,KAAK;EACL,IAAI,MAAM,EAAE;EACZ,MAAM,SAAS,EAAE,wBAAwB;EACzC,MAAM,OAAO,EAAE,sBAAsB;EACrC,MAAM,SAAS,EAAE,wBAAwB;EACzC,MAAM,OAAO,EAAE,8BAA8B;EAC7C,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,OAAO,EAAE,8BAA8B;EAC7C,MAAM,eAAe,EAAE,8BAA8B;EACrD,MAAM,iBAAiB,EAAE,8BAA8B;EACvD,MAAM,iBAAiB,EAAE,8BAA8B;EACvD,MAAM,iBAAiB,EAAE,8BAA8B;EACvD,MAAM,iBAAiB,EAAE,8BAA8B;EACvD,MAAM,8BAA8B,EAAE,oDAAoD;EAC1F,MAAM,WAAW,EAAE,0BAA0B;EAC7C,MAAM,gBAAgB,EAAE,+BAA+B;EACvD,MAAM,WAAW,EAAE,0BAA0B;EAC7C,KAAK;EACL,GAAG;EACH,EAAE,MAAM,EAAE;EACV,IAAI,OAAO,EAAE;EACb,MAAM,SAAS,EAAE,wBAAwB;EACzC,MAAM,SAAS,EAAE,wBAAwB;EACzC,MAAM,OAAO,EAAE,sBAAsB;EACrC,MAAM,OAAO,EAAE,mCAAmC;EAClD,MAAM,UAAU,EAAE,6BAA6B;EAC/C,MAAM,UAAU,EAAE,6BAA6B;EAC/C,MAAM,UAAU,EAAE,6BAA6B;EAC/C,MAAM,YAAY,EAAE,sCAAsC;EAC1D,MAAM,YAAY,EAAE,sCAAsC;EAC1D,MAAM,YAAY,EAAE,sCAAsC;EAC1D,MAAM,YAAY,EAAE,sCAAsC;EAC1D,MAAM,YAAY,EAAE,sCAAsC;EAC1D,MAAM,YAAY,EAAE,sCAAsC;EAC1D,MAAM,YAAY,EAAE,sCAAsC;EAC1D,MAAM,YAAY,EAAE,sCAAsC;EAC1D,MAAM,YAAY,EAAE,sCAAsC;EAC1D,MAAM,OAAO,EAAE,mCAAmC;EAClD,MAAM,eAAe,EAAE,qCAAqC;EAC5D,MAAM,iBAAiB,EAAE,qCAAqC;EAC9D,MAAM,iBAAiB,EAAE,qCAAqC;EAC9D,MAAM,iBAAiB,EAAE,qCAAqC;EAC9D,MAAM,iBAAiB,EAAE,qCAAqC;EAC9D,MAAM,8BAA8B,EAAE,oDAAoD;EAC1F,MAAM,WAAW,EAAE,iCAAiC;EACpD,MAAM,gBAAgB,EAAE,sCAAsC;EAC9D,MAAM,WAAW,EAAE,iCAAiC;EACpD,KAAK;EACL,IAAI,MAAM,EAAE;EACZ,MAAM,SAAS,EAAE,wBAAwB;EACzC,MAAM,OAAO,EAAE,sBAAsB;EACrC,MAAM,SAAS,EAAE,wBAAwB;EACzC,MAAM,OAAO,EAAE,4BAA4B;EAC3C,MAAM,UAAU,EAAE,6BAA6B;EAC/C,MAAM,UAAU,EAAE,6BAA6B;EAC/C,MAAM,UAAU,EAAE,6BAA6B;EAC/C,MAAM,YAAY,EAAE,+BAA+B;EACnD,MAAM,YAAY,EAAE,+BAA+B;EACnD,MAAM,YAAY,EAAE,+BAA+B;EACnD,MAAM,YAAY,EAAE,+BAA+B;EACnD,MAAM,YAAY,EAAE,+BAA+B;EACnD,MAAM,YAAY,EAAE,+BAA+B;EACnD,MAAM,YAAY,EAAE,+BAA+B;EACnD,MAAM,YAAY,EAAE,+BAA+B;EACnD,MAAM,YAAY,EAAE,+BAA+B;EACnD,MAAM,OAAO,EAAE,4BAA4B;EAC3C,MAAM,eAAe,EAAE,8BAA8B;EACrD,MAAM,iBAAiB,EAAE,8BAA8B;EACvD,MAAM,iBAAiB,EAAE,8BAA8B;EACvD,MAAM,iBAAiB,EAAE,8BAA8B;EACvD,MAAM,iBAAiB,EAAE,8BAA8B;EACvD,MAAM,8BAA8B,EAAE,6CAA6C;EACnF,MAAM,WAAW,EAAE,0BAA0B;EAC7C,MAAM,gBAAgB,EAAE,+BAA+B;EACvD,MAAM,WAAW,EAAE,0BAA0B;EAC7C,KAAK;EACL,GAAG;EACH,CAAC,CAAC;AAEF,EAAO,SAASC,uBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE;EACvE,EAAE,IAAI,CAAC,IAAI,EAAE;EACb,IAAI,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;EACpC,GAAG;EACH,EAAE,IAAI,CAAC,OAAO,EAAE;EAChB,IAAI,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;EACvC,GAAG;EACH,EAAE,IAAI,CAAC,SAAS,EAAE;EAClB,IAAI,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;EACzC,GAAG;EACH,EAAE,IAAI,KAAK,CAAC,IAAI,EAAE;EAClB,IAAI,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;EACtB,GAAG;EACH,EAAE,MAAM,KAAK,GAAGD,iBAAe,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC;EACpD,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,EAAE;EAC7B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,SAAS,EAAE;EACxC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,iCAAiC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;EAClE,GAAG;EACH,EAAE,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC;EACrB,CAAC;;EC/KD,IAAIE,aAAW,GAAG,IAAI,CAAC;EACvB,IAAIC,YAAU,GAAG,IAAI,CAAC;EACtB,IAAIC,aAAW,GAAG,IAAI,CAAC;EACvB,IAAIC,gBAAc,GAAG,IAAI,CAAC;EAM1B,IAAIC,UAAQ,GAAG,IAAI,CAAC;AAKpB,EAAO,MAAM,YAAY,SAAS,WAAW,CAAC;EAC9C,EAAE,WAAW,WAAW,GAAG;EAC3B,IAAI,IAAIJ,aAAW,KAAK,IAAI,EAAE;EAC9B,MAAM,OAAOA,aAAW,CAAC;EACzB,KAAK;EACL,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;EAC9B,IAAIA,aAAW,GAAG,IAAI,CAAC,cAAc,CAACE,aAAW,CAAC,CAAC;EACnD,IAAI,OAAOF,aAAW,CAAC;EACvB,GAAG;EAEH,EAAE,OAAO,kBAAkB,GAAG;EAC9B,IAAI,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;EACzC,MAAMC,YAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;EACpD,KAAK,MAAM,IAAI,OAAO,eAAe,KAAK,WAAW,EAAE;EACvD,MAAMA,YAAU,GAAG,IAAI,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;EAC7C,KAAK;EACL,IAAI,IAAI,CAACA,YAAU,EAAE,OAAO;EAC5B,IAAIC,aAAW,GAAGD,YAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;EAClD,IAAI,IAAI,CAACC,aAAW,IAAI,CAACA,aAAW,CAAC,YAAY,EAAE,OAAO;EAC1D,IAAIC,gBAAc,GAAG;EACrB,MAAM,sBAAsB,EAAED,aAAW,CAAC,YAAY,CAAC,wBAAwB,CAAC;EAChF,MAAM,wBAAwB,EAAEA,aAAW,CAAC,YAAY,CAAC,0BAA0B,CAAC;EACpF,KAAK,CAAC;EACN,IAAIE,UAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;EAClC,GAAG;EAEH,EAAE,OAAO,cAAc,CAAC,OAAO,EAAE;EAEjC,IAAI,IAAI,OAAO,sBAAsB,KAAK,WAAW,EAAE;EACvD,MAAM,OAAO,OAAO,YAAY,sBAAsB,CAAC;EACvD,KAAK;EACL,IAAI,OAAO,KAAK,CAAC;EACjB,GAAG;EAEH,EAAE,OAAO,WAAW,GAAG;EACvB,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC;EACzB,MAAM,WAAW,EAAE,IAAI,CAAC,cAAc,EAAE;EACxC,MAAM,yBAAyB,EAAE,IAAI,CAAC,4BAA4B,EAAE;EACpE,MAAM,SAAS,EAAE,IAAI;EACrB,MAAM,cAAc,EAAE,IAAI;EAC1B,MAAM,YAAY,EAAE,IAAI,CAAC,eAAe,EAAE;EAC1C,MAAM,cAAc,EAAE,IAAI,CAAC,iBAAiB,EAAE;EAC9C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,OAAO,iBAAiB,GAAG;EAC7B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,OAAO,4BAA4B,GAAG;EACxC,IAAI,OAAO,KAAK,CAAC,4BAA4B,EAAE,CAAC;EAChD,GAAG;EAEH,EAAE,OAAO,eAAe,GAAG;EAC3B,IAAI,OAAOF,aAAW,CAAC,YAAY,CAACA,aAAW,CAAC,gBAAgB,CAAC,CAAC;EAClE,GAAG;EAEH,EAAE,OAAO,iBAAiB,GAAG;EAC7B,IAAI,OAAOA,aAAW,CAAC,YAAY,CAACA,aAAW,CAAC,gBAAgB,CAAC,CAAC;EAClE,GAAG;EAEH,EAAE,OAAO,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE;EAChE,IAAI,OAAOH,uBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;EAClE,GAAG;EAEH,EAAE,WAAW,UAAU,GAAG;EAC1B,IAAI,OAAOE,YAAU,CAAC;EACtB,GAAG;EAEH,EAAE,WAAW,WAAW,GAAG;EAC3B,IAAI,OAAOC,aAAW,CAAC;EACvB,GAAG;EAMH,EAAE,WAAW,QAAQ,GAAG;EACxB,IAAI,OAAOE,UAAQ,CAAC;EACpB,GAAG;EAEH,EAAE,WAAW,cAAc,GAAG;EAC9B,IAAI,OAAOR,gBAAc,CAAC;EAC1B,GAAG;EACH,EAAE,WAAW,YAAY,GAAG;EAC5B,IAAI,OAAOC,cAAY,CAAC;EACxB,GAAG;EAEH,EAAE,WAAW,GAAG;EAChB,IAAI,MAAM,QAAQ,GAAG;EACrB,MAAM,KAAK,EAAE,KAAK;EAClB,MAAM,KAAK,EAAE,KAAK;EAClB,MAAM,SAAS,EAAE,KAAK;EACtB,KAAK,CAAC;EACN,IAAI,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;EAC/D,IAAI,OAAO,OAAO,CAAC;EACnB,GAAG;EAEH,EAAE,cAAc,GAAG;EACnB,IAAI,IAAI,CAAC,UAAU,GAAG;EACtB,MAAM,sBAAsB,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,wBAAwB,CAAC;EACjF,MAAM,wBAAwB,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,0BAA0B,CAAC;EACrF,KAAK,CAAC;EACN,GAAG;EAMH,EAAE,gBAAgB,CAAC,IAAI,EAAE;EACzB,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;EACxB,MAAM,IAAI,CAAC,OAAO,GAAGN,OAAK,CAAC,oBAAoB,CAAC;EAChD,QAAQ,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;EACrD,QAAQ,SAAS,EAAE,IAAI,CAAC,SAAS;EACjC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACtB,MAAM,OAAO;EACb,KAAK;EAEL,IAAI,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC;EAC/C,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE;EAC9D,MAAM,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;EACjE,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE;EAC3D,MAAM,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC;EACpE,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,0BAA0B,KAAK,IAAI,EAAE;EAClD,MAAM,IAAI,CAAC,0BAA0B,GAAG,CAAC,QAAQ,CAAC,yBAAyB,CAAC;EAC5E,KAAK,MAAM,IAAI,IAAI,CAAC,0BAA0B,IAAI,QAAQ,CAAC,yBAAyB,EAAE;EACtF,MAAM,IAAI,CAAC,0BAA0B,GAAG,KAAK,CAAC;EAC9C,KAAK;EAEL,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;EAEvB,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;EAClD,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;EAC7B,QAAQ,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;EACtF,OAAO;EAEP,MAAM,MAAM,OAAO,GAAGA,OAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;EAC1E,MAAM,QAAQ,OAAO;EACrB,QAAQ,KAAK,OAAO;EACpB,UAAU,IAAI,CAAC,MAAM,GAAGA,OAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;EACrD,UAAU,MAAM;EAChB,QAAQ,KAAK,eAAe,CAAC;EAC7B,QAAQ,KAAK,8BAA8B,CAAC;EAC5C,QAAQ,KAAK,iBAAiB,CAAC;EAC/B,QAAQ,KAAK,iBAAiB,CAAC;EAC/B,QAAQ,KAAK,iBAAiB,CAAC;EAC/B,QAAQ,KAAK,iBAAiB;EAC9B,UAAU,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;EACvC,UAAU,MAAM;EAChB,QAAQ;EACR,UAAU,MAAM,IAAI,KAAK,CAAC,4CAA4C,GAAG,OAAO,CAAC,CAAC;EAClF,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;EACpC,QAAQ,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;EAC3E,OAAO;EAEP,MAAM,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE;EACvC,QAAQ,OAAO,CAAC,IAAI,CAAC,iEAAiE,CAAC,CAAC;EACxF,QAAQ,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC;EACpC,OAAO;EAEP,MAAM,IAAI,CAAC,OAAO,GAAGA,OAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC9C,MAAM,OAAO;EACb,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,QAAQ,CAAC,cAAc,EAAE;EACtF,MAAM,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;EAChC,KAAK;EAEL,IAAI,IAAI,CAAC,OAAO,GAAGA,OAAK,CAAC,oBAAoB,CAAC;EAC9C,MAAM,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;EACnD,MAAM,SAAS,EAAE,IAAI,CAAC,SAAS;EAC/B,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAEpB,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;EAC5B,GAAG;EAEH,EAAE,eAAe,GAAG;EACpB,IAAI,MAAM,eAAe,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,kBAAkB,EAAE;EACjF,MAAM,0BAA0B,EAAE,IAAI,CAAC,0BAA0B;EACjE,KAAK,CAAC,CAAC;EACP,IAAI,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;EACzE,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;EAC7C,MAAM,IAAI,CAAC,UAAU,GAAG,eAAe,CAAC,mBAAmB,EAAE,CAAC;EAC9D,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;EACvD,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACvD,QAAQ,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC7C,QAAQ,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE;EACnC,UAAU,SAAS,CAAC,UAAU,GAAG,eAAe,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;EAC3E,SAAS;EACT,OAAO;EACP,KAAK;EACL,GAAG;EAEH,EAAE,GAAG,GAAG;EACR,IAAI,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,0BAA0B,EAAE,GAAG,IAAI,CAAC;EAC1E,IAAI,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;EAE5B,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAChC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;EAE7C,IAAI,IAAI,IAAI,CAAC,aAAa,EAAE;EAC5B,MAAM,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;EACvE,MAAM,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;EAC9C,KAAK;EAEL,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;EAEjG,IAAI,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;EAClC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,0BAA0B,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAChE,MAAM,MAAM,QAAQ,GAAG,0BAA0B,CAAC,CAAC,CAAC,CAAC;EACrD,MAAM,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;EAC1D,MAAM,IAAI,IAAI,CAAC,gBAAgB,EAAE,OAAO;EACxC,KAAK;EACL,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,eAAe,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;EACnD,MAAM,IAAI,IAAI,CAAC,gBAAgB,EAAE,OAAO;EACxC,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE;EACtB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACpD,QAAQ,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;EACvC,QAAQ,IAAI,MAAM,CAAC,WAAW,EAAE;EAChC,UAAU,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;EACnC,SAAS;EACT,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE;EACzB,QAAQ,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;EACnD,QAAQ,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,QAAQ,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,SAAS,EAAE;EACnD,UAAU,IAAI,CAAC,mBAAmB,EAAE,CAAC;EACrC,SAAS;EACT,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;EAC/C,QAAQ,OAAO,IAAI,IAAI,CAAC,kBAAkB,CAAC;EAC3C,UAAU,OAAO,EAAE,IAAI,CAAC,aAAa;EACrC,UAAU,IAAI,EAAE,OAAO;EACvB,UAAU,UAAU,EAAE,IAAI,CAAC,SAAS;EACpC,UAAU,MAAM,EAAE,IAAI,CAAC,MAAM;EAC7B,UAAU,OAAO,EAAE,IAAI,CAAC,OAAO;EAC/B,SAAS,CAAC,CAAC;EACX,OAAO;EACP,MAAM,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;EACjD,MAAM,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;EAC/C,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;EAC7C,MAAM,OAAO;EACb,KAAK;EAEL,IAAI,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EACzD,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;EACjC,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;EAClC,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE;EAC1B,QAAQ,IAAI,CAAC,uBAAuB,EAAE,CAAC;EACvC,OAAO;EACP,MAAM,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;EAC1C,KAAK;EAEL,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;EAC3C,GAAG;EAEH,EAAE,WAAW,GAAG;EAChB,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;EAClD,GAAG;EAEH,EAAE,gBAAgB,GAAG;EACrB,IAAI,OAAO,IAAI,CAAC,aAAa,CAAC;EAC9B,GAAG;EAEH,EAAE,mBAAmB,GAAG;EACxB,IAAI,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;EAC7B,IAAI,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;EAC5B,IAAI,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC,aAAa,EAAE,CAAC;EAC5D,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,CAAC,CAAC;EAC1F,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;EAC3C,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE;EACrC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE;EACzB,QAAQ,QAAQ,IAAI,CAAC,UAAU;EAC/B,UAAU,KAAK,QAAQ,CAAC;EACxB,UAAU,KAAK,OAAO,CAAC;EACvB,UAAU,KAAK,SAAS;EACxB,YAAY,IAAI,IAAI,CAAC,mBAAmB,EAAE;EAC1C,cAAc,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,aAAa,MAAM;EACnB,cAAc,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;EACjF,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;EAChF,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU,CAAC;EAC1B,UAAU,KAAK,UAAU;EACzB,YAAY,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;EAClF,YAAY,MAAM;EAClB,UAAU;EACV,YAAY,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;EACrD,SAAS;EACT,OAAO,MAAM;EACb,QAAQ,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;EAC9E,OAAO;EACP,KAAK,MAAM;EACX,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;EAC3G,KAAK;EACL,IAAI,EAAE,CAAC,oBAAoB,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,iBAAiB,EAAE,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;EAC7F,GAAG;EAEH,EAAE,uBAAuB,GAAG;EAC5B,IAAI,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;EAC7B,IAAI,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;EAC5B,IAAI,IAAI,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC;EACjD,IAAI,IAAI,CAAC,uBAAuB,GAAG,EAAE,CAAC;EACtC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;EACnD,MAAM,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACjD,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,iBAAiB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;EAC7D,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC,CAAC;EAChG,MAAM,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;EAC7C,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EAC3E,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EAC3E,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACzE,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EAEzE,MAAM,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE;EACvC,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACxG,OAAO,MAAM;EACb,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;EAC7G,OAAO;EACP,MAAM,EAAE,CAAC,oBAAoB,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,iBAAiB,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;EACvG,KAAK;EACL,GAAG;EASH,EAAE,gBAAgB,GAAG;EACrB,IAAI,OAAO,EAAE,CAAC;EACd,GAAG;EAMH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;EACvC,IAAI,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;EACtD,MAAM,QAAQ,IAAI,CAAC,MAAM;EACzB,QAAQ,KAAK,OAAO;EACpB,UAAU,OAAO,2BAA2B,CAAC;EAC7C,QAAQ,KAAK,aAAa;EAC1B,UAAU,OAAO,4BAA4B,CAAC;EAC9C,QAAQ,KAAK,UAAU,CAAC;EACxB,QAAQ;EACR,UAAU,OAAO,8BAA8B,CAAC;EAChD,OAAO;EACP,KAAK,MAAM;EACX,MAAM,QAAQ,IAAI,CAAC,MAAM;EACzB,QAAQ,KAAK,OAAO;EACpB,UAAU,OAAO,4BAA4B,CAAC;EAC9C,QAAQ,KAAK,aAAa;EAC1B,UAAU,OAAO,6BAA6B,CAAC;EAC/C,QAAQ,KAAK,UAAU,CAAC;EACxB,QAAQ;EACR,UAAU,OAAO,+BAA+B,CAAC;EACjD,OAAO;EACP,KAAK;EACL,GAAG;EAOH,EAAE,uBAAuB,CAAC,IAAI,EAAE;EAChC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;EAC7C,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACnD,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC9D,KAAK;EACL,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3B,GAAG;EAMH,EAAE,eAAe,GAAG;EACpB,IAAI,IAAI,uBAAuB,CAAC;EAChC,IAAI,QAAQ,IAAI,CAAC,UAAU;EAC3B,MAAM,KAAK,UAAU;EACrB,QAAQ,uBAAuB,GAAG,mBAAmB,CAAC;EACtD,QAAQ,MAAM;EACd,MAAM,KAAK,UAAU;EACrB,QAAQ,uBAAuB,GAAG,mBAAmB,CAAC;EACtD,QAAQ,MAAM;EACd,MAAM,KAAK,UAAU;EACrB,QAAQ,uBAAuB,GAAG,mBAAmB,CAAC;EACtD,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,OAAO,CAAC;EACnB,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,SAAS;EACpB,QAAQ,uBAAuB,GAAG,oBAAoB,CAAC;EACvD,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE;EAC5B,UAAU,uBAAuB,GAAG,oBAAoB,CAAC;EACzD,SAAS,MAAM;EACf,UAAU,MAAM,IAAI,KAAK,CAAC,CAAC,0BAA0B,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;EAC7E,SAAS;EACT,KAAK;EAEL,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;EACvC,IAAI,IAAI,UAAU,KAAK,IAAI,EAAE;EAC7B,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,uBAAuB;EAC/B,QAAQ,qCAAqC;EAC7C,OAAO,CAAC;EACR,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,QAAQ,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;EACxC,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,SAAS,CAAC,UAAU,KAAK,SAAS;EAC5C,UAAU,CAAC,oBAAoB,GAAG,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC;EACvD,UAAU,CAAC,sBAAsB,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC;EAC3D,UAAU,CAAC,kBAAkB,GAAG,CAAC,GAAG,CAAC,EAAE,eAAe,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;EACjE,SAAS,CAAC;EACV,OAAO;EACP,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,gBAAgB;EACxB,QAAQ,uBAAuB;EAC/B,OAAO,CAAC;EACR,KAAK;EAEL,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC;EAC/D,GAAG;EAEH,EAAE,sBAAsB,GAAG;EAC3B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,uBAAuB;EAC7B,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,yBAAyB,GAAG;EAC9B,IAAI,QAAQ,IAAI,CAAC,UAAU;EAC3B,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,OAAO;EAClB,QAAQ,OAAO,IAAI,CAAC,+BAA+B,EAAE;EACrD,UAAU,IAAI,CAAC,kCAAkC,EAAE,CAAC;EACpD,MAAM;EACN,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,yCAAyC,EAAE,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;EAClG,KAAK;EACL,GAAG;EAKH,EAAE,+BAA+B,GAAG;EACpC,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,GAAG,UAAU,CAAC,cAAc,CAAC;EACxF,KAAK,CAAC,CAAC;EACP,GAAG;EAKH,EAAE,kCAAkC,GAAG;EACvC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC;EACpC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC3C,MAAM,IAAI,SAAS,CAAC,UAAU,KAAK,SAAS,EAAE;EAC9C,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,GAAG,UAAU,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;EACxI,SAAS,CAAC;EACV,OAAO,MAAM;EACb,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,GAAG,UAAU,CAAC,iBAAiB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EACjI,SAAS,CAAC;EACV,OAAO;EACP,KAAK;EACL,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;EACvC,GAAG;EAEH,EAAE,kCAAkC,GAAG;EACvC,IAAI,MAAM,MAAM,GAAG;EACnB,MAAM,cAAc;EACpB,KAAK,CAAC;EAEN,IAAI,QAAQ,IAAI,CAAC,UAAU;EAC3B,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,OAAO;EAClB,QAAQ,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;EAC9C,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,UAAU,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;EACtC,UAAU,IAAI,CAAC,wCAAwC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;EACzE,UAAU,IAAI,CAAC,2CAA2C,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;EAC5E,UAAU,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE;EACvC,YAAY,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;EACxC,WAAW;EACX,SAAS;EACT,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,2CAA2C,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;EACnG,KAAK;EAEL,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;EACvC,GAAG;EAEH,EAAE,wCAAwC,CAAC,MAAM,EAAE,OAAO,EAAE;EAC5D,IAAI,MAAM,CAAC,IAAI;EACf,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,eAAe,CAAC;EACzC,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,2CAA2C,CAAC,MAAM,EAAE,OAAO,EAAE;EAC/D,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,CAAC;EACxC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC3C,MAAM,IAAI,SAAS,CAAC,UAAU,KAAK,SAAS,EAAE;EAC9C,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,yBAAyB,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;EAChF,SAAS,CAAC;EACV,OAAO,MAAM;EACb,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,mBAAmB,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;EACzE,SAAS,CAAC;EACV,OAAO;EACP,KAAK;EACL,GAAG;EAEH,EAAE,gCAAgC,GAAG;EACrC,IAAI,OAAO;EACX,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,2BAA2B;EACjC,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,CAAC;EACxC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACrD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC3C,MAAM,IAAI,SAAS,CAAC,UAAU,KAAK,SAAS,EAAE;EAC9C,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,4BAA4B,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;EACxE,SAAS,CAAC;EACV,OAAO,MAAM;EACb,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,sBAAsB,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;EACjE,SAAS,CAAC;EACV,OAAO;EACP,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,gCAAgC,GAAG;EACrC,IAAI,OAAO;EACX,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,8BAA8B;EACpC,MAAM,8BAA8B;EACpC,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,CAAC;EACxC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACrD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC3C,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,sBAAsB,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;EAClE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,sBAAsB,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;EAClE,OAAO,CAAC;EACR,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,gCAAgC,GAAG;EACrC,IAAI,OAAO;EACX,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,8BAA8B;EACpC,MAAM,8BAA8B;EACpC,MAAM,8BAA8B;EACpC,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,CAAC;EACxC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACrD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC3C,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,sBAAsB,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;EAClE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,sBAAsB,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;EAClE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,sBAAsB,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;EAClE,OAAO,CAAC;EACR,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,gCAAgC,GAAG;EACrC,IAAI,OAAO;EACX,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,wBAAwB;EAC9B,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,CAAC;EACxC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACrD,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,mBAAmB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EACrE,OAAO,CAAC;EACR,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,iBAAiB,GAAG;EACtB,IAAI,IAAI,CAAC,UAAU,CAAC,sBAAsB,GAAG,IAAI,CAAC;EAClD,IAAI,IAAI,CAAC,UAAU,CAAC,wBAAwB,GAAG,IAAI,CAAC;EACpD,GAAG;EAEH,EAAE,MAAM,GAAG;EACX,IAAI,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;EAChC,IAAI,IAAI,CAAC,aAAa,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC,MAAM,EAAE,CAAC;EACvF,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EACH,CAAC;;ECjqBM,SAAS,iBAAiB,CAAC,MAAM,EAAE;EAC1C,EAAE,IAAI,GAAG,GAAG,WAAW;EACvB,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;EAC1C,IAAI,IAAI,MAAM,CAAC,aAAa,EAAE;EAC9B,MAAM,GAAG,GAAG,WAAW;EACvB,QAAQ,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;EAC5C,QAAQ,IAAI,MAAM,CAAC,gBAAgB,EAAE;EACrC,UAAU,MAAM,CAAC,gBAAgB,GAAG,KAAK,CAAC;EAC1C,UAAU,OAAO,MAAM,CAAC,qBAAqB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EACjE,SAAS;EACT,QAAQ,OAAO,MAAM,CAAC,aAAa,EAAE,CAAC;EACtC,OAAO,CAAC;EACR,KAAK,MAAM,IAAI,MAAM,CAAC,YAAY,EAAE;EACpC,MAAM,GAAG,GAAG,WAAW;EACvB,QAAQ,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;EAC5C,QAAQ,IAAI,MAAM,CAAC,gBAAgB,EAAE;EACrC,UAAU,MAAM,CAAC,gBAAgB,GAAG,KAAK,CAAC;EAC1C,UAAU,OAAO,MAAM,CAAC,qBAAqB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EACjE,SAAS;EACT,QAAQ,OAAO,MAAM,CAAC,YAAY,EAAE,CAAC;EACrC,OAAO,CAAC;EACR,KAAK,MAAM;EACX,MAAM,GAAG,GAAG,WAAW;EACvB,QAAQ,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;EACnD,OAAO,CAAC;EACR,KAAK;EACL,IAAI,OAAO,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;EACxC,GAAG,CAAC;EACJ,EAAE,MAAM,QAAQ,GAAG,WAAW;EAC9B,IAAI,OAAO,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;EACxC,GAAG,CAAC;EAKJ,EAAE,QAAQ,CAAC,IAAI,GAAG,WAAW;EAC7B,IAAI,OAAO,IAAI,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK;EAC3C,MAAM,IAAI;EACV,QAAQ,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;EAC3C,OAAO,CAAC,OAAO,CAAC,EAAE;EAClB,QAAQ,MAAM,CAAC,CAAC,CAAC,CAAC;EAClB,OAAO;EACP,KAAK,CAAC,CAAC;EACP,GAAG,CAAC;EACJ,EAAE,QAAQ,CAAC,aAAa,GAAG,SAAS,iBAAiB,EAAE;EACvD,IAAI,MAAM,GAAG,iBAAiB,CAAC;EAC/B,IAAI,oBAAoB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;EAC3C,IAAI,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;EAC7B,GAAG,CAAC;EAEJ,EAAE,oBAAoB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;EACzC,EAAE,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;EAC3B,EAAE,OAAO,QAAQ,CAAC;EAClB,CAAC;EAED,SAAS,oBAAoB,CAAC,MAAM,EAAE,QAAQ,EAAE;EAChD,EAAE,MAAM,UAAU,GAAGA,OAAK,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;EACnD,EAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC9C,IAAI,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;EACnC,IAAI,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,SAAS;EAC7D,IAAI,IAAI,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,UAAU,EAAE;EAChD,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,IAAI,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,EAAE;EACpF,QAAQ,QAAQ,CAAC,QAAQ,CAAC,GAAG,WAAW;EACxC,UAAU,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;EACpD,UAAU,OAAO,QAAQ,CAAC;EAC1B,SAAS,CAAC;EACV,OAAO,MAAM;EACb,QAAQ,IAAI,QAAQ,KAAK,UAAU,EAAE;EACrC,UAAU,QAAQ,CAAC,QAAQ,GAAG,WAAW;EACzC,YAAY,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;EAC5D,WAAW,CAAC;EACZ,SAAS,MAAM;EACf,UAAU,QAAQ,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC7D,SAAS;EACT,OAAO;EACP,KAAK,MAAM;EACX,MAAM,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM;EAChD,QAAQ,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC;EAChC,OAAO,CAAC,CAAC;EACT,MAAM,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,KAAK,KAAK;EACrD,QAAQ,MAAM,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC;EACjC,OAAO,CAAC,CAAC;EACT,KAAK;EACL,GAAG;EACH,CAAC;;EC3ED,MAAM,WAAW,GAAG,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;EAKlD,MAAM,WAAW,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;EAErC,MAAM,eAAe,GAAG;EACxB,EAAE,QAAQ,EAAE,YAAY;EACxB,EAAE,OAAO,EAAE,WAAW;EACtB,CAAC,CAAC;EAEF,IAAI,QAAQ,GAAG,IAAI,CAAC;AAKpB,EAAO,MAAM,GAAG,CAAC;EACjB,EAAE,OAAO,iBAAiB,GAAG;EAC7B,IAAI,QAAQ,GAAG,KAAK,CAAC;EACrB,GAAG;EAEH,EAAE,OAAO,gBAAgB,GAAG;EAC5B,IAAI,QAAQ,GAAG,IAAI,CAAC;EACpB,GAAG;EAEH,EAAE,WAAW,cAAc,GAAG;EAC9B,IAAI,OAAO,WAAW,CAAC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,WAAW,CAAC,CAAC;EAC1D,GAAG;EAMH,EAAE,WAAW,oBAAoB,GAAG;EACpC,IAAI,OAAO,WAAW,CAAC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;EACvF,GAAG;EAKH,EAAE,WAAW,0BAA0B,GAAG;EAC1C,IAAI,OAAO,CAAC,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,eAAe,KAAK,WAAW,KAAK,OAAO,aAAa,KAAK,WAAW,CAAC;EAC7H,GAAG;EAKH,EAAE,WAAW,gBAAgB,GAAG;EAChC,IAAI,OAAO,WAAW,CAAC,WAAW,CAAC;EACnC,GAAG;EAKH,EAAE,WAAW,iBAAiB,GAAG;EACjC,IAAI,OAAO,YAAY,CAAC,WAAW,CAAC;EACpC,GAAG;EAKH,EAAE,WAAW,qBAAqB,GAAG;EACrC,IAAI,OAAO,KAAK,CAAC;EACjB,GAAG;EAMH,EAAE,WAAW,iBAAiB,GAAG;EACjC,IAAI,OAAO,OAAO,iBAAiB,KAAK,WAAW,CAAC;EACpD,GAAG;EAKH,EAAE,WAAW,4BAA4B,GAAG;EAC5C,IAAI,OAAO,YAAY,CAAC,WAAW,CAAC;EACpC,GAAG;EAMH,EAAE,WAAW,0BAA0B,GAAG;EAC1C,IAAI,OAAO,WAAW,CAAC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,QAAQ,CAAC,WAAW,IAAI,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;EAC3H,GAAG;EAMH,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,QAAQ,GAAG,QAAQ,IAAI,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,IAAI,CAAC;EAC1C,IAAI,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,IAAI,IAAI,CAAC;EAC5C,IAAI,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;EAC9B,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;EACvB,IAAI,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;EACxB,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;EAC/B,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,OAAO;EACpC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;EAExB,IAAI,IAAI,QAAQ,CAAC,SAAS,EAAE;EAC5B,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC1D,QAAQ,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;EAChD,OAAO;EACP,KAAK;EAGL,IAAI,IAAI,QAAQ,CAAC,eAAe,EAAE;EAClC,MAAM,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,eAAe,EAAE;EAChD,QAAQ,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/D,OAAO;EACP,KAAK;EACL,GAAG;EAEH,EAAE,WAAW,GAAG;EAChB,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EAKH,EAAE,YAAY,GAAG;EACjB,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,OAAO;EAE5B,IAAI,IAAI,MAAM,GAAG,IAAI,CAAC;EAEtB,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE;EACtB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACnD,QAAQ,MAAM,cAAc,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;EAC9C,QAAQ,IAAI,cAAc,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;EACzD,UAAU,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE;EAC3C,YAAY,MAAM,IAAI,KAAK,CAAC,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;EAChF,WAAW;EACX,UAAU,MAAM,GAAG,cAAc,CAAC;EAClC,UAAU,MAAM;EAChB,SAAS;EACT,OAAO;EACP,MAAM,IAAI,MAAM,KAAK,IAAI,EAAE;EAC3B,QAAQ,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;EAC3C,OAAO;EACP,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE;EAC1B,MAAM,IAAI,IAAI,CAAC,IAAI,IAAI,eAAe,EAAE;EACxC,QAAQ,IAAI,CAAC,QAAQ,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE;EACjE,UAAU,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC9C,SAAS;EACT,OAAO,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE;EACtC,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,UAAU,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;EAC1C,YAAY,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;EACpC,YAAY,MAAM;EAClB,WAAW;EACX,SAAS;EACT,OAAO,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE;EACtC,QAAQ,MAAM,GAAG,SAAS,CAAC;EAC3B,OAAO;EACP,MAAM,IAAI,CAAC,MAAM,EAAE;EACnB,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,qBAAqB,EAAE,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC;EACnF,OAAO;EACP,KAAK,MAAM;EACX,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACnD,QAAQ,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;EACxC,UAAU,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;EAClC,UAAU,MAAM;EAChB,SAAS;EACT,OAAO;EACP,MAAM,IAAI,CAAC,MAAM,EAAE;EACnB,QAAQ,MAAM,GAAG,SAAS,CAAC;EAC3B,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;EACpB,MAAM,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;EAC9B,KAAK;EACL,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;EACzB,GAAG;EAQH,EAAE,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE;EACjC,IAAI,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;EACvC,MAAM,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;EAClD,KAAK;EACL,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;EACzF,MAAM,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;EACzD,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE;EAC7B,MAAM,MAAM,SAAS,GAAGc,YAAO,CAAC,MAAM,EAAE,qCAAqC,CAAC,QAAQ,CAAC,CAAC,CAAC;EACzF,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EACnC,MAAM,OAAO,SAAS,CAAC;EACvB,KAAK;EAEL,IAAI,MAAM,GAAG,OAAO,MAAM,KAAK,UAAU,GAAG,MAAM,CAAC,QAAQ,EAAE,GAAG,MAAM,CAAC;EACvE,IAAI,MAAM,iBAAiB,GAAG,EAAE,CAAC;EACjC,IAAI,MAAM,YAAY,GAAG,qCAAqC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;EAE/E,IAAI,IAAI,QAAQ,IAAI,OAAO,QAAQ,CAAC,aAAa,KAAK,QAAQ,EAAE;EAChE,MAAM,YAAY,CAAC,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,YAAY,IAAI,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC;EACjI,KAAK;EAEL,IAAI,SAAS,iBAAiB,CAAC,IAAI,EAAE;EACrC,MAAM,MAAM,cAAc,GAAG,IAAI,SAAS,CAAC,MAAM,EAAE;EACnD,QAAQ,aAAa,EAAE,SAAS,CAAC,aAAa;EAC9C,QAAQ,aAAa,EAAE,SAAS,CAAC,aAAa;EAC9C,QAAQ,SAAS,EAAE,SAAS,CAAC,SAAS;EACtC,QAAQ,iBAAiB,EAAE,SAAS,CAAC,iBAAiB;EACtD,QAAQ,SAAS,EAAE,SAAS,CAAC,SAAS;EACtC,QAAQ,aAAa,EAAE,SAAS,CAAC,aAAa;EAC9C,QAAQ,eAAe,EAAE,SAAS,CAAC,gBAAgB;EACnD,QAAQ,MAAM,EAAE,SAAS,CAAC,MAAM;EAChC,QAAQ,SAAS,EAAE,SAAS,CAAC,SAAS;EACtC,QAAQ,QAAQ,EAAE,SAAS,CAAC,QAAQ;EACpC,QAAQ,SAAS,EAAE,SAAS,CAAC,SAAS;EACtC,QAAQ,mBAAmB,EAAE,SAAS,CAAC,mBAAmB;EAC1D,QAAQ,0BAA0B,EAAE,SAAS,CAAC,0BAA0B;EACxE,QAAQ,SAAS,EAAE,SAAS,CAAC,SAAS;EACtC,QAAQ,eAAe,EAAE,SAAS,CAAC,eAAe;EAClD,QAAQ,cAAc,EAAE,SAAS,CAAC,cAAc;EAChD,QAAQ,UAAU,EAAE,SAAS,CAAC,UAAU;EACxC,QAAQ,cAAc,EAAE,SAAS,CAAC,cAAc;EAChD,QAAQ,KAAK,EAAE,SAAS,CAAC,KAAK;EAC9B,QAAQ,YAAY,EAAE,SAAS,CAAC,YAAY;EAC5C,OAAO,CAAC,CAAC;EACT,MAAM,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;EACvD,MAAM,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;EACpE,MAAM,SAAS,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;EAC9C,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK;EAEL,IAAI,SAAS,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE;EACjD,MAAM,MAAM,aAAa,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACnD,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC5C,QAAQ,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;EAC5B,QAAQ,MAAM,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;EAC7C,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE;EACtB,UAAU,aAAa,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;EACtC,SAAS,MAAM;EACf,UAAU,QAAQ,IAAI;EACtB,YAAY,KAAK,QAAQ,CAAC;EAC1B,YAAY,KAAK,SAAS,CAAC;EAC3B,YAAY,KAAK,OAAO,CAAC;EACzB,YAAY,KAAK,iBAAiB;EAClC,cAAc,aAAa,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;EACtD,cAAc,MAAM;EACpB,YAAY;EACZ,cAAc,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;EACtC,WAAW;EACX,SAAS;EACT,OAAO;EACP,MAAM,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAChD,MAAM,MAAM,cAAc,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;EAC1D,MAAM,IAAI,cAAc,EAAE;EAC1B,QAAQ,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;EACvD,QAAQ,IAAI,cAAc,CAAC,aAAa,EAAE;EAC1C,UAAU,OAAO,cAAc,CAAC,aAAa,EAAE,CAAC;EAChD,SAAS,MAAM;EACf,UAAU,OAAO,cAAc,CAAC,YAAY,EAAE,CAAC;EAC/C,SAAS;EACT,OAAO;EAEP,MAAM,MAAM,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC,GAAG,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE;EACtF,QAAQ,aAAa;EACrB,QAAQ,aAAa,EAAE,MAAM,CAAC,aAAa;EAC3C,QAAQ,SAAS,EAAE,MAAM,CAAC,SAAS;EACnC,QAAQ,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;EACnD,QAAQ,SAAS,EAAE,MAAM,CAAC,SAAS;EACnC,QAAQ,aAAa,EAAE,MAAM,CAAC,aAAa;EAC3C,QAAQ,eAAe,EAAE,MAAM,CAAC,gBAAgB;EAChD,QAAQ,OAAO,EAAE,MAAM,CAAC,OAAO;EAC/B,QAAQ,MAAM,EAAE,MAAM,CAAC,MAAM;EAC7B,QAAQ,MAAM,EAAE,MAAM,CAAC,MAAM;EAC7B,QAAQ,SAAS,EAAE,MAAM,CAAC,SAAS;EACnC,QAAQ,QAAQ,EAAE,MAAM,CAAC,QAAQ;EACjC,QAAQ,SAAS,EAAE,MAAM,CAAC,SAAS;EACnC,QAAQ,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;EACvD,QAAQ,0BAA0B,EAAE,MAAM,CAAC,0BAA0B;EACrE,QAAQ,SAAS,EAAE,MAAM,CAAC,SAAS;EACnC,QAAQ,eAAe,EAAE,MAAM,CAAC,eAAe;EAC/C,QAAQ,cAAc,EAAE,MAAM,CAAC,cAAc;EAC7C,QAAQ,UAAU,EAAE,MAAM,CAAC,UAAU;EACrC,QAAQ,cAAc,EAAE,MAAM,CAAC,cAAc;EAC7C,QAAQ,KAAK,EAAE,MAAM,CAAC,KAAK;EAC3B,QAAQ,GAAG,EAAE,MAAM,CAAC,GAAG;EACvB,QAAQ,QAAQ;EAChB,QAAQ,YAAY,EAAE,MAAM,CAAC,YAAY;EACzC,QAAQ,UAAU,EAAE,MAAM,CAAC,UAAU;EACrC,QAAQ,iBAAiB;EACzB,QAAQ,qBAAqB;EAC7B,OAAO,CAAC,CAAC;EACT,MAAM,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;EAC7C,MAAM,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;EAC3C,MAAM,SAAS,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;EACzC,MAAM,IAAI,SAAS,CAAC,aAAa,EAAE;EACnC,QAAQ,OAAO,SAAS,CAAC,aAAa,EAAE,CAAC;EACzC,OAAO,MAAM;EACb,QAAQ,OAAO,SAAS,CAAC,YAAY,EAAE,CAAC;EACxC,OAAO;EACP,KAAK;EACL,IAAI,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;EACzC,MAAM,OAAO,EAAE,IAAI,CAAC,OAAO;EAC3B,MAAM,MAAM,EAAE,IAAI,CAAC,MAAM;EACzB,MAAM,SAAS,EAAE,IAAI,CAAC,SAAS;EAC/B,MAAM,eAAe,EAAE,IAAI,CAAC,eAAe;EAC3C,MAAM,cAAc,EAAE,IAAI,CAAC,cAAc;EACzC,MAAM,GAAG,EAAE,IAAI;EACf,MAAM,QAAQ;EACd,MAAM,iBAAiB;EACvB,MAAM,qBAAqB;EAC3B,KAAK,EAAE,YAAY,CAAC,CAAC;EAErB,IAAI,MAAM,SAAS,GAAG,iBAAiB,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC;EAGjF,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;EACtB,MAAM,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;EACrC,KAAK;EAGL,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;EACvB,MAAM,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC;EACvC,KAAK;EAEL,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EAEjC,IAAI,OAAO,SAAS,CAAC;EACrB,GAAG;EAgCH,EAAE,eAAe,GAAG;EACpB,IAAI,IAAI,EAAE,CAAC;EACX,IAAI,IAAI,QAAQ,CAAC;EACjB,IAAI,IAAI,OAAO,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,UAAU,EAAE;EAC/D,MAAM,EAAE,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;EAC3C,MAAM,QAAQ,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;EACjD,KAAK,MAAM;EACX,MAAM,EAAE,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;EAC3C,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE;EAC7B,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE;EACvE,QAAQ,IAAI,IAAI,CAAC,IAAI,IAAI,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;EAC7D,UAAU,MAAM,IAAI,KAAK,CAAC,CAAC,2BAA2B,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC5E,SAAS;EACT,OAAO;EACP,KAAK;EAEL,IAAI,MAAM,YAAY,GAAG,qCAAqC,CAAC,QAAQ,CAAC,CAAC;EAEzE,IAAI,IAAI,QAAQ,IAAI,OAAO,QAAQ,CAAC,aAAa,KAAK,QAAQ,EAAE;EAChE,MAAM,YAAY,CAAC,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,YAAY,IAAI,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC;EACjI,KAAK;EAEL,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE;EACrC,MAAM,YAAY,CAAC,UAAU,GAAG,EAAE,CAAC;EACnC,MAAM,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;EACrC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACjD,QAAQ,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;EAC/C,QAAQ,MAAM,IAAI,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;EACvD,QAAQ,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC;EACrC,UAAU,IAAI;EACd,UAAU,MAAM;EAChB,UAAU,QAAQ,EAAE,CAAC;EACrB,SAAS,CAAC,CAAC;EACX,OAAO;EACP,KAAK,MAAM;EACX,MAAM,YAAY,CAAC,UAAU,GAAG,EAAE,CAAC;EACnC,MAAM,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;EACrC,MAAM,KAAK,IAAI,CAAC,IAAI,SAAS,EAAE;EAC/B,QAAQ,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS;EACnD,QAAQ,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;EAC/C,QAAQ,MAAM,IAAI,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;EACvD,QAAQ,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC;EACrC,UAAU,IAAI,EAAE,IAAI,IAAI,CAAC;EACzB,UAAU,MAAM;EAChB,UAAU,QAAQ,EAAE,CAAC;EACrB,SAAS,CAAC,CAAC;EACX,OAAO;EACP,KAAK;EACL,IAAI,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;EAEvD,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAuBH,EAAE,cAAc,GAAG;EACnB,IAAI,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;EACrC,IAAI,MAAM,cAAc,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;EAC3D,IAAI,IAAI,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,KAAK,KAAK,EAAE,OAAO,cAAc,CAAC;EAC7E,IAAI,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;EACvC,IAAI,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;EACzC,IAAI,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;EACrC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE;EAClC,MAAM,SAAS,CAAC,CAAC,CAAC;EAClB,SAAS,SAAS,CAAC,MAAM,CAAC;EAC1B,SAAS,UAAU,CAAC,OAAO,CAAC;EAC5B,SAAS,WAAW,CAAC,IAAI,CAAC,CAAC;EAC3B,KAAK;EAEL,IAAI,OAAO,WAAW;EACtB,MAAM,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;EAC5D,MAAM,IAAI,OAAO,CAAC,OAAO,EAAE;EAC3B,QAAQ,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;EACjC,OAAO;EACP,MAAM,OAAO,OAAO,CAAC;EACrB,KAAK,CAAC;EACN,GAAG;EAQH,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE;EAChC,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;EAC/D,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EASH,EAAE,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE;EAC5C,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;EACjC,MAAM,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;EAChG,KAAK;EACL,IAAI,QAAQ,GAAG,QAAQ,IAAI,EAAE,CAAC;EAC9B,IAAI,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;EAC/F,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;EAC9B,MAAM,IAAI;EACV,MAAM,MAAM;EACZ,MAAM,QAAQ;EACd,MAAM,aAAa;EACnB,MAAM,aAAa;EACnB,MAAM,UAAU,EAAE,QAAQ,CAAC,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC,wBAAwB,CAAC,MAAM,CAAC;EACrF,KAAK,CAAC,CAAC;EACP,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,YAAY,CAAC,MAAM,EAAE;EACvB,IAAI,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC;EACjC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAKH,EAAE,OAAO,GAAG;EACZ,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO;EAG9B,IAAI,UAAU,CAAC,MAAM;EACrB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACpD,QAAQ,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EACtC,OAAO;EAEP,MAAM,IAAI,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;EACxC,MAAM,IAAI,WAAW,EAAE;EAEvB,QAAQ,IAAI,WAAW,CAAC,MAAM,EAAE;EAChC,UAAU,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC;EAC3C,SAAS;EACT,QAAQ,IAAI,WAAW,CAAC,WAAW,CAAC,cAAc,EAAE;EACpD,UAAU,WAAW,CAAC,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC/D,SAAS;EACT,OAAO;EACP,KAAK,EAAE,CAAC,CAAC,CAAC;EACV,GAAG;EACH,CAAC;EAED,SAAS,qCAAqC,CAAC,QAAQ,EAAE;EACzD,EAAE,IAAI,CAAC,QAAQ,EAAE;EACjB,IAAI,OAAO,EAAE,CAAC;EACd,GAAG;EACH,EAAE,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;EAEvD,EAAE,IAAI,QAAQ,CAAC,cAAc,CAAC,aAAa,CAAC,EAAE;EAC9C,IAAI,cAAc,CAAC,SAAS,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;EAC1D,IAAI,gBAAgB,CAAC,SAAS,GAAG,QAAQ,CAAC,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC;EAC9E,GAAG;EACH,EAAE,IAAI,QAAQ,CAAC,cAAc,CAAC,iBAAiB,CAAC,EAAE;EAClD,IAAI,cAAc,CAAC,SAAS,EAAE,iBAAiB,EAAE,UAAU,CAAC,CAAC;EAC7D,IAAI,gBAAgB,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;EAClE,GAAG;EACH,EAAE,IAAI,QAAQ,CAAC,cAAc,CAAC,iBAAiB,CAAC,EAAE;EAClD,IAAI,cAAc,CAAC,SAAS,EAAE,iBAAiB,EAAE,WAAW,CAAC,CAAC;EAC9D,IAAI,gBAAgB,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;EACnE,GAAG;EACH,EAAE,IAAI,QAAQ,CAAC,cAAc,CAAC,eAAe,CAAC,EAAE;EAChD,IAAI,cAAc,CAAC,SAAS,EAAE,eAAe,EAAE,qBAAqB,CAAC,CAAC;EACtE,IAAI,gBAAgB,CAAC,mBAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;EAC3E,GAAG;EACH,EAAE,OAAO,gBAAgB,CAAC;EAC1B,CAAC;;ECzjBM,SAAS,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE;EACpC,EAAE,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;EACrC,EAAE,OAAO,IAAI,QAAQ,CAAC,CAAC,gBAAgB,GAAG,IAAI,EAAE,EAAE,GAAGd,OAAK,CAAC,0BAA0B,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;EAC1G,GAAGA,OAAK,CAAC,yBAAyB,CAAC,QAAQ,CAAC,EAAE;CAC/C,CAAC,CAAC,EAAE,CAAC;EACN,CAAC;;ECQD,MAAM,gBAAgB,SAAS,WAAW,CAAC;EAC3C,EAAE,WAAW,WAAW,GAAG,EAAE,OAAO,KAAK,EAAE;EAC3C,EAAE,OAAO,cAAc,GAAG,EAAE,OAAO,KAAK,EAAE;EAC1C,EAAE,OAAO,iBAAiB,GAAG,EAAE,OAAO,KAAK,EAAE;EAC7C,EAAE,OAAO,gBAAgB,GAAG,EAAE,OAAO,KAAK,EAAE;EAC5C,EAAE,OAAO,eAAe,GAAG,EAAE,OAAO,CAAC,EAAE;EACvC,EAAE,WAAW,UAAU,GAAG,EAAE,OAAO,IAAI,EAAE;EACzC,EAAE,WAAW,WAAW,GAAG,EAAE,OAAO,IAAI,EAAE;EAC1C,EAAE,WAAW,QAAQ,GAAG,EAAE,OAAO,IAAI,EAAE;EACvC,EAAE,OAAO,kBAAkB,GAAG,EAAE;EAChC,EAAE,OAAO,cAAc,GAAG,EAAE;EAC5B,EAAE,UAAU,GAAG,EAAE,OAAO,EAAE,EAAE;EAC5B,EAAE,WAAW,GAAG,EAAE,OAAO,IAAI,EAAE;EAC/B,EAAE,QAAQ,GAAG,EAAE,OAAO,EAAE,EAAE;EAC1B,EAAE,cAAc,GAAG,EAAE;EACrB,EAAE,KAAK,GAAG,EAAE;EACZ,EAAE,iBAAiB,GAAG,EAAE;EACxB,EAAE,SAAS,GAAG,EAAE;EAEhB,EAAE,OAAO,WAAW,GAAG;EACvB,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC;EACzB,MAAM,WAAW,EAAE,KAAK;EACxB,MAAM,yBAAyB,EAAE,KAAK;EACtC,MAAM,cAAc,EAAE,KAAK;EAC3B,MAAM,aAAa,EAAE,KAAK;EAC1B,MAAM,SAAS,EAAE,KAAK;EACtB,MAAM,YAAY,EAAE,CAAC;EACrB,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC,AAED,MAAM,GAAG,GAAG,GAAG,CAAC;EAChB,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;EAClB,GAAG,CAAC,eAAe,GAAG,eAAe,CAAC;EACtC,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC;EAC1B,GAAG,CAAC,eAAe,GAAG,eAAe,CAAC;EACtC,GAAG,CAAC,YAAY,GAAG,YAAY,CAAC;EAChC,GAAG,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;EACxC,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;EAClB,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;EAClB,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC;EACtB,GAAG,CAAC,KAAK,GAAG,EAAE,GAAG,MAAM,EAAE,GAAGA,OAAK,EAAE,CAAC;EACpC,GAAG,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;EAC5C,GAAG,CAAC,YAAY,GAAG,YAAY,CAAC;EAChC,GAAG,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;EAC1C,GAAG,CAAC,WAAW,GAAG,WAAW,CAAC;EAC9B,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;EACxB,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;;;;;;;;"} \ No newline at end of file diff --git a/dist/gpu-browser-core.min.js b/dist/gpu-browser-core.min.js index 1d3c6b6c..7cd8db25 100644 --- a/dist/gpu-browser-core.min.js +++ b/dist/gpu-browser-core.min.js @@ -1,14 +1,2 @@ -/** - * gpu.js - * http://gpu.rocks/ - * - * GPU Accelerated JavaScript - * - * @version 2.0.5 - * @date Fri Oct 11 2019 07:23:36 GMT-0400 (Eastern Daylight Time) - * - * @license MIT - * The MIT License - * - * Copyright (c) 2019 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(){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=m[e];return t?n+"."+t:e}function E(e){y=" ".repeat(e)}function _(e,t){const r=`${n}Variable${g.length}`;return l.push(`${y}const ${r} = ${t};`),g.push(e),r}function v(e){l.push(`${y}// ${e}`)}function D(){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 w(e,t){return`${n}.${e}(${s(t,{contextName:n,contextVariables:g,getEntity:S,addVariable:_,variables:c,onUnrecognizedArgumentLookup:p})})`}function $(e){const t=g.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(){switch(n){case"drawBuffersWEBGL":return c.push(`${p}${i}.drawBuffersWEBGL([${s(arguments[0],{contextName:i,contextVariables:o,getEntity:g,addVariable:x,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}${m(n,arguments)};`);case"number":case"boolean":l&&-1===o.indexOf(a(t))?(c.push(`${p}const ${i}Variable${o.length} = ${m(n,arguments)};`),o.push(t=a(t))):(c.push(`${p}const ${i}Variable${o.length} = ${m(n,arguments)};`),o.push(t));break;default:null===t?c.push(`${m(n,arguments)};`):c.push(`${p}const ${i}Variable${o.length} = ${m(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 g(e){return r.hasOwnProperty(e)?`${i}.${r[e]}`:u(e)}function m(e,t){return`${i}.${e}(${s(t,{contextName:i,contextVariables:o,getEntity:g,addVariable:x,variables:h,onUnrecognizedArgumentLookup:d})})`}function x(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=a(t),e.graphical&&s(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.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),e.setOptimizeFloatMemory=(()=>e),e.setArgumentTypes=(()=>e),e.setDebug=(()=>e),e.setLoopMaxIterations=(()=>e),e.setPipeline=(()=>e),e.setPrecision=(()=>e),e.setImmutable=(()=>e),e.setFunctions=(()=>e),e.addSubKernel=(()=>e),e.destroy=(()=>{}),e.validateSettings=(()=>{}),e.graphical&&e.output&&s(e),e}function s(e){const{x:t,y:n}=e.output;if(e.context&&e.context.createImageData){const r=new Uint8ClampedArray(t*n*4);e._imageData=e.context.createImageData(t,n),e._colorData=r}else{const r=new Uint8ClampedArray(t*n*4);e._imageData={data:r},e._colorData=r}}function a(e){let t=null;if(e.length)if(3===e.length){const[n,r,i]=e;t={x:n,y:r,z:i}}else if(2===e.length){const[n,r]=e;t={x:n,y:r}}else{const[n]=e;t={x:n}}else t=e;return t}t.exports={gpuMock:function(e,t={}){const n=t.output?a(t.output):null;function s(){return s.output.z?function(){const e=r(arguments),t=new Array(this.output.z);for(let n=0;n0&&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(","),this.astGeneric(n[e],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?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":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;default:throw this.astErrorOutput("Unexpected expression",e)}if(!e.computed)switch(r){case"Number":case"Integer":case"Float":case"Boolean":return t.push(`${l}_${u}`),t}const c=`${l}_${u}`;switch(r){case"Array(2)":case"Array(3)":case"Array(4)":case"HTMLImageArray":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":case"HTMLImage":default:let e,n;if("constants"===l){const t=this.constants[u];e=(n="Input"===this.constantTypes[u])?t.size:null}else e=(n=this.isInput(u))?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=e.elements.length;t.push("new Float32Array([");for(let r=0;r0&&t.push(", ");const n=e.elements[r];this.astGeneric(n,t)}return t.push("])"),t}astDebuggerStatement(e,t){return t.push("debugger;"),t}}}},{"../function-node":9}],6:[function(e,t,n){const{utils:r}=e("../../utils");t.exports={cpuKernelString:function(e,t){const n=[],i=[],s=[],a=!/^function/.test(e.color.toString());if(n.push(" const { context, canvas, constants: incomingConstants } = settings;",` const output = new Int32Array(${JSON.stringify(Array.from(e.output))});`,` const _constantTypes = ${JSON.stringify(e.constantTypes)};`,` const _constants = ${function(e,t){const n=[];for(const r in t){if(!t.hasOwnProperty(r))continue;const i=t[r],s=e[r];switch(i){case"Number":case"Integer":case"Float":case"Boolean":n.push(`${r}:${s}`);break;case"Array(2)":case"Array(3)":case"Array(4)":n.push(`${r}:new ${s.constructor.name}(${JSON.stringify(Array.from(s))})`)}}return`{ ${n.join()} }`}(e.constants,e.constantTypes)};`),i.push(" constants: _constants,"," context,"," output,"," thread: {x: 0, y: 0, z: 0},"),e.graphical){n.push(` const _imageData = context.createImageData(${e.output[0]}, ${e.output[1]});`),n.push(` const _colorData = new Uint8ClampedArray(${e.output[0]} * ${e.output[1]} * 4);`);const t=r.flattenFunctionToString((a?"function ":"")+e.color.toString(),{thisLookup:t=>{switch(t){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(e[t])},findDependency:(e,t)=>null}),o=r.flattenFunctionToString((a?"function ":"")+e.getPixels.toString(),{thisLookup:t=>{switch(t){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(e[t])},findDependency:()=>null});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 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":111}],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(){return null}static combineKernels(e){return e}constructor(e,t){super(e,t),this.mergeSettings(e.settings||t),this._imageData=null,this._colorData=null,this._kernelString=null,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.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)}}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._processConstants()}\n return (${this.argumentNames.map(e=>"user_"+e).join(", ")}) => {\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"HTMLImage":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("")}_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 ${n}(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 }`}_resultKernel2DLoop(e){const{output:t}=this,n=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 ${n}(outputX);\n ${this._mapSubKernels(e=>`const resultX_${e.name} = result_${e.name}[y] = new ${n}(outputX);\n`).join("")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }`}_graphicalKernel2DLoop(e){const{output:t}=this,n=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\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 ${this._mapSubKernels(e=>`const resultX_${e.name} = result_${e.name}[y] = new ${n}(outputX);\n`).join("")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }`}_resultKernel3DLoop(e){const{output:t}=this,n=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 ${n}(outputX);\n ${this._mapSubKernels(e=>`const resultX_${e.name} = resultY_${e.name}[y] = new ${n}(outputX);\n`).join(" ")}\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))}}}},{"../../utils":111,"../function-builder":8,"../kernel":34,"./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:g,optimizeFloatMemory:m,precision:x,plugins:f,source:y,subKernels:T,functions:b,leadingReturnStatement:A,followingReturnStatement:S,dynamicArguments:E,dynamicOutput:_,warnVarUsage:v}=e,D=new Array(i.length),w={};for(let e=0;eP.needsArgumentType(e,t),I=(e,t,n)=>{P.assignArgumentType(e,t,n)},R=(e,t,n)=>P.lookupReturnType(e,t,n),F=e=>P.lookupFunctionArgumentTypes(e),k=(e,t)=>P.lookupFunctionArgumentName(e,t),L=(e,t)=>P.lookupFunctionArgumentBitRatio(e,t),z=(e,t,n,r)=>{P.assignArgumentType(e,t,n,r)},O=(e,t,n,r)=>{P.assignArgumentBitRatio(e,t,n,r)},V=(e,t,n)=>{P.trackFunctionCall(e,t,n)},M=(e,n)=>{const r=[];for(let t=0;tnew t(e.source,{returnType:e.returnType,argumentTypes:e.argumentTypes,output:g,plugins:f,constants:l,constantTypes:w,constantBitRatios:c,optimizeFloatMemory:m,precision:x,lookupReturnType:R,lookupFunctionArgumentTypes:F,lookupFunctionArgumentName:k,lookupFunctionArgumentBitRatio:L,needsArgumentType:$,assignArgumentType:I,triggerImplyArgumentType:z,triggerImplyArgumentBitRatio:O,onFunctionCall:V,onNestedFunction:M})));let G=null;T&&(G=T.map(e=>{const{name:n,source:r}=e;return new t(r,Object.assign({},C,{name:n,isSubKernel:!0,isRootKernel:!1}))}));const P=new r({kernel:e,rootNode:K,functionNodes:U,nativeFunctions:d,subKernelNodes:G});return P}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.argumentChain=[],this.functionNodeDependencies={},this.functionCalls={},this.rootNode&&(this.functionMap.kernel=this.rootNode),this.functionNodes)for(let e=0;e-1)return-1===t.indexOf(e)&&t.push(e),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")&&"_"===e.object.name[0]?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.declarations=[],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":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","asin","atan","atan2","ceil","cos","exp","floor","log","log2","max","min","pow","random","round","sign","sin","sqrt","tan"].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":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;default:throw this.astErrorOutput(`Unhandled type ${e.type} in getDependencies`,e)}return t}getVariableSignature(e){if(!this.isAstVariable(e))throw new Error(`ast of type "${e.type}" is not a variable signature`);if("Identifier"===e.type)return"value";const t=[];for(;e;)e.computed?t.push("[]"):"ThisExpression"===e.type?t.unshift("this"):e.property&&e.property.name?"x"===e.property.name||"y"===e.property.name||"z"===e.property.name?t.unshift(".value"):"constants"===e.property.name||"thread"===e.property.name||"output"===e.property.name?t.unshift("."+e.property.name):t.unshift(".value"):e.name?t.unshift("value"):e.callee&&e.callee.name?t.unshift("fn()"):e.elements?t.unshift("[]"):t.unshift("unknown"),e=e.object;const n=t.join("");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 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;t0&&t.push(","),this.astGeneric(e.expressions,t);return t}astUnaryExpression(e,t){return this.checkAndUpconvertBitwiseUnary(e,t)?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{name:t=e.object.name,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{name:t=e.object.object.name,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{name:t=e.object.object.object.name,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{name:t=e.object.object.object.object.name,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{name:t=e.property.name,origin:"Math",type:"Number",signature:r};switch(e.property.name){case"r":case"g":case"b":case"a":return{name:t=e.object.name,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)))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)))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)))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)))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"[][]":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?this.runningContexts[this.runningContexts.length-1]:null}newContext(e){const t=Object.assign({},this.currentContext);this.contexts.push(t),this.runningContexts.push(t),e(),this.runningContexts.pop()}scan(e){if(e)if(Array.isArray(e))for(let t=0;t{this.scan(e.body)});break;case"AssignmentExpression":case"LogicalExpression":case"BinaryExpression":this.scan(e.left),this.scan(e.right);break;case"UpdateExpression":case"UnaryExpression":this.scan(e.argument);break;case"VariableDeclaration":this.scan(e.declarations);break;case"VariableDeclarator":const{currentContext:t}=this,n={ast:e,context:t,name:e.id.name,origin:"declaration",forceInteger:this.inLoopInit,assignable:!this.inLoopInit&&!t.hasOwnProperty(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":this.newContext(()=>{this.inLoopInit=!0,this.scan(e.init),this.inLoopInit=!1,this.scan(e.test),this.scan(e.update),this.newContext(()=>{this.scan(e.body)})});break;case"DoWhileStatement":case"WhileStatement":this.newContext(()=>{this.scan(e.body),this.scan(e.test)});break;case"Identifier":this.identifiers.push({context:this.currentContext,ast:e});break;case"ReturnStatement":this.returnStatements.push(e),this.scan(e.argument);break;case"MemberExpression":this.scan(e.object),this.scan(e.property);break;case"ExpressionStatement":this.scan(e.expression);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}"`)}}}}},{}],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){const n=e.toArray.toString(),r=!/^function/.test(n);return`() => {\n ${i.flattenFunctionToString(`${r?"function ":""}${n}`,{findDependency:(t,n)=>{if("utils"===t)return`const ${n} = ${i[n].toString()};`;if("this"===t)return`${r?"function ":""}${e[n].toString()}`;throw new Error("unhandled fromObject")},thisLookup:n=>{if("texture"===n)return t;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;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=r(n.context,{useTrackablePrimitives:!0,onReadPixels:e=>{if(L.subKernels){if(d){const t=L.subKernels[g++].property;h.push(` result${isNaN(t)?"."+t:`[${t}]`} = ${a(e,L)};`)}else h.push(` const result = { result: ${a(e,L)} };`),d=!0;g===L.subKernels.length&&h.push(" return result;")}else e?h.push(` return ${a(e,L)};`):h.push(" return null;")},onUnrecognizedArgumentLookup:e=>{const t=u(e,L.kernelArguments,[],p);if(t)return t;const n=u(e,L.kernelConstants,A?Object.keys(A).map(e=>A[e]):[],p);return n||null}});let d=!1,g=0;const{source:m,canvas:x,output:f,pipeline:y,graphical:T,loopMaxIterations:b,constants:A,optimizeFloatMemory:S,precision:E,fixIntegerDivisionAccuracy:_,functions:v,nativeFunctions:D,subKernels:w,immutable:$,argumentTypes:I,constantTypes:R,kernelArguments:F,kernelConstants:k}=n,L=new e(m,{canvas:x,context:p,checkContext:!1,output:f,pipeline:y,graphical:T,loopMaxIterations:b,constants:A,optimizeFloatMemory:S,precision:E,fixIntegerDivisionAccuracy:_,functions:v,nativeFunctions:D,subKernels:w,immutable:$,argumentTypes:I,constantTypes:R});let z=[];if(p.setIndent(2),L.build.apply(L,t),z.push(p.toString()),p.reset(),L.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"HTMLImage":case"HTMLVideo":p.insertVariable(`uploadValue_${e.name}`,e.uploadValue);break;case"HTMLImageArray":for(let r=0;re.varName).join(", ")}) {`),p.setIndent(4),L.run.apply(L,t),L.renderKernels?L.renderKernels():L.renderOutput&&L.renderOutput(),z.push(" /** start setup uploads for kernel values **/"),L.kernelArguments.forEach(e=>{z.push(" "+e.getStringValueHandler().split("\n").join("\n "))}),z.push(" /** end setup uploads for kernel values **/"),z.push(p.toString()),L.renderOutput===L.renderTexture){p.reset();const e=L.renderKernels(),t=p.getContextVariableName(L.outputTexture);z.push(` return {\n result: {\n texture: ${t},\n type: '${e.result.type}',\n toArray: ${o(e.result,t)}\n },`);const{subKernels:n,subKernelOutputTextures:r}=L;for(let t=0;t"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}`)}})}(L)),z.push(" innerKernel.getPixels = getPixels;")),z.push(" return innerKernel;");let O=[];return k.forEach(e=>{O.push(`${e.getStringValueHandler()}`)}),`function kernel(settings) {\n const { context, constants } = settings;\n ${O.join("")}\n ${l||""}\n${z.join("\n")}\n}`}}},{"../../utils":111,"gl-wiretap":2}],12:[function(e,t,n){const{Kernel:r}=e("../kernel"),{Texture:i}=e("../../texture"),{utils:s}=e("../../utils"),{GLTextureArray2Float:a}=e("./texture/array-2-float"),{GLTextureArray2Float2D:o}=e("./texture/array-2-float-2d"),{GLTextureArray2Float3D:u}=e("./texture/array-2-float-3d"),{GLTextureArray3Float:l}=e("./texture/array-3-float"),{GLTextureArray3Float2D:c}=e("./texture/array-3-float-2d"),{GLTextureArray3Float3D:h}=e("./texture/array-3-float-3d"),{GLTextureArray4Float:p}=e("./texture/array-4-float"),{GLTextureArray4Float2D:d}=e("./texture/array-4-float-2d"),{GLTextureArray4Float3D:g}=e("./texture/array-4-float-3d"),{GLTextureFloat:m}=e("./texture/float"),{GLTextureFloat2D:x}=e("./texture/float-2d"),{GLTextureFloat3D:f}=e("./texture/float-3d"),{GLTextureMemoryOptimized:y}=e("./texture/memory-optimized"),{GLTextureMemoryOptimized2D:T}=e("./texture/memory-optimized-2d"),{GLTextureMemoryOptimized3D:b}=e("./texture/memory-optimized-3d"),{GLTextureUnsigned:A}=e("./texture/unsigned"),{GLTextureUnsigned2D:S}=e("./texture/unsigned-2d"),{GLTextureUnsigned3D:E}=e("./texture/unsigned-3d"),{GLTextureGraphical:_}=e("./texture/graphical");const v=Object.freeze({PackedPixelToUint8Array:Symbol("PackedPixelToUint8Array"),PackedPixelToFloat:Symbol("PackedPixelToFloat"),PackedPixelTo2DFloat:Symbol("PackedPixelTo2DFloat"),PackedPixelTo3DFloat:Symbol("PackedPixelTo3DFloat"),PackedTexture:Symbol("PackedTexture"),FloatPixelToFloat32Array:Symbol("FloatPixelToFloat32Array"),FloatPixelToFloat:Symbol("FloatPixelToFloat"),FloatPixelTo2DFloat:Symbol("FloatPixelTo2DFloat"),FloatPixelTo3DFloat:Symbol("FloatPixelTo3DFloat"),FloatPixelToArray2:Symbol("FloatPixelToArray2"),FloatPixelTo2DArray2:Symbol("FloatPixelTo2DArray2"),FloatPixelTo3DArray2:Symbol("FloatPixelTo3DArray2"),FloatPixelToArray3:Symbol("FloatPixelToArray3"),FloatPixelTo2DArray3:Symbol("FloatPixelTo2DArray3"),FloatPixelTo3DArray3:Symbol("FloatPixelTo3DArray3"),FloatPixelToArray4:Symbol("FloatPixelToArray4"),FloatPixelTo2DArray4:Symbol("FloatPixelTo2DArray4"),FloatPixelTo3DArray4:Symbol("FloatPixelTo3DArray4"),FloatTexture:Symbol("FloatTexture"),MemoryOptimizedFloatPixelToMemoryOptimizedFloat:Symbol("MemoryOptimizedFloatPixelToFloat"),MemoryOptimizedFloatPixelToMemoryOptimized2DFloat:Symbol("MemoryOptimizedFloatPixelTo2DFloat"),MemoryOptimizedFloatPixelToMemoryOptimized3DFloat:Symbol("MemoryOptimizedFloatPixelTo3DFloat")}),D={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 get testCanvas(){throw new Error(`"testCanvas" not defined on ${this.name}`)}static get testContext(){throw new Error(`"testContext" not defined on ${this.name}`)}static get features(){throw new Error(`"features" not defined on ${this.name}`)}static setupFeatureChecks(){throw new Error(`"setupFeatureChecks" not defined on ${this.name}`)}setFixIntegerDivisionAccuracy(e){return this.fixIntegerDivisionAccuracy=e,this}setPrecision(e){return this.precision=e,this}setFloatTextures(e){return s.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(D[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 D[e.match(/int|float|vec[2-4]/)[0]]}static combineKernels(e,t){e.apply(null,arguments);const{texSize:n,context:r,threadDim:i}=t.texSize;let a;if("single"===t.precision){const e=n[0],t=Math.ceil(n[1]/4);a=new Float32Array(e*t*4*4),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)}return a=a.subarray(0,i[0]*i[1]*i[2]),1===t.output.length?a:2===t.output.length?s.splitArray(a,t.output[0]):3===t.output.length?s.splitArray(a,t.output[0]*t.output[1]).map(function(e){return s.splitArray(e,t.output[0])}):void 0}constructor(e,t){super(e,t),this.transferValues=null,this.formatValues=null,this.TextureConstructor=null,this.renderOutput=null,this.renderRawOutput=null,this.texSize=null,this.translatedSource=null,this.renderStrategy=null,this.compiledFragmentShader=null,this.compiledVertexShader=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=_,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=E,this.renderStrategy=v.PackedPixelTo3DFloat,null):this.output[1]>0?(this.TextureConstructor=S,this.renderStrategy=v.PackedPixelTo2DFloat,null):(this.TextureConstructor=A,this.renderStrategy=v.PackedPixelToFloat,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=E,this.renderStrategy=v.PackedPixelTo3DFloat,this.formatValues=s.erect3DPackedFloat,null):this.output[1]>0?(this.TextureConstructor=S,this.renderStrategy=v.PackedPixelTo2DFloat,this.formatValues=s.erect2DPackedFloat,null):(this.TextureConstructor=A,this.renderStrategy=v.PackedPixelToFloat,this.formatValues=s.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.renderStrategy=v.FloatTexture,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=T,null):(this.TextureConstructor=y,null):this.output[2]>0?(this.TextureConstructor=f,null):this.output[1]>0?(this.TextureConstructor=x,null):(this.TextureConstructor=m,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=u,null):this.output[1]>0?(this.TextureConstructor=o,null):(this.TextureConstructor=a,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=h,null):this.output[1]>0?(this.TextureConstructor=c,null):(this.TextureConstructor=l,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=g,null):this.output[1]>0?(this.TextureConstructor=d,null):(this.TextureConstructor=p,null)}if(this.renderOutput=this.renderValues,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToArrays),this.optimizeFloatMemory)switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=b,this.renderStrategy=v.MemoryOptimizedFloatPixelToMemoryOptimized3DFloat,this.formatValues=s.erectMemoryOptimized3DFloat,null):this.output[1]>0?(this.TextureConstructor=T,this.renderStrategy=v.MemoryOptimizedFloatPixelToMemoryOptimized2DFloat,this.formatValues=s.erectMemoryOptimized2DFloat,null):(this.TextureConstructor=y,this.renderStrategy=v.MemoryOptimizedFloatPixelToMemoryOptimizedFloat,this.formatValues=s.erectMemoryOptimizedFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=u,this.renderStrategy=v.FloatPixelTo3DArray2,this.formatValues=s.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=o,this.renderStrategy=v.FloatPixelTo2DArray2,this.formatValues=s.erect2DArray2,null):(this.TextureConstructor=a,this.renderStrategy=v.FloatPixelToArray2,this.formatValues=s.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=h,this.renderStrategy=v.FloatPixelTo3DArray3,this.formatValues=s.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=c,this.renderStrategy=v.FloatPixelTo2DArray3,this.formatValues=s.erect2DArray3,null):(this.TextureConstructor=l,this.renderStrategy=v.FloatPixelToArray3,this.formatValues=s.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=g,this.renderStrategy=v.FloatPixelTo3DArray4,this.formatValues=s.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=d,this.renderStrategy=v.FloatPixelTo2DArray4,this.formatValues=s.erect2DArray4,null):(this.TextureConstructor=p,this.renderStrategy=v.FloatPixelToArray4,this.formatValues=s.erectArray4,null)}else switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=f,this.renderStrategy=v.FloatPixelTo3DFloat,this.formatValues=s.erect3DFloat,null):this.output[1]>0?(this.TextureConstructor=x,this.renderStrategy=v.FloatPixelTo2DFloat,this.formatValues=s.erect2DFloat,null):(this.TextureConstructor=m,this.renderStrategy=v.FloatPixelToFloat,this.formatValues=s.erectFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=u,this.renderStrategy=v.FloatPixelTo3DArray2,this.formatValues=s.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=o,this.renderStrategy=v.FloatPixelTo2DArray2,this.formatValues=s.erect2DArray2,null):(this.TextureConstructor=a,this.renderStrategy=v.FloatPixelToArray2,this.formatValues=s.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=h,this.renderStrategy=v.FloatPixelTo3DArray3,this.formatValues=s.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=c,this.renderStrategy=v.FloatPixelTo2DArray3,this.formatValues=s.erect2DArray3,null):(this.TextureConstructor=l,this.renderStrategy=v.FloatPixelToArray3,this.formatValues=s.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=g,this.renderStrategy=v.FloatPixelTo3DArray4,this.formatValues=s.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=d,this.renderStrategy=v.FloatPixelTo2DArray4,this.formatValues=s.erect2DArray4,null):(this.TextureConstructor=p,this.renderStrategy=v.FloatPixelToArray4,this.formatValues=s.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 s.linesToString(this.getMainResultKernelNumberTexture())+s.linesToString(this.getMainResultSubKernelNumberTexture())}getMainResultArray2Texture(){return s.linesToString(this.getMainResultKernelArray2Texture())+s.linesToString(this.getMainResultSubKernelArray2Texture())}getMainResultArray3Texture(){return s.linesToString(this.getMainResultKernelArray3Texture())+s.linesToString(this.getMainResultSubKernelArray3Texture())}getMainResultArray4Texture(){return s.linesToString(this.getMainResultKernelArray4Texture())+s.linesToString(this.getMainResultSubKernelArray4Texture())}getFloatTacticDeclaration(){switch(this.tactic){case"speed":return"precision lowp float;\n";case"performance":return"precision highp float;\n";case"balanced":default:return"precision mediump float;\n"}}getIntTacticDeclaration(){switch(this.tactic){case"speed":return"precision lowp int;\n";case"performance":return"precision highp int;\n";case"balanced":default:return"precision mediump int;\n"}}getSampler2DTacticDeclaration(){switch(this.tactic){case"speed":return"precision lowp sampler2D;\n";case"performance":return"precision highp sampler2D;\n";case"balanced":default:return"precision mediump sampler2D;\n"}}getSampler2DArrayTacticDeclaration(){switch(this.tactic){case"speed":return"precision lowp sampler2DArray;\n";case"performance":return"precision highp sampler2DArray;\n";case"balanced":default:return"precision mediump sampler2DArray;\n"}}renderTexture(){return new this.TextureConstructor({texture:this.outputTexture,size:this.texSize,dimensions:this.threadDim,output:this.output,context:this.context})}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}readMemoryOptimizedFloatPixelsToFloat32Array(){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,i]=n,a=new Uint8Array(r*i*4);return t.readPixels(0,0,r,i,t.RGBA,t.UNSIGNED_BYTE,a),new Uint8ClampedArray((e?a:s.flipPixels(a,r,i)).buffer)}renderKernelsToArrays(){const e={result:this.renderOutput()};for(let t=0;t0&&this._setupSubOutputTextures()}return this}renderValues(){return this.formatValues(this.transferValues(),this.output[0],this.output[1],this.output[2])}},renderStrategy:v}},{"../../texture":110,"../../utils":111,"../kernel":34,"./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":28,"./texture/memory-optimized-2d":26,"./texture/memory-optimized-3d":27,"./texture/unsigned":31,"./texture/unsigned-2d":29,"./texture/unsigned-3d":30}],13:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureArray2Float2D:class extends i{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return r.erect2DArray2(this.renderValues(),this.output[0],this.output[1])}}}},{"../../../utils":111,"./float":24}],14:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureArray2Float3D:class extends i{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return r.erect3DArray2(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}},{"../../../utils":111,"./float":24}],15:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureArray2Float:class extends i{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return r.erectArray2(this.renderValues(),this.output[0],this.output[1])}}}},{"../../../utils":111,"./float":24}],16:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureArray3Float2D:class extends i{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return r.erect2DArray3(this.renderValues(),this.output[0],this.output[1])}}}},{"../../../utils":111,"./float":24}],17:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureArray3Float3D:class extends i{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return r.erect3DArray3(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}},{"../../../utils":111,"./float":24}],18:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureArray3Float:class extends i{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return r.erectArray3(this.renderValues(),this.output[0])}}}},{"../../../utils":111,"./float":24}],19:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureArray4Float2D:class extends i{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return r.erect2DArray4(this.renderValues(),this.output[0],this.output[1])}}}},{"../../../utils":111,"./float":24}],20:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureArray4Float3D:class extends i{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return r.erect3DArray4(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}},{"../../../utils":111,"./float":24}],21:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureArray4Float:class extends i{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return r.erectArray4(this.renderValues(),this.output[0])}}}},{"../../../utils":111,"./float":24}],22:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureFloat2D:class extends i{constructor(e){super(e),this.type="ArrayTexture(1)"}toArray(){return r.erect2DFloat(this.renderValues(),this.output[0],this.output[1])}}}},{"../../../utils":111,"./float":24}],23:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureFloat3D:class extends i{constructor(e){super(e),this.type="ArrayTexture(1)"}toArray(){return r.erect3DFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}},{"../../../utils":111,"./float":24}],24:[function(e,t,n){const{utils:r}=e("../../../utils"),{Texture:i}=e("../../../texture");t.exports={GLTextureFloat:class extends i{constructor(e){super(e),this.type="ArrayTexture(1)"}renderRawOutput(){const{context:e}=this,t=e.createFramebuffer();e.bindFramebuffer(e.FRAMEBUFFER,t),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture,0);const n=new Float32Array(this.size[0]*this.size[1]*4);return e.readPixels(0,0,this.size[0],this.size[1],e.RGBA,e.FLOAT,n),n}renderValues(){return this.renderRawOutput()}toArray(){return r.erectFloat(this.renderValues(),this.output[0])}}}},{"../../../texture":110,"../../../utils":111}],25:[function(e,t,n){const{GLTextureUnsigned:r}=e("./unsigned");t.exports={GLTextureGraphical:class extends r{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return this.renderValues()}}}},{"./unsigned":31}],26:[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":111,"./float":24}],27:[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":111,"./float":24}],28:[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":111,"./float":24}],29:[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":111,"./unsigned":31}],30:[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":111,"./unsigned":31}],31:[function(e,t,n){const{utils:r}=e("../../../utils"),{Texture:i}=e("../../../texture");t.exports={GLTextureUnsigned:class extends i{constructor(e){super(e),this.type="NumberTexture"}renderRawOutput(){const{context:e}=this,t=e.createFramebuffer();e.bindFramebuffer(e.FRAMEBUFFER,t),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture,0);const n=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,n),n}renderValues(){return new Float32Array(this.renderRawOutput().buffer)}toArray(){return r.erectPackedFloat(this.renderValues(),this.output[0])}}}},{"../../../texture":110,"../../../utils":111}],32:[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?a:(this.setupFeatureChecks(),a=null!==u)}static setupFeatureChecks(){if(o=null,l=null,"function"==typeof r)try{if(!(u=r(2,2,{preserveDrawingBuffer:!0}))||!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")},c=this.getFeatures()}catch(e){console.warn(e)}}static isContextMatch(e){try{return"ANGLE"===e.getParameter(e.RENDERER)}catch(e){return!1}}static getFeatures(){const e=this.getIsDrawBuffers();return Object.freeze({isFloatRead:this.getIsFloatRead(),isIntegerDivisionAccurate:this.getIsIntegerDivisionAccurate(),isTextureFloat:this.getIsTextureFloat(),isDrawBuffers:e,kernelMap:e,channelCount:this.getChannelCount(),maxTextureSize:this.getMaxTextureSize()})}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){super.setOutput(e),this.graphical&&this.extensions.STACKGL_resize_drawingbuffer&&this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0],this.maxTexSize[1])}}}},{"../gl/kernel-string":11,"../web-gl/kernel":67,gl:1}],33:[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(!h)throw new Error("tactic 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.id=`${this.origin}_${n}`,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}getSource(){throw new Error(`"getSource" not defined on ${this.constructor.name}`)}updateValue(e){throw new Error(`"updateValue" not defined on ${this.constructor.name}`)}}}},{}],34:[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="balanced",this.plugins=null,this.returnType=null,this.leadingReturnStatement=null,this.followingReturnStatement=null,this.optimizeFloatMemory=null,this.strictIntegers=!1,this.fixIntegerDivisionAccuracy=null,this.warnVarUsage=!0}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":if("function"==typeof e.functions[0]){this.functions=e.functions.map(e=>r.functionToIFunction(e));continue}break;case"graphical":e[t]&&!e.hasOwnProperty("precision")&&(this.precision="unsigned"),this[t]=e[t];continue}this[t]=e[t]}this.canvas||(this.canvas=this.initCanvas()),this.context||(this.context=this.initContext()),this.plugins||(this.plugins=this.initPlugins(e))}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(e){throw new Error(`"initPlugins" not defined on ${this.constructor.name}`)}setupArguments(e){if(this.kernelArguments=[],this.argumentTypes)for(let e=0;er.functionToIFunction(e)):this.functions=e,this}setNativeFunctions(e){return this.nativeFunctions=e,this}setInjectedNative(e){return this.injectedNative=e,this}setPipeline(e){return this.pipeline=e,this}setPrecision(e){return this.precision=e,this}setOutputToTexture(e){return r.warnDeprecated("method","setOutputToTexture","setPipeline"),this.pipeline=e,this}setImmutable(e){return this.immutable=e,this}setCanvas(e){return this.canvas=e,this}setStrictIntegers(e){return this.strictIntegers=e,this}setDynamicOutput(e){return this.dynamicOutput=e,this}setHardcodeConstants(e){return r.warnDeprecated("method","setHardcodeConstants"),this.setDynamicOutput(e),this.setDynamicArguments(e),this}setDynamicArguments(e){return this.dynamicArguments=e,this}setUseLegacyEncoder(e){return this.useLegacyEncoder=e,this}setWarnVarUsage(e){return this.warnVarUsage=e,this}getCanvas(){return r.warnDeprecated("method","getCanvas"),this.canvas}getWebGl(){return r.warnDeprecated("method","getWebGl"),this.context}setContext(e){return this.context=e,this}setArgumentTypes(e){if(Array.isArray(e))this.argumentTypes=e;else{this.argumentTypes=[];for(const t in e){const n=this.argumentNames.indexOf(t);if(-1===n)throw new Error(`unable to find argument ${t}`);this.argumentTypes[n]=e[t]}}return this}setTactic(e){return this.tactic=e,this}requestFallback(e){if(!this.onRequestFallback)throw new Error(`"onRequestFallback" not defined on ${this.constructor.name}`);return this.fallbackRequested=!0,this.onRequestFallback(e)}validateSettings(){throw new Error(`"validateSettings" not defined on ${this.constructor.name}`)}addSubKernel(e){if(null===this.subKernels&&(this.subKernels=[]),!e.source)throw new Error('subKernel missing "source" property');if(!e.property&&isNaN(e.property))throw new Error('subKernel missing "property" property');if(!e.name)throw new Error('subKernel missing "name" property');return this.subKernels.push(e),this}destroy(e){throw new Error(`"destroy" called on ${this.constructor.name}`)}getBitRatio(e){if("single"===this.precision)return 4;if(Array.isArray(e[0]))return this.getBitRatio(e[0]);if(e.constructor===i)return this.getBitRatio(e.value);switch(e.constructor){case Uint8ClampedArray:case Uint8Array:case Int8Array:return 1;case Uint16Array:case Int16Array:return 2;case Float32Array:case Int32Array:default:return 4}}getPixels(){throw new Error(`"getPixels" called on ${this.constructor.name}`)}checkOutput(){if(!this.output||!r.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 e=0;ee.name):null,returnType:this.returnType}}}}}},{"../input":107,"../utils":111}],35:[function(e,t,n){t.exports={fragmentShader:"__HEADER__;\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nconst int LOOP_MAX = __LOOP_MAX__;\n\n__PLUGINS__;\n__CONSTANTS__;\n\nvarying vec2 vTexCoord;\n\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\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}"}},{}],36:[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",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",HTMLImage:"sampler2D",HTMLImageArray:"sampler2DArray"},a={"===":"==","!==":"!="};t.exports={WebGLFunctionNode:class extends i{constructor(e,t){super(e,t),t&&t.hasOwnProperty("fixIntegerDivisionAccuracy")&&(this.fixIntegerDivisionAccuracy=t.fixIntegerDivisionAccuracy)}astFunction(e,t){if(this.isRootKernel)t.push("void");else{this.returnType||this.findLastReturn()&&(this.returnType=this.getType(e.body),"LiteralInteger"===this.returnType&&(this.returnType="Number"));const{returnType:n}=this;if(n){const e=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 i=this.argumentTypes[this.argumentNames.indexOf(r)];if(!i)throw this.astErrorOutput(`Unknown argument ${r} type`,e);"LiteralInteger"===i&&(this.argumentTypes[n]=i="Number");const a=s[i];if(!a)throw this.astErrorOutput("Unexpected expression",e);"sampler2D"===a||"sampler2DArray"===a?t.push(`${a} user_${r},ivec2 user_${r}Size,ivec3 user_${r}Dim`):t.push(`${a} user_${r}`)}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=[];if(this.astGeneric(e.right,n),"Integer"!==this.getType(e.right))throw this.astErrorOutput("Unhandled binary expression with literal",e);t.push(n.join(""))}else t.push("int("),this.astGeneric(e.right,t),t.push(")");this.popState("casting-to-integer"),this.popState("building-integer");break;case"Integer & LiteralInteger":this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.castLiteralToInteger(e.right,t),this.popState("building-integer");break;case"Number & 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.isState("in-for-loop-test")?(this.pushState("building-integer"),t.push("int("),this.astGeneric(e.left,t),t.push(")"),t.push(a[e.operator]||e.operator),this.castLiteralToInteger(e.right,t),this.popState("building-integer")):(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("in-for-loop-test")||this.isState("in-for-loop-init")||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;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;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={"%":"mod","**":"pow"}[e.operator];if(!r)return null;switch(t.push(r),t.push("("),this.getType(e.left)){case"Integer":this.castValueToFloat(e.left,t);break;case"LiteralInteger":this.castLiteralToFloat(e.left,t);break;default:this.astGeneric(e.left,t)}switch(t.push(","),this.getType(e.right)){case"Integer":this.castValueToFloat(e.right,t);break;case"LiteralInteger":this.castLiteralToFloat(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseOperators(e,t){const n={"&":"bitwiseAnd","|":"bitwiseOr","^":"bitwiseXOR","<<":"bitwiseZeroFillLeftShift",">>":"bitwiseSignedRightShift",">>>":"bitwiseZeroFillRightShift"}[e.operator];if(!n)return null;switch(t.push(n),t.push("("),this.getType(e.left)){case"Number":case"Float":this.castValueToInteger(e.left,t);break;case"LiteralInteger":this.castLiteralToInteger(e.left,t);break;default:this.astGeneric(e.left,t)}switch(t.push(","),this.getType(e.right)){case"Number":case"Float":this.castValueToInteger(e.right,t);break;case"LiteralInteger":this.castLiteralToInteger(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseUnary(e,t){const n={"~":"bitwiseNot"}[e.operator];if(!n)return null;switch(t.push(n),t.push("("),this.getType(e.argument)){case"Number":case"Float":this.castValueToInteger(e.argument,t);break;case"LiteralInteger":this.castLiteralToInteger(e.argument,t);break;default:this.astGeneric(e.argument,t)}return t.push(")"),t}castLiteralToInteger(e,t){return this.pushState("casting-to-integer"),this.astGeneric(e,t),this.popState("casting-to-integer"),t}castLiteralToFloat(e,t){return this.pushState("casting-to-float"),this.astGeneric(e,t),this.popState("casting-to-float"),t}castValueToInteger(e,t){return this.pushState("casting-to-integer"),t.push("int("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-integer"),t}castValueToFloat(e,t){return this.pushState("casting-to-float"),t.push("float("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-float"),t}astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const n=this.getType(e);return"Infinity"===e.name?t.push("3.402823466e+38"):"Boolean"===n&&this.argumentNames.indexOf(e.name)>-1?t.push(`bool(user_${e.name})`):t.push(`user_${e.name}`),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){this.pushState("in-for-loop-init"),this.astGeneric(e.init,n);const{declarations:t}=e.init;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}e+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:r,signature:i,origin:s,type:a,xProperty:o,yProperty:u,zProperty:l}=this.getMemberExpressionDetails(e);switch(i){case"value.thread.value":case"this.thread.value":if("x"!==r&&"y"!==r&&"z"!==r)throw this.astErrorOutput("Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`",e);return t.push(`threadId.${r}`),t;case"this.output.value":if(this.dynamicOutput)switch(r){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(r){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"===s)return t.push(Math[r]),t;switch(n){case"r":return t.push(`user_${r}.r`),t;case"g":return t.push(`user_${r}.g`),t;case"b":return t.push(`user_${r}.b`),t;case"a":return t.push(`user_${r}.a`),t}break;case"this.constants.value":if(void 0===o)switch(a){case"Array(2)":case"Array(3)":case"Array(4)":return t.push(`constants_${r}`),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"[][]":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(a){case"Number":case"Integer":case"Float":case"Boolean":return t.push(`${s}_${r}`),t}const c=`${s}_${r}`;switch(a){case"Array(2)":case"Array(3)":case"Array(4)":this.astGeneric(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(o)),t.push("]");break;case"HTMLImageArray":t.push(`getImage3D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"ArrayTexture(1)":t.push(`getFloatFromSampler2D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"Array1D(2)":case"Array2D(2)":case"Array3D(2)":t.push(`getMemoryOptimizedVec2(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"ArrayTexture(2)":t.push(`getVec2FromSampler2D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"Array1D(3)":case"Array2D(3)":case"Array3D(3)":t.push(`getMemoryOptimizedVec3(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"ArrayTexture(3)":t.push(`getVec3FromSampler2D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"Array1D(4)":case"Array2D(4)":case"Array3D(4)":t.push(`getMemoryOptimizedVec4(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"ArrayTexture(4)":case"HTMLImage":case"HTMLVideo":t.push(`getVec4FromSampler2D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"NumberTexture":case"Array":case"Array2D":case"Array3D":case"Array4D":case"Input":case"Number":case"Float":case"Integer":if("single"===this.precision)t.push(`getMemoryOptimized32(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");else{const e="user"===s?this.lookupFunctionArgumentBitRatio(this.name,r):this.constantBitRatios[r];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(o,u,l,t),t.push(")")}break;case"MemoryOptimizedNumberTexture":t.push(`getMemoryOptimized32(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;default:throw new Error(`unhandled member expression "${a}"`)}return t}astCallExpression(e,t){if(!e.callee)throw this.astErrorOutput("Unknown CallExpression",e);let n=null;const r=this.isAstMathFunction(e);if(!(n=r||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))throw this.astErrorOutput("Unhandled function, couldn't find name",e);if("atan2"===n&&(n="atan"),this.calledFunctions.indexOf(n)<0&&this.calledFunctions.push(n),"random"===n&&this.plugins&&this.plugins.length>0)for(let e=0;e0&&t.push(", "),i){case"Integer":this.castValueToFloat(r,t);break;default:this.astGeneric(r,t)}}else{const r=this.lookupFunctionArgumentTypes(n)||[];for(let i=0;i0&&t.push(", ");const o=this.getType(s);switch(a||(this.triggerImplyArgumentType(n,i,o,this),a=o),o){case"Number":case"Float":if("Integer"===a){t.push("int("),this.astGeneric(s,t),t.push(")");continue}if("Number"===a||"Float"===a){this.astGeneric(s,t);continue}if("LiteralInteger"===a){this.castLiteralToFloat(s,t);continue}break;case"Integer":if("Number"===a||"Float"===a){t.push("float("),this.astGeneric(s,t),t.push(")");continue}if("Integer"===a){this.astGeneric(s,t);continue}break;case"LiteralInteger":if("Integer"===a){this.castLiteralToInteger(s,t);continue}if("Number"===a||"Float"===a){this.castLiteralToFloat(s,t);continue}if("LiteralInteger"===a){this.astGeneric(s,t);continue}break;case"Array(2)":case"Array(3)":case"Array(4)":if(a===o){if("Identifier"!==s.type)throw this.astErrorOutput(`Unhandled argument type ${s.type}`,e);this.triggerImplyArgumentBitRatio(this.name,s.name,n,i),t.push(`user_${s.name}`);continue}break;case"HTMLImage":case"HTMLImageArray":case"HTMLVideo":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":case"Array":case"Input":if(a===o){if("Identifier"!==s.type)throw this.astErrorOutput(`Unhandled argument type ${s.type}`,e);this.triggerImplyArgumentBitRatio(this.name,s.name,n,i),t.push(`user_${s.name},user_${s.name}Size,user_${s.name}Dim`);continue}}throw this.astErrorOutput(`Unhandled argument combination of ${o} and ${a} for argument named "${s.name}"`,e)}}return t.push(")"),t}astArrayExpression(e,t){const n=e.elements.length;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,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":111,"../function-node":9}],37:[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:g}=e("./kernel-value/memory-optimized-number-texture"),{WebGLKernelValueDynamicMemoryOptimizedNumberTexture:m}=e("./kernel-value/dynamic-memory-optimized-number-texture"),{WebGLKernelValueNumberTexture:x}=e("./kernel-value/number-texture"),{WebGLKernelValueDynamicNumberTexture:f}=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:E}=e("./kernel-value/dynamic-single-array2d-i"),{WebGLKernelValueSingleArray3DI:_}=e("./kernel-value/single-array3d-i"),{WebGLKernelValueDynamicSingleArray3DI:v}=e("./kernel-value/dynamic-single-array3d-i"),{WebGLKernelValueSingleArray2:D}=e("./kernel-value/single-array2"),{WebGLKernelValueSingleArray3:w}=e("./kernel-value/single-array3"),{WebGLKernelValueSingleArray4:$}=e("./kernel-value/single-array4"),{WebGLKernelValueUnsignedArray:I}=e("./kernel-value/unsigned-array"),{WebGLKernelValueDynamicUnsignedArray:R}=e("./kernel-value/dynamic-unsigned-array"),F={unsigned:{dynamic:{Boolean:r,Integer:s,Float:i,Array:R,"Array(2)":!1,"Array(3)":!1,"Array(4)":!1,"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:f,"ArrayTexture(1)":f,"ArrayTexture(2)":f,"ArrayTexture(3)":f,"ArrayTexture(4)":f,MemoryOptimizedNumberTexture:m,HTMLImage:o,HTMLImageArray:!1,HTMLVideo:l},static:{Boolean:r,Float:i,Integer:s,Array:I,"Array(2)":!1,"Array(3)":!1,"Array(4)":!1,"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:x,"ArrayTexture(1)":x,"ArrayTexture(2)":x,"ArrayTexture(3)":x,"ArrayTexture(4)":x,MemoryOptimizedNumberTexture:g,HTMLImage:a,HTMLImageArray:!1,HTMLVideo:u}},single:{dynamic:{Boolean:r,Integer:s,Float:i,Array:T,"Array(2)":D,"Array(3)":w,"Array(4)":$,"Array1D(2)":A,"Array1D(3)":A,"Array1D(4)":A,"Array2D(2)":E,"Array2D(3)":E,"Array2D(4)":E,"Array3D(2)":v,"Array3D(3)":v,"Array3D(4)":v,Input:h,NumberTexture:f,"ArrayTexture(1)":f,"ArrayTexture(2)":f,"ArrayTexture(3)":f,"ArrayTexture(4)":f,MemoryOptimizedNumberTexture:m,HTMLImage:o,HTMLImageArray:!1,HTMLVideo:l},static:{Boolean:r,Float:i,Integer:s,Array:y,"Array(2)":D,"Array(3)":w,"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:x,"ArrayTexture(1)":x,"ArrayTexture(2)":x,"ArrayTexture(3)":x,"ArrayTexture(4)":x,MemoryOptimizedNumberTexture:g,HTMLImage: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=F[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:F}},{"./kernel-value/boolean":38,"./kernel-value/dynamic-html-image":39,"./kernel-value/dynamic-html-video":40,"./kernel-value/dynamic-memory-optimized-number-texture":41,"./kernel-value/dynamic-number-texture":42,"./kernel-value/dynamic-single-array":43,"./kernel-value/dynamic-single-array1d-i":44,"./kernel-value/dynamic-single-array2d-i":45,"./kernel-value/dynamic-single-array3d-i":46,"./kernel-value/dynamic-single-input":47,"./kernel-value/dynamic-unsigned-array":48,"./kernel-value/dynamic-unsigned-input":49,"./kernel-value/float":50,"./kernel-value/html-image":51,"./kernel-value/html-video":52,"./kernel-value/integer":54,"./kernel-value/memory-optimized-number-texture":55,"./kernel-value/number-texture":56,"./kernel-value/single-array":57,"./kernel-value/single-array1d-i":58,"./kernel-value/single-array2":59,"./kernel-value/single-array2d-i":60,"./kernel-value/single-array3":61,"./kernel-value/single-array3d-i":62,"./kernel-value/single-array4":63,"./kernel-value/single-input":64,"./kernel-value/unsigned-array":65,"./kernel-value/unsigned-input":66}],38:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueBoolean:class extends i{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const bool ${this.id} = ${e};\n`:`uniform bool ${this.id};\n`}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}}},{"../../../utils":111,"./index":53}],39:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueHTMLImage:i}=e("./html-image");t.exports={WebGLKernelValueDynamicHTMLImage:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){const{width:t,height:n}=e;this.checkSize(t,n),this.dimensions=[t,n,1],this.textureSize=[t,n],this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"./html-image":51}],40:[function(e,t,n){const{WebGLKernelValueDynamicHTMLImage:r}=e("./dynamic-html-image");t.exports={WebGLKernelValueDynamicHTMLVideo:class extends r{}}},{"./dynamic-html-image":39}],41:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueMemoryOptimizedNumberTexture:i}=e("./memory-optimized-number-texture");t.exports={WebGLKernelValueDynamicMemoryOptimizedNumberTexture:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.checkSize(e.size[0],e.size[1]),this.dimensions=e.dimensions,this.textureSize=e.size,this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"./memory-optimized-number-texture":55}],42:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueNumberTexture:i}=e("./number-texture");t.exports={WebGLKernelValueDynamicNumberTexture:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=e.dimensions,this.checkSize(e.size[0],e.size[1]),this.textureSize=e.size,this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"./number-texture":56}],43:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueSingleArray:i}=e("./single-array");t.exports={WebGLKernelValueDynamicSingleArray:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"./single-array":57}],44:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueSingleArray1DI:i}=e("./single-array1d-i");t.exports={WebGLKernelValueDynamicSingleArray1DI:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"./single-array1d-i":58}],45:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueSingleArray2DI:i}=e("./single-array2d-i");t.exports={WebGLKernelValueDynamicSingleArray2DI:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"./single-array2d-i":60}],46:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueSingleArray3DI:i}=e("./single-array3d-i");t.exports={WebGLKernelValueDynamicSingleArray3DI:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"./single-array3d-i":62}],47:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueSingleInput:i}=e("./single-input");t.exports={WebGLKernelValueDynamicSingleInput:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform 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.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"./single-input":64}],48:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueUnsignedArray:i}=e("./unsigned-array");t.exports={WebGLKernelValueDynamicUnsignedArray:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0]*(4/this.bitRatio),this.textureSize[1]*(4/this.bitRatio));const t=this.getTransferArrayType(e);this.preUploadValue=new t(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"./unsigned-array":65}],49:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueUnsignedInput:i}=e("./unsigned-input");t.exports={WebGLKernelValueDynamicUnsignedInput:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,n,i]=e.size;this.dimensions=new Int32Array([t||1,n||1,i||1]),this.textureSize=r.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0]*(4/this.bitRatio),this.textureSize[1]*(4/this.bitRatio));const s=this.getTransferArrayType(e.value);this.preUploadValue=new s(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"./unsigned-input":66}],50:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueFloat:class extends i{constructor(e,t){super(e,t),this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(e){return"constants"===this.origin?Number.isInteger(e)?`const float ${this.id} = ${e}.0;\n`:`const float ${this.id} = ${e};\n`:`uniform float ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1f(this.id,this.uploadValue=e)}}}},{"../../../utils":111,"./index":53}],51:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueHTMLImage:class extends i{constructor(e,t){super(e,t);const{width:n,height:r}=e;this.checkSize(n,r),this.dimensions=[n,r,1],this.requestTexture(),this.textureSize=[n,r],this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!0),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue=e),this.kernel.setUniform1i(this.id,this.index)}}}},{"../../../utils":111,"./index":53}],52:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueHTMLImage:i}=e("./html-image");t.exports={WebGLKernelValueHTMLVideo:class extends i{}}},{"../../../utils":111,"./html-image":51}],53:[function(e,t,n){const{utils:r}=e("../../../utils"),{Input:i}=e("../../../input"),{KernelValue:s}=e("../../kernel-value");t.exports={WebGLKernelValue:class extends s{constructor(e,t){super(e,t),this.dimensionsId=null,this.sizeId=null,this.initialValueConstructor=e.constructor,this.onRequestTexture=t.onRequestTexture,this.onRequestIndex=t.onRequestIndex,this.uploadValue=null,this.textureSize=null,this.bitRatio=null}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 width of ${e} larger than maximum size of ${n} for your GPU`):new Error(`Argument height of ${t} larger than maximum size of ${n} for your GPU`)}requestTexture(){this.texture=this.onRequestTexture(),this.setupTexture()}setupTexture(){this.contextHandle=this.onRequestContextHandle(),this.index=this.onRequestIndex(),this.dimensionsId=this.id+"Dim",this.sizeId=this.id+"Size"}getTransferArrayType(e){if(Array.isArray(e[0]))return this.getTransferArrayType(e[0]);switch(e.constructor){case Array:case Int32Array:case Int16Array:case Int8Array:return Float32Array;case Uint8ClampedArray:case Uint8Array:case Uint16Array:case Uint32Array:case Float32Array:case Float64Array:return e.constructor}return console.warn("Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros"),e.constructor}formatArrayTransfer(e,t,n){if(r.isArray(e[0])||this.optimizeFloatMemory){const n=new Float32Array(t);return r.flattenTo(e,n),n}switch(e.constructor){case Uint8ClampedArray:case Uint8Array:case Int8Array:case Uint16Array:case Int16Array:case Float32Array:case Int32Array:{const i=new(n||e.constructor)(t);return r.flattenTo(e,i),i}default:{const n=new Float32Array(t);return r.flattenTo(e,n),n}}}getBitRatio(e){if(Array.isArray(e[0]))return this.getBitRatio(e[0]);if(e.constructor===i)return this.getBitRatio(e.value);switch(e.constructor){case Uint8ClampedArray:case Uint8Array:case Int8Array:return 1;case Uint16Array:case Int16Array:return 2;case Float32Array:case Int32Array:default:return 4}}getStringValueHandler(){throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`)}getVariablePrecisionString(){switch(this.tactic){case"speed":return"lowp";case"performance":return"highp";case"balanced":default:return"mediump"}}}}},{"../../../input":107,"../../../utils":111,"../../kernel-value":33}],54:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueInteger:class extends i{constructor(e,t){super(e,t),this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(e){return"constants"===this.origin?`const int ${this.id} = ${parseInt(e)};\n`:`uniform int ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}}},{"../../../utils":111,"./index":53}],55:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueMemoryOptimizedNumberTexture:class extends i{constructor(e,t){super(e,t);const[n,r]=e.size;this.checkSize(n,r),this.setupTexture(),this.dimensions=e.dimensions,this.textureSize=e.size,this.uploadValue=e.texture,this.forceUploadEachRun=!0}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName}.texture;\n`}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();if(this.checkContext&&e.context!==this.context)throw new Error(`Value ${this.name} (${this.type}) must be from same context`);const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.uploadValue=e.texture),this.kernel.setUniform1i(this.id,this.index)}}}},{"../../../utils":111,"./index":53}],56:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueNumberTexture:class extends i{constructor(e,t){super(e,t);const[n,r]=e.size;this.checkSize(n,r),this.setupTexture();const{size:i,dimensions:s}=e;this.bitRatio=this.getBitRatio(e),this.dimensions=s,this.textureSize=i,this.uploadValue=e.texture,this.forceUploadEachRun=!0}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName}.texture;\n`}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();if(this.checkContext&&e.context!==this.context)throw new Error(`Value ${this.name} (${this.type}) must be from same context`);const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.uploadValue=e.texture),this.kernel.setUniform1i(this.id,this.index)}}}},{"../../../utils":111,"./index":53}],57:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueSingleArray:class extends i{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=4,this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;r.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}},{"../../../utils":111,"./index":53}],58:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueSingleArray1DI:class extends i{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=4,this.setShape(e)}setShape(e){const t=r.getDimensions(e,!0);this.textureSize=r.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],1,1]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;r.flatten2dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}},{"../../../utils":111,"./index":53}],59:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueSingleArray2:class extends i{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec2 ${this.id} = vec2(${e[0]},${e[1]});\n`:`uniform vec2 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform2fv(this.id,this.uploadValue=e)}}}},{"../../../utils":111,"./index":53}],60:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueSingleArray2DI:class extends i{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=4,this.setShape(e)}setShape(e){const t=r.getDimensions(e,!0);this.textureSize=r.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],t[2],1]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;r.flatten3dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}},{"../../../utils":111,"./index":53}],61:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueSingleArray3:class extends i{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec3 ${this.id} = vec3(${e[0]},${e[1]},${e[2]});\n`:`uniform vec3 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform3fv(this.id,this.uploadValue=e)}}}},{"../../../utils":111,"./index":53}],62:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueSingleArray3DI:class extends i{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=4,this.setShape(e)}setShape(e){const t=r.getDimensions(e,!0);this.textureSize=r.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],t[2],t[3]]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;r.flatten4dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}},{"../../../utils":111,"./index":53}],63:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueSingleArray4:class extends i{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec4 ${this.id} = vec4(${e[0]},${e[1]},${e[2]},${e[3]});\n`:`uniform vec4 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform4fv(this.id,this.uploadValue=e)}}}},{"../../../utils":111,"./index":53}],64:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueSingleInput:class extends i{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=4;let[n,i,s]=e.size;this.dimensions=new Int32Array([n||1,i||1,s||1]),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}.value, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;r.flattenTo(e.value,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}},{"../../../utils":111,"./index":53}],65:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueUnsignedArray:class extends i{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=this.getBitRatio(e),this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0]*(4/this.bitRatio),this.textureSize[1]*(4/this.bitRatio)),this.TranserArrayType=this.getTransferArrayType(e),this.preUploadValue=new this.TranserArrayType(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer)}getStringValueHandler(){return r.linesToString([`const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,`const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,`flattenTo(${this.varName}, preUploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;r.flattenTo(e,this.preUploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}},{"../../../utils":111,"./index":53}],66:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueUnsignedInput:class extends i{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=this.getBitRatio(e);const[n,i,s]=e.size;this.dimensions=new Int32Array([n||1,i||1,s||1]),this.textureSize=r.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0]*(4/this.bitRatio),this.textureSize[1]*(4/this.bitRatio)),this.TranserArrayType=this.getTransferArrayType(e.value),this.preUploadValue=new this.TranserArrayType(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer)}getStringValueHandler(){return r.linesToString([`const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,`const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,`flattenTo(${this.varName}.value, preUploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;r.flattenTo(e.value,this.preUploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}},{"../../../utils":111,"./index":53}],67:[function(e,t,n){const{GLKernel:r}=e("../gl/kernel"),{FunctionBuilder:i}=e("../function-builder"),{WebGLFunctionNode:s}=e("./function-node"),{utils:a}=e("../../utils"),o=e("../../plugins/triangle-noise"),{fragmentShader:u}=e("./fragment-shader"),{vertexShader:l}=e("./vertex-shader"),{glKernelString:c}=e("../gl/kernel-string"),{lookupKernelValueType:h}=e("./kernel-value-maps");let p=null,d=null,g=null,m=null,x=null;const f=[o],y=[],T={};t.exports={WebGLKernel:class extends r{static get isSupported(){return null!==p?p:(this.setupFeatureChecks(),p=this.isContextMatch(g))}static setupFeatureChecks(){"undefined"!=typeof document?d=document.createElement("canvas"):"undefined"!=typeof OffscreenCanvas&&(d=new OffscreenCanvas(0,0)),d&&(g=d.getContext("webgl")||d.getContext("experimental-webgl"))&&g.getExtension&&(m={OES_texture_float:g.getExtension("OES_texture_float"),OES_texture_float_linear:g.getExtension("OES_texture_float_linear"),OES_element_index_uint:g.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:g.getExtension("WEBGL_draw_buffers")},x=this.getFeatures())}static isContextMatch(e){return"undefined"!=typeof WebGLRenderingContext&&e instanceof WebGLRenderingContext}static getFeatures(){const e=this.getIsDrawBuffers();return Object.freeze({isFloatRead:this.getIsFloatRead(),isIntegerDivisionAccurate:this.getIsIntegerDivisionAccurate(),isTextureFloat:this.getIsTextureFloat(),isDrawBuffers:e,kernelMap:e,channelCount:this.getChannelCount(),maxTextureSize:this.getMaxTextureSize()})}static getIsTextureFloat(){return Boolean(m.OES_texture_float)}static getIsDrawBuffers(){return Boolean(m.WEBGL_draw_buffers)}static getChannelCount(){return m.WEBGL_draw_buffers?g.getParameter(m.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL):1}static getMaxTextureSize(){return g.getParameter(g.MAX_TEXTURE_SIZE)}static lookupKernelValueType(e,t,n,r){return h(e,t,n,r)}static get testCanvas(){return d}static get testContext(){return g}static get features(){return x}static get fragmentShader(){return u}static get vertexShader(){return l}constructor(e,t){super(e,t),this.program=null,this.pipeline=t.pipeline,this.endianness=a.systemEndianness(),this.extensions={},this.subKernelOutputTextures=null,this.kernelArguments=null,this.argumentTextureCount=0,this.constantTextureCount=0,this.compiledFragmentShader=null,this.compiledVertexShader=null,this.fragShader=null,this.vertShader=null,this.drawBuffersMap=null,this.outputTexture=null,this.maxTexSize=null,this.switchingKernels=!1,this.onRequestSwitchKernel=null,this.mergeSettings(e.settings||t),this.threadDim=null,this.framebuffer=null,this.buffer=null,this.textureCache={},this.programUniformLocationCache={},this.uniform1fCache={},this.uniform1iCache={},this.uniform2fCache={},this.uniform2fvCache={},this.uniform2ivCache={},this.uniform3fvCache={},this.uniform3ivCache={},this.uniform4fvCache={},this.uniform4ivCache={}}initCanvas(){if("undefined"!=typeof document){const e=document.createElement("canvas");return e.width=2,e.height=2,e}if("undefined"!=typeof OffscreenCanvas)return new OffscreenCanvas(0,0)}initContext(){const e={alpha:!1,depth:!1,antialias:!1};return this.canvas.getContext("webgl",e)||this.canvas.getContext("experimental-webgl",e)}initPlugins(e){const t=[],{source:n}=this;if("string"==typeof n)for(let e=0;ee===r.name)&&t.push(r)}return t}initExtensions(){this.extensions={OES_texture_float:this.context.getExtension("OES_texture_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear"),OES_element_index_uint:this.context.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:this.context.getExtension("WEBGL_draw_buffers"),WEBGL_color_buffer_float:this.context.getExtension("WEBGL_color_buffer_float")}}validateSettings(e){if(!this.validate)return void(this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output));const{features:t}=this.constructor;if(!0===this.optimizeFloatMemory&&!t.isTextureFloat)throw new Error("Float textures are not supported");if("single"===this.precision&&!t.isFloatRead)throw new Error("Single precision not supported");if(!this.graphical&&null===this.precision&&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);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){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]x.channelCount)throw new Error("Too many channels!");return this.translatedSource=t}setupArguments(e){this.kernelArguments=[],this.argumentTextureCount=0;const t=null===this.argumentTypes;if(t&&(this.argumentTypes=[]),this.argumentSizes=[],this.argumentBitRatios=[],e.lengththis.argumentNames.length)throw new Error("too many arguments for kernel");const{context:n}=this;let r=0;for(let i=0;ithis.context.createTexture(),onRequestIndex:()=>r++,onUpdateValueMismatch:()=>{this.switchingKernels=!0},onRequestContextHandle:()=>n.TEXTURE0+this.constantTextureCount+this.argumentTextureCount++});this.kernelArguments.push(c),this.argumentSizes.push(c.textureSize),this.argumentBitRatios[i]=c.bitRatio}}setupConstants(e){const{context:t}=this;this.kernelConstants=[],this.forceUploadKernelConstants=[];let n=null===this.constantTypes;n&&(this.constantTypes={}),this.constantBitRatios={};let r=0;for(const i in this.constants){const s=this.constants[i];let o;n?(o=a.getVariableType(s,this.strictIntegers),this.constantTypes[i]=o):o=this.constantTypes[i];const u=this.constructor.lookupKernelValueType(o,"static",this.precision,s);if(null===u)return this.requestFallback(e);const l=new u(s,{name:i,type:o,tactic:this.tactic,origin:"constants",context:this.context,checkContext:this.checkContext,kernel:this,strictIntegers:this.strictIntegers,onRequestTexture:()=>this.context.createTexture(),onRequestIndex:()=>r++,onRequestContextHandle:()=>t.TEXTURE0+this.constantTextureCount++});this.constantBitRatios[i]=l.bitRatio,this.kernelConstants.push(l),l.forceUploadEachRun&&this.forceUploadKernelConstants.push(l)}}build(){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];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 g=n.getAttribLocation(this.program,"aPos");n.enableVertexAttribArray(g),n.vertexAttribPointer(g,2,n.FLOAT,!1,0,0);const m=n.getAttribLocation(this.program,"aTexCoord");n.enableVertexAttribArray(m),n.vertexAttribPointer(m,2,n.FLOAT,!1,0,p),n.bindFramebuffer(n.FRAMEBUFFER,this.framebuffer);let x=0;n.useProgram(this.program);for(let e in this.constants)this.kernelConstants[x++].updateValue(this.constants[e]);this.immutable||(this._setupOutputTexture(),null!==this.subKernels&&this.subKernels.length>0&&this._setupSubOutputTextures())}translateSource(){const e=i.fromKernel(this,s,{fixIntegerDivisionAccuracy:this.fixIntegerDivisionAccuracy});if(this.translatedSource=e.getPrototypeString("kernel"),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 div_with_int_check(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}":""}_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){this.outputTexture&&this.context.deleteTexture(this.outputTexture),this.buffer&&this.context.deleteBuffer(this.buffer),this.framebuffer&&this.context.deleteFramebuffer(this.framebuffer),this.vertShader&&this.context.deleteShader(this.vertShader),this.fragShader&&this.context.deleteShader(this.fragShader),this.program&&this.context.deleteProgram(this.program);const t=Object.keys(this.textureCache);for(let e=0;e=0&&(y[e]=null,T[e]=null)}this.destroyExtensions(),delete this.context,delete this.canvas}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}}}},{"../../plugins/triangle-noise":109,"../../utils":111,"../function-builder":8,"../gl/kernel":12,"../gl/kernel-string":11,"./fragment-shader":35,"./function-node":36,"./kernel-value-maps":37,"./vertex-shader":68}],68:[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}"}},{}],69:[function(e,t,n){t.exports={fragmentShader:"#version 300 es\n__HEADER__;\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__;\n\nconst int LOOP_MAX = __LOOP_MAX__;\n\n__PLUGINS__;\n__CONSTANTS__;\n\nin vec2 vTexCoord;\n\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\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}"}},{}],70:[function(e,t,n){const{WebGLFunctionNode:r}=e("../web-gl/function-node");t.exports={WebGL2FunctionNode:class extends r{astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const n=this.getType(e);return"Infinity"===e.name?t.push("intBitsToFloat(2139095039)"):"Boolean"===n&&this.argumentNames.indexOf(e.name)>-1?t.push(`bool(user_${e.name})`):t.push(`user_${e.name}`),t}}}},{"../web-gl/function-node":36}],71:[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:g}=e("./kernel-value/unsigned-input"),{WebGL2KernelValueDynamicUnsignedInput:m}=e("./kernel-value/dynamic-unsigned-input"),{WebGL2KernelValueMemoryOptimizedNumberTexture:x}=e("./kernel-value/memory-optimized-number-texture"),{WebGL2KernelValueDynamicMemoryOptimizedNumberTexture:f}=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:E}=e("./kernel-value/dynamic-single-array1d-i"),{WebGL2KernelValueSingleArray2DI:_}=e("./kernel-value/single-array2d-i"),{WebGL2KernelValueDynamicSingleArray2DI:v}=e("./kernel-value/dynamic-single-array2d-i"),{WebGL2KernelValueSingleArray3DI:D}=e("./kernel-value/single-array3d-i"),{WebGL2KernelValueDynamicSingleArray3DI:w}=e("./kernel-value/dynamic-single-array3d-i"),{WebGL2KernelValueSingleArray2:$}=e("./kernel-value/single-array2"),{WebGL2KernelValueSingleArray3:I}=e("./kernel-value/single-array3"),{WebGL2KernelValueSingleArray4:R}=e("./kernel-value/single-array4"),{WebGL2KernelValueUnsignedArray:F}=e("./kernel-value/unsigned-array"),{WebGL2KernelValueDynamicUnsignedArray:k}=e("./kernel-value/dynamic-unsigned-array"),L={unsigned:{dynamic:{Boolean:r,Integer:s,Float:i,Array:k,"Array(2)":!1,"Array(3)":!1,"Array(4)":!1,"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:T,"ArrayTexture(1)":T,"ArrayTexture(2)":T,"ArrayTexture(3)":T,"ArrayTexture(4)":T,MemoryOptimizedNumberTexture:f,HTMLImage:o,HTMLImageArray:l,HTMLVideo:h},static:{Boolean:r,Float:i,Integer:s,Array:F,"Array(2)":!1,"Array(3)":!1,"Array(4)":!1,"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:y,"ArrayTexture(1)":y,"ArrayTexture(2)":y,"ArrayTexture(3)":y,"ArrayTexture(4)":y,MemoryOptimizedNumberTexture:f,HTMLImage:a,HTMLImageArray:u,HTMLVideo:c}},single:{dynamic:{Boolean:r,Integer:s,Float:i,Array:A,"Array(2)":$,"Array(3)":I,"Array(4)":R,"Array1D(2)":E,"Array1D(3)":E,"Array1D(4)":E,"Array2D(2)":v,"Array2D(3)":v,"Array2D(4)":v,"Array3D(2)":w,"Array3D(3)":w,"Array3D(4)":w,Input:d,NumberTexture:T,"ArrayTexture(1)":T,"ArrayTexture(2)":T,"ArrayTexture(3)":T,"ArrayTexture(4)":T,MemoryOptimizedNumberTexture:f,HTMLImage:o,HTMLImageArray:l,HTMLVideo:h},static:{Boolean:r,Float:i,Integer:s,Array:b,"Array(2)":$,"Array(3)":I,"Array(4)":R,"Array1D(2)":S,"Array1D(3)":S,"Array1D(4)":S,"Array2D(2)":_,"Array2D(3)":_,"Array2D(4)":_,"Array3D(2)":D,"Array3D(3)":D,"Array3D(4)":D,Input:p,NumberTexture:y,"ArrayTexture(1)":y,"ArrayTexture(2)":y,"ArrayTexture(3)":y,"ArrayTexture(4)":y,MemoryOptimizedNumberTexture:x,HTMLImage: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/boolean":72,"./kernel-value/dynamic-html-image":74,"./kernel-value/dynamic-html-image-array":73,"./kernel-value/dynamic-html-video":75,"./kernel-value/dynamic-memory-optimized-number-texture":76,"./kernel-value/dynamic-number-texture":77,"./kernel-value/dynamic-single-array":78,"./kernel-value/dynamic-single-array1d-i":79,"./kernel-value/dynamic-single-array2d-i":80,"./kernel-value/dynamic-single-array3d-i":81,"./kernel-value/dynamic-single-input":82,"./kernel-value/dynamic-unsigned-array":83,"./kernel-value/dynamic-unsigned-input":84,"./kernel-value/float":85,"./kernel-value/html-image":87,"./kernel-value/html-image-array":86,"./kernel-value/html-video":88,"./kernel-value/integer":89,"./kernel-value/memory-optimized-number-texture":90,"./kernel-value/number-texture":91,"./kernel-value/single-array":92,"./kernel-value/single-array1d-i":93,"./kernel-value/single-array2":94,"./kernel-value/single-array2d-i":95,"./kernel-value/single-array3":96,"./kernel-value/single-array3d-i":97,"./kernel-value/single-array4":98,"./kernel-value/single-input":99,"./kernel-value/unsigned-array":100,"./kernel-value/unsigned-input":101}],72:[function(e,t,n){const{WebGLKernelValueBoolean:r}=e("../../web-gl/kernel-value/boolean");t.exports={WebGL2KernelValueBoolean:class extends r{}}},{"../../web-gl/kernel-value/boolean":38}],73:[function(e,t,n){const{WebGL2KernelValueHTMLImageArray:r}=e("./html-image-array");t.exports={WebGL2KernelValueDynamicHTMLImageArray:class extends r{getSource(){const e=this.getVariablePrecisionString();return utils.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)}}}},{"./html-image-array":86}],74:[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":111,"../../web-gl/kernel-value/dynamic-html-image":39}],75:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueDynamicHTMLImage:i}=e("./dynamic-html-image");t.exports={WebGL2KernelValueDynamicHTMLVideo:class extends i{}}},{"../../../utils":111,"./dynamic-html-image":74}],76:[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":111,"../../web-gl/kernel-value/dynamic-memory-optimized-number-texture":41}],77:[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":111,"../../web-gl/kernel-value/dynamic-number-texture":42}],78:[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.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"../../web-gl2/kernel-value/single-array":92}],79:[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":111,"../../web-gl2/kernel-value/single-array1d-i":93}],80:[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":111,"../../web-gl2/kernel-value/single-array2d-i":95}],81:[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":111,"../../web-gl2/kernel-value/single-array3d-i":97}],82:[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.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"../../web-gl2/kernel-value/single-input":99}],83:[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":111,"../../web-gl/kernel-value/dynamic-unsigned-array":48}],84:[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":111,"../../web-gl/kernel-value/dynamic-unsigned-input":49}],85:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueFloat:i}=e("../../web-gl/kernel-value/float");t.exports={WebGL2KernelValueFloat:class extends i{}}},{"../../../utils":111,"../../web-gl/kernel-value/float":50}],86:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("../../web-gl/kernel-value/index");t.exports={WebGL2KernelValueHTMLImageArray:class extends i{constructor(e,t){super(e,t),this.checkSize(e[0].width,e[0].height),this.requestTexture(),this.dimensions=[e[0].width,e[0].height,e.length],this.textureSize=[e[0].width,e[0].height]}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.texParameteri(t.TEXTURE_2D_ARRAY,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D_ARRAY,t.TEXTURE_MIN_FILTER,t.NEAREST),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;n0)for(let t=0;te.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 u.isSupported}static get isWebGL2Supported(){return o.isSupported}static get isHeadlessGLSupported(){return a.isSupported}static get isCanvasSupported(){return"undefined"!=typeof HTMLCanvasElement}static get isGPUHTMLImageArraySupported(){return o.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 u=Object.assign({context:this.context,canvas:this.canvas,functions:this.functions,nativeFunctions:this.nativeFunctions,injectedNative:this.injectedNative,gpu:this,validate:d,onRequestFallback:o,onRequestSwitchKernel:function t(r,s){const a=new Array(r.length);for(let e=0;et.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.');n=n||{};const{argumentTypes:r,argumentNames:i}=this.Kernel.nativeFunctionArguments(t)||{};return this.nativeFunctions.push({name:e,source:t,settings:n,argumentTypes:r,argumentNames:i,returnType:n.returnType||this.Kernel.nativeFunctionReturnType(t)}),this}injectNative(e){return this.injectedNative=e,this}destroy(){this.kernels&&setTimeout(()=>{for(let e=0;ee[i]),t.__defineSetter__(i,t=>{e[i]=t})))}}t.exports={kernelRunShortcut:function(e){let t=function(){return e.build.apply(e,arguments),(t=e.renderKernels?function(){return e.run.apply(e,arguments),e.switchingKernels?(e.switchingKernels=!1,e.onRequestSwitchKernel(arguments,e)):e.renderKernels()}:e.renderOutput?function(){return e.run.apply(e,arguments),e.switchingKernels?(e.switchingKernels=!1,e.onRequestSwitchKernel(arguments,e)):e.renderOutput()}:function(){return e.run.apply(e,arguments)}).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),n.kernel=e},i(e,n),n.kernel=e,n}}},{"./utils":111}],109:[function(e,t,n){t.exports={name:"triangle-noise-noise",onBeforeRun:e=>{e.setUniform1f("triangle_noise_seed",Math.random())},functionMatch:"Math.random()",functionReplace:"n4rand(vTexCoord)",functionReturnType:"Number",source:"\n\nuniform highp float triangle_noise_seed;\nhighp float triangle_noise_shift = 0.000001;\n\n//https://www.shadertoy.com/view/4t2SDh\n//note: uniformly distributed, normalized rand, [0;1[\nfloat nrand( vec2 n )\n{\n return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453);\n}\n//note: remaps v to [0;1] in interval [a;b]\nfloat remap( float a, float b, float v )\n{\n return clamp( (v-a) / (b-a), 0.0, 1.0 );\n}\n\nfloat n4rand( vec2 n )\n{\n float t = fract( triangle_noise_seed + triangle_noise_shift );\n float nrnd0 = nrand( n + 0.07*t );\n float nrnd1 = nrand( n + 0.11*t ); \n float nrnd2 = nrand( n + 0.13*t );\n float nrnd3 = nrand( n + 0.17*t );\n float result = (nrnd0+nrnd1+nrnd2+nrnd3) / 4.0;\n triangle_noise_shift = result + 0.000001;\n return result;\n}"}},{}],110:[function(e,t,n){t.exports={Texture:class{constructor(e){const{texture:t,size:n,dimensions:r,output:i,context:s,type:a="NumberTexture"}=e;if(!i)throw new Error('settings property "output" required.');if(!s)throw new Error('settings property "context" required.');this.texture=t,this.size=n,this.dimensions=r,this.output=i,this.context=s,this.kernel=null,this.type=a}toArray(){throw new Error(`Not implemented on ${this.constructor.name}`)}delete(){return this.context.deleteTexture(this.texture)}}}},{}],111:[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:()=>c,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,"function".length).toLowerCase(),getFunctionNameFromString:e=>a.exec(e)[1].trim(),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"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"}switch(e.nodeName){case"IMG":return"HTMLImage";case"VIDEO":return"HTMLVideo"}return e.hasOwnProperty("type")?e.type:"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.`)},functionToIFunction(e,t){if(t=t||{},"string"!=typeof e&&"function"!=typeof e)throw new Error("source not a string or function");const n="string"==typeof e?e:e.toString();let r=[];return{source:n,argumentTypes:r=Array.isArray(t.argumentTypes)?t.argumentTypes:"object"==typeof t.argumentTypes?l.getArgumentNamesFromString(n).map(e=>t.argumentTypes[e])||[]:t.argumentTypes||[],returnType:t.returnType||null}},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=[];const c=function e(t){if(Array.isArray(t)){const n=[];for(let r=0;rt.id.properties.map(e))[0];if(/this/.test(n)){const e=[],n=r.map(i);for(let i=0;ie(t.id)).join(", ")} ] = ${e(t.declarations[0].init)}`}return s&&-1!==s.indexOf(t.declarations[0].id.name)?"":`${t.kind} ${t.declarations[0].id.name} = ${e(t.declarations[0].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"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{const n=new GPU({mode:t}),r=n.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].r},{output:[e.width,e.height],precision:"unsigned",argumentTypes:["HTMLImage"]}),i=n.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].g},{output:[e.width,e.height],precision:"unsigned",argumentTypes:["HTMLImage"]}),s=n.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].b},{output:[e.width,e.height],precision:"unsigned",argumentTypes:["HTMLImage"]}),a=n.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].a},{output:[e.width,e.height],precision:"unsigned",argumentTypes:["HTMLImage"]}),o=[r(e),i(e),s(e),a(e)];return o.rKernel=r,o.gKernel=i,o.bKernel=s,o.aKernel=a,o.gpu=n,o},splitRGBAToCanvases:(t,n,r,i)=>{const{GPU:s}=e("./gpu.js"),a=new s({mode:i}),o=a.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)"}});o(t);const u=new s({mode:i}),l=u.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)"}});l(t);const c=new s({mode:i}),h=c.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)"}});h(t);const p=new s({mode:i}),d=p.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 d(t),a.destroy(),u.destroy(),c.destroy(),p.destroy(),[o.canvas,l.canvas,h.canvas,d.canvas]}},c=l.getSystemEndianness();t.exports={utils:l}},{"./gpu.js":105,"./input":107,"./texture":110,acorn:1}]},{},[104])(104)}); \ No newline at end of file +var GPU=function(e){"use strict";function t(e){const t=new Array(e.length);for(let r=0;r{e.output=u(t),e.graphical&&o(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.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,e.setOptimizeFloatMemory=()=>e,e.setArgumentTypes=()=>e,e.setDebug=()=>e,e.setLoopMaxIterations=()=>e,e.setPipeline=()=>e,e.setPrecision=()=>e,e.setImmutable=()=>e,e.setFunctions=()=>e,e.addSubKernel=()=>e,e.destroy=()=>{},e.validateSettings=()=>{},e.graphical&&e.output&&o(e),e}function o(e){const{x:t,y:r}=e.output;if(e.context&&e.context.createImageData){const n=new Uint8ClampedArray(t*r*4);e._imageData=e.context.createImageData(t,r),e._colorData=n}else{const n=new Uint8ClampedArray(t*r*4);e._imageData={data:n},e._colorData=n}}function u(e){let t=null;if(e.length)if(3===e.length){const[r,n,i]=e;t={x:r,y:n,z:i}}else if(2===e.length){const[r,n]=e;t={x:r,y:n}}else{const[r]=e;t={x:r}}else t=e;return t}var l=function(e,t={}){const o=t.output?u(t.output):null;function l(){return l.output.z?s.apply(l,arguments):l.output.y?l.graphical?i.apply(l,arguments):n.apply(l,arguments):r.apply(l,arguments)}return l._fn=e,l.constants=t.constants||null,l.context=t.context||null,l.canvas=t.canvas||null,l.graphical=t.graphical||!1,l._imageData=null,l._colorData=null,l.output=o,l.thread={x:0,y:0,z:0},a(l)};const h=/([^\s,]+)/g,c=/function ([^(]*)/,p=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;function d(e){return"function"==typeof e}function m(e){return c.exec(e)[1].trim()}function g(e,t){if(t=t||{},"string"!=typeof e&&"function"!=typeof e)throw new Error("source not a string or function");const r="string"==typeof e?e:e.toString();let n=[];return{source:r,argumentTypes:n=Array.isArray(t.argumentTypes)?t.argumentTypes:"object"==typeof t.argumentTypes?y(r).map(e=>t.argumentTypes[e])||[]:t.argumentTypes||[],returnType:t.returnType||null}}function f(e,t,r){const n=r?`It has been replaced with "${r}"`:"It has been removed";console.warn(`You are using a deprecated ${e} "${t}". ${n}. Fixing, but please upgrade as it will soon be removed.`)}function x(e){return"string"==typeof e&&"function"===e.slice(0,"function".length).toLowerCase()}function y(e){const t=e.replace(p,"");let r=t.slice(t.indexOf("(")+1,t.indexOf(")")).match(h);return null===r&&(r=[]),r}function T(e){return!isNaN(e.length)}function b(e,t,r){const n=new Array(r);for(let i=0;ie.substring(e.indexOf("{")+1,e.lastIndexOf("}")),getArgumentNamesFromString:y,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]=R.clone(e[r]),delete e.isActiveClone);return t},isArray:T,getVariableType:w,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]):R.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(T(e)){const t=[];let n=e;for(;T(n);)t.push(n.length),n=n[0];r=t.reverse()}else if(e instanceof v)r=e.output;else{if(!(e instanceof _))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:f,functionToIFunction:g,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:b,erectMemoryOptimized3DFloat:A,erectFloat:(e,t)=>{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:n,thisLookup:i,doNotDefine:s}=r;let a=r.flattened;a||(a=r.flattened={});const o=e.parse(t),u=[];const l=function e(t){if(Array.isArray(t)){const r=[];for(let n=0;nt.id.properties.map(e))[0];if(/this/.test(r)){const e=[],r=n.map(i);for(let i=0;ie(t.id)).join(", ")} ] = ${e(t.declarations[0].init)}`}return s&&-1!==s.indexOf(t.declarations[0].id.name)?"":`${t.kind} ${t.declarations[0].id.name} = ${e(t.declarations[0].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"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 t=0;tg(e));continue}break;case"graphical":e[t]&&!e.hasOwnProperty("precision")&&(this.precision="unsigned"),this[t]=e[t];continue}this[t]=e[t]}this.canvas||(this.canvas=this.initCanvas()),this.context||(this.context=this.initContext()),this.plugins||(this.plugins=this.initPlugins(e))}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(e){throw new Error(`"initPlugins" not defined on ${this.constructor.name}`)}setupArguments(e){if(this.kernelArguments=[],this.argumentTypes)for(let e=0;eg(e)):this.functions=e,this}setNativeFunctions(e){return this.nativeFunctions=e,this}setInjectedNative(e){return this.injectedNative=e,this}setPipeline(e){return this.pipeline=e,this}setPrecision(e){return this.precision=e,this}setOutputToTexture(e){return f("method","setOutputToTexture","setPipeline"),this.pipeline=e,this}setImmutable(e){return this.immutable=e,this}setCanvas(e){return this.canvas=e,this}setStrictIntegers(e){return this.strictIntegers=e,this}setDynamicOutput(e){return this.dynamicOutput=e,this}setHardcodeConstants(e){return f("method","setHardcodeConstants"),this.setDynamicOutput(e),this.setDynamicArguments(e),this}setDynamicArguments(e){return this.dynamicArguments=e,this}setUseLegacyEncoder(e){return this.useLegacyEncoder=e,this}setWarnVarUsage(e){return this.warnVarUsage=e,this}getCanvas(){return f("method","getCanvas"),this.canvas}getWebGl(){return f("method","getWebGl"),this.context}setContext(e){return this.context=e,this}setArgumentTypes(e){if(Array.isArray(e))this.argumentTypes=e;else{this.argumentTypes=[];for(const t in e){const r=this.argumentNames.indexOf(t);if(-1===r)throw new Error(`unable to find argument ${t}`);this.argumentTypes[r]=e[t]}}return this}setTactic(e){return this.tactic=e,this}requestFallback(e){if(!this.onRequestFallback)throw new Error(`"onRequestFallback" not defined on ${this.constructor.name}`);return this.fallbackRequested=!0,this.onRequestFallback(e)}validateSettings(){throw new Error(`"validateSettings" not defined on ${this.constructor.name}`)}addSubKernel(e){if(null===this.subKernels&&(this.subKernels=[]),!e.source)throw new Error('subKernel missing "source" property');if(!e.property&&isNaN(e.property))throw new Error('subKernel missing "property" property');if(!e.name)throw new Error('subKernel missing "name" property');return this.subKernels.push(e),this}destroy(e){throw new Error(`"destroy" called on ${this.constructor.name}`)}getBitRatio(e){if("single"===this.precision)return 4;if(Array.isArray(e[0]))return this.getBitRatio(e[0]);if(e.constructor===_)return this.getBitRatio(e.value);switch(e.constructor){case Uint8ClampedArray:case Uint8Array:case Int8Array:return 1;case Uint16Array:case Int16Array:return 2;case Float32Array:case Int32Array:default:return 4}}getPixels(){throw new Error(`"getPixels" called on ${this.constructor.name}`)}checkOutput(){if(!this.output||!T(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 e=0;ee.name):null,returnType:this.returnType}}}}class F{static fromKernel(e,t,r){const{kernelArguments:n,kernelConstants:i,argumentNames:s,argumentSizes:a,argumentBitRatios:o,constants:u,constantBitRatios:l,debug:h,loopMaxIterations:c,nativeFunctions:p,output:d,optimizeFloatMemory:m,precision:g,plugins:f,source:x,subKernels:y,functions:T,leadingReturnStatement:b,followingReturnStatement:A,dynamicArguments:E,dynamicOutput:S,warnVarUsage:_}=e,v=new Array(n.length),D={};for(let e=0;eG.needsArgumentType(e,t),w=(e,t,r)=>{G.assignArgumentType(e,t,r)},R=(e,t,r)=>G.lookupReturnType(e,t,r),I=e=>G.lookupFunctionArgumentTypes(e),z=(e,t)=>G.lookupFunctionArgumentName(e,t),O=(e,t)=>G.lookupFunctionArgumentBitRatio(e,t),C=(e,t,r,n)=>{G.assignArgumentType(e,t,r,n)},N=(e,t,r,n)=>{G.trackArgumentSynonym(e,t,r,n)},k=(e,t,r)=>G.lookupArgumentSynonym(e,t,r),M=(e,t,r)=>{G.trackFunctionCall(e,t,r)},U=Object.assign({isRootKernel:!1,onNestedFunction:(e,r)=>{const n=[];for(let t=0;tnew t(e.source,{returnType:e.returnType,argumentTypes:e.argumentTypes,output:d,plugins:f,constants:u,constantTypes:D,constantBitRatios:l,optimizeFloatMemory:m,precision:g,lookupReturnType:R,lookupFunctionArgumentTypes:I,lookupFunctionArgumentName:z,lookupFunctionArgumentBitRatio:O,needsArgumentType:$,assignArgumentType:w,triggerImplyArgumentType:C,triggerTrackArgumentSynonym:N,lookupArgumentSynonym:k,onFunctionCall:M})));let K=null;y&&(K=y.map(e=>{const{name:r,source:n}=e;return new t(n,Object.assign({},U,{name:r,isSubKernel:!0,isRootKernel:!1}))}));const G=new F({kernel:e,rootNode:L,functionNodes:V,nativeFunctions:p,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.argumentChain=[],this.functionNodeDependencies={},this.functionCalls={},this.rootNode&&(this.functionMap.kernel=this.rootNode),this.functionNodes)for(let e=0;e-1)return-1===t.indexOf(e)&&t.push(e),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.runningContexts[this.runningContexts.length-1]:null}newContext(e){const t=Object.assign({},this.currentContext);this.contexts.push(t),this.runningContexts.push(t),e(),this.runningContexts.pop()}scan(e){if(Array.isArray(e))for(let t=0;t{this.scan(e.body)});break;case"AssignmentExpression":case"LogicalExpression":case"BinaryExpression":this.scan(e.left),this.scan(e.right);break;case"UpdateExpression":case"UnaryExpression":this.scan(e.argument);break;case"VariableDeclaration":this.scan(e.declarations);break;case"VariableDeclarator":const{currentContext:t}=this,r={ast:e,context:t,name:e.id.name,origin:"declaration",forceInteger:this.inLoopInit,assignable:!this.inLoopInit&&!t.hasOwnProperty(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":this.newContext(()=>{this.inLoopInit=!0,this.scan(e.init),this.inLoopInit=!1,this.scan(e.test),this.scan(e.update),this.newContext(()=>{this.scan(e.body)})});break;case"DoWhileStatement":case"WhileStatement":this.newContext(()=>{this.scan(e.body),this.scan(e.test)});break;case"Identifier":this.identifiers.push({context:this.currentContext,ast:e});break;case"ReturnStatement":this.returnStatements.push(e),this.scan(e.argument);break;case"MemberExpression":this.scan(e.object),this.scan(e.property);break;case"ExpressionStatement":this.scan(e.expression);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":this.scan(e.left),this.scan(e.right);break;case"Literal":case"DebuggerStatement":case"EmptyStatement":case"BreakStatement":case"ContinueStatement":break;default:throw new Error(`unhandled type "${e.type}"`)}}}class O{constructor(e,t){if(!e&&!t.ast)throw new Error("source parameter is missing");if(t=t||{},this.source=e,this.ast=null,this.name="string"==typeof e?t.isRootKernel?"kernel":t.name||m(e):null,this.calledFunctions=[],this.constants={},this.constantTypes={},this.constantBitRatios={},this.isRootKernel=!1,this.isSubKernel=!1,this.debug=null,this.declarations=null,this.functions=null,this.identifiers=null,this.contexts=null,this.functionCalls=null,this.states=[],this.needsArgumentType=null,this.assignArgumentType=null,this.lookupReturnType=null,this.lookupFunctionArgumentTypes=null,this.lookupFunctionArgumentBitRatio=null,this.triggerImplyArgumentType=null,this.triggerImplyArgumentBitRatio=null,this.onNestedFunction=null,this.onFunctionCall=null,this.optimizeFloatMemory=null,this.precision=null,this.loopMaxIterations=null,this.argumentNames="string"==typeof this.source?y(this.source):null,this.argumentTypes=[],this.argumentSizes=[],this.argumentBitRatios=null,this.returnType=null,this.output=[],this.plugins=null,this.leadingReturnStatement=null,this.followingReturnStatement=null,this.dynamicOutput=null,this.dynamicArguments=null,this.strictTypingChecking=!1,this.fixIntegerDivisionAccuracy=null,this.warnVarUsage=!0,t)for(const e in t)t.hasOwnProperty(e)&&this.hasOwnProperty(e)&&(this[e]=t[e]);this.literalTypes={},this.validate(),this._string=null,this._internalVariableNames={}}validate(){if("string"!=typeof this.source&&!this.ast)throw new Error("this.source not a string");if(!this.ast&&!x(this.source))throw new Error("this.source not a function string");if(!this.name)throw new Error("this.name could not be set");if(this.argumentTypes.length>0&&this.argumentTypes.length!==this.argumentNames.length)throw new Error(`argumentTypes count of ${this.argumentTypes.length} exceeds ${this.argumentNames.length}`);if(this.output.length<1)throw new Error("this.output is not big enough")}isIdentifierConstant(e){return!!this.constants&&this.constants.hasOwnProperty(e)}isInput(e){return"Input"===this.argumentTypes[this.argumentNames.indexOf(e)]}pushState(e){this.states.push(e)}popState(e){if(this.state!==e)throw new Error(`Cannot popState ${e} when in ${this.state}`);this.states.pop()}isState(e){return this.state===e}get state(){return this.states[this.states.length-1]}astMemberExpressionUnroll(e){if("Identifier"===e.type)return e.name;if("ThisExpression"===e.type)return"this";if("MemberExpression"===e.type&&e.object&&e.property)return e.object.hasOwnProperty("name")&&"_"===e.object.name[0]?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(t){if(this.ast)return this.ast;if("object"==typeof this.source)return this.traceFunctionAST(this.source),this.ast=this.source;const r=t&&t.hasOwnProperty("parse")?t.parse:e.parse;if(null===t)throw new Error("Missing JS to AST parser");const n=Object.freeze(r(`const parser_${this.name} = ${this.source};`,{locations:!0})),i=n.body[0].declarations[0].init;if(this.traceFunctionAST(i),!n)throw new Error("Failed to parse JS code");return this.ast=i}traceFunctionAST(e){const{contexts:t,declarations:r,functions:n,identifiers:i,functionCalls:s}=new z(e);this.contexts=t,this.identifiers=i,this.functionCalls=s,this.declarations=[],this.functions=n;for(let e=0;e":case"<":return"Boolean";case"&":case"|":case"^":case"<<":case">>":case">>>":return"Integer"}const r=this.getType(e.left);if(this.isState("skip-literal-correction"))return r;if("LiteralInteger"===r){const t=this.getType(e.right);return"LiteralInteger"===t?e.left.value%1==0?"Integer":"Float":t}return C[r]||r;case"UpdateExpression":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","asin","atan","atan2","ceil","cos","exp","floor","log","log2","max","min","pow","random","round","sign","sin","sqrt","tan"].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":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;default:throw this.astErrorOutput(`Unhandled type ${e.type} in getDependencies`,e)}return t}getVariableSignature(e){if(!this.isAstVariable(e))throw new Error(`ast of type "${e.type}" is not a variable signature`);if("Identifier"===e.type)return"value";const t=[];for(;e;)e.computed?t.push("[]"):"ThisExpression"===e.type?t.unshift("this"):e.property&&e.property.name?"x"===e.property.name||"y"===e.property.name||"z"===e.property.name?t.unshift(".value"):"constants"===e.property.name||"thread"===e.property.name||"output"===e.property.name?t.unshift("."+e.property.name):t.unshift(".value"):e.name?t.unshift("value"):e.callee&&e.callee.name?t.unshift("fn()"):e.elements?t.unshift("[]"):t.unshift("unknown"),e=e.object;const r=t.join("");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 r=0;r0?n[n.length-1]:0;return new Error(`${e} on line ${n.length}, position ${i.length}:\n ${r}`)}astDebuggerStatement(e,t){return t}astConditionalExpression(e,t){if("ConditionalExpression"!==e.type)throw this.astErrorOutput("Not a conditional expression",e);return t.push("("),this.astGeneric(e.test,t),t.push("?"),this.astGeneric(e.consequent,t),t.push(":"),this.astGeneric(e.alternate,t),t.push(")"),t}astFunction(e,t){throw new Error(`"astFunction" not defined on ${this.constructor.name}`)}astFunctionDeclaration(e,t){return this.isChildFunction(e)?t:this.astFunction(e,t)}astFunctionExpression(e,t){return this.isChildFunction(e)?t:this.astFunction(e,t)}isChildFunction(e){for(let t=0;t0&&t.push(","),this.astGeneric(e.expressions,t);return t}astUnaryExpression(e,t){return this.checkAndUpconvertBitwiseUnary(e,t)?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{name:t=e.object.name,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{name:t=e.object.object.name,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{name:t=e.object.object.object.name,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{name:t=e.object.object.object.object.name,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{name:t=e.property.name,origin:"Math",type:"Number",signature:n};switch(e.property.name){case"r":case"g":case"b":case"a":return{name:t=e.object.name,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)))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)))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)))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)))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"[][]":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&&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 new 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(","),this.astGeneric(r[e],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?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":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;default:throw this.astErrorOutput("Unexpected expression",e)}if(!e.computed)switch(n){case"Number":case"Integer":case"Float":case"Boolean":return t.push(`${l}_${u}`),t}const h=`${l}_${u}`;switch(n){case"Array(2)":case"Array(3)":case"Array(4)":case"HTMLImageArray":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":case"HTMLImage":default:let e,r;if("constants"===l){const t=this.constants[u];e=(r="Input"===this.constantTypes[u])?t.size:null}else e=(r=this.isInput(u))?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=e.elements.length;t.push("new Float32Array([");for(let n=0;n0&&t.push(", ");const r=e.elements[n];this.astGeneric(r,t)}return t.push("])"),t}astDebuggerStatement(e,t){return t.push("debugger;"),t}}function k(e,t){const r=[],n=[],i=[],s=!/^function/.test(e.color.toString());if(r.push(" const { context, canvas, constants: incomingConstants } = settings;",` const output = new Int32Array(${JSON.stringify(Array.from(e.output))});`,` const _constantTypes = ${JSON.stringify(e.constantTypes)};`,` const _constants = ${function(e,t){const r=[];for(const n in t){if(!t.hasOwnProperty(n))continue;const i=t[n],s=e[n];switch(i){case"Number":case"Integer":case"Float":case"Boolean":r.push(`${n}:${s}`);break;case"Array(2)":case"Array(3)":case"Array(4)":r.push(`${n}:new ${s.constructor.name}(${JSON.stringify(Array.from(s))})`)}}return`{ ${r.join()} }`}(e.constants,e.constantTypes)};`),n.push(" constants: _constants,"," context,"," output,"," thread: {x: 0, y: 0, z: 0},"),e.graphical){r.push(` const _imageData = context.createImageData(${e.output[0]}, ${e.output[1]});`),r.push(` const _colorData = new Uint8ClampedArray(${e.output[0]} * ${e.output[1]} * 4);`);const t=R.flattenFunctionToString((s?"function ":"")+e.color.toString(),{thisLookup:t=>{switch(t){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(e[t])},findDependency:(e,t)=>null}),a=R.flattenFunctionToString((s?"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});n.push(" _imageData,"," _colorData,",` color: ${t},`),i.push(` kernel.getPixels = ${a};`)}const a=[],o=Object.keys(e.constantTypes);for(let t=0;t"this"===t?(s?"function ":"")+e[r].toString():null,thisLookup:e=>{switch(e){case"canvas":return;case"context":return"context"}}});i.push(t),n.push(" _mediaTo2DArray,"),n.push(" _imageTo3DArray,")}else if(-1!==e.argumentTypes.indexOf("HTMLImage")||-1!==a.indexOf("HTMLImage")){const t=R.flattenFunctionToString((s?"function ":"")+e._mediaTo2DArray.toString(),{findDependency:(e,t)=>null,thisLookup:e=>{switch(e){case"canvas":return"settings.canvas";case"context":return"settings.context"}throw new Error("unhandled thisLookup")}});i.push(t),n.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 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({ ${n.join("\n")} });\n ${i.join("\n")}\n return kernel;\n}`}class M extends I{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(){return null}static combineKernels(e){return e}constructor(e,t){super(e,t),this.mergeSettings(e.settings||t),this._imageData=null,this._colorData=null,this._kernelString=null,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=R.getVariableType(e[0],this.strictIntegers);if("Array"===t)this.output=R.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=F.fromKernel(this,N);this.translatedSources=e.getPrototypes("kernel"),this.graphical||this.returnType||(this.returnType=e.getKernelResultType())}build(){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)}}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._processConstants()}\n return (${this.argumentNames.map(e=>"user_"+e).join(", ")}) => {\n ${this._processArguments()}\n ${this.graphical?this._graphicalKernelBody(e):this._resultKernelBody(e)}\n ${t.length>0?t.join("\n"):""}\n };`}toString(){return k(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"HTMLImage":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("")}_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 }`}_resultKernel2DLoop(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 }`}_graphicalKernel2DLoop(e){const t=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\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 ${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 }`}_resultKernel3DLoop(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 }`}_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=F.fromKernel(this,N).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))}}class U extends v{constructor(e){super(e),this.type="ArrayTexture(1)"}renderRawOutput(){const{context:e}=this,t=e.createFramebuffer();e.bindFramebuffer(e.FRAMEBUFFER,t),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture,0);const r=new Float32Array(this.size[0]*this.size[1]*4);return e.readPixels(0,0,this.size[0],this.size[1],e.RGBA,e.FLOAT,r),r}renderValues(){return this.renderRawOutput()}toArray(){return R.erectFloat(this.renderValues(),this.output[0])}}class P extends U{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return R.erectArray2(this.renderValues(),this.output[0],this.output[1])}}class L extends U{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return R.erect2DArray2(this.renderValues(),this.output[0],this.output[1])}}class V extends U{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return R.erect3DArray2(this.renderValues(),this.output[0],this.output[1],this.output[2])}}class K extends U{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return R.erectArray3(this.renderValues(),this.output[0])}}class G extends U{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return R.erect2DArray3(this.renderValues(),this.output[0],this.output[1])}}class B extends U{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return R.erect3DArray3(this.renderValues(),this.output[0],this.output[1],this.output[2])}}class X extends U{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return R.erectArray4(this.renderValues(),this.output[0])}}class j extends U{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return R.erect2DArray4(this.renderValues(),this.output[0],this.output[1])}}class H extends U{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return R.erect3DArray4(this.renderValues(),this.output[0],this.output[1],this.output[2])}}class W extends U{constructor(e){super(e),this.type="ArrayTexture(1)"}toArray(){return R.erect2DFloat(this.renderValues(),this.output[0],this.output[1])}}class q extends U{constructor(e){super(e),this.type="ArrayTexture(1)"}toArray(){return R.erect3DFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}class Y extends U{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return R.erectMemoryOptimizedFloat(this.renderValues(),this.output[0])}}class J extends U{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return R.erectMemoryOptimized2DFloat(this.renderValues(),this.output[0],this.output[1])}}class Z extends U{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return R.erectMemoryOptimized3DFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}class Q extends v{constructor(e){super(e),this.type="NumberTexture"}renderRawOutput(){const{context:e}=this,t=e.createFramebuffer();e.bindFramebuffer(e.FRAMEBUFFER,t),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture,0);const r=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,r),r}renderValues(){return new Float32Array(this.renderRawOutput().buffer)}toArray(){return R.erectPackedFloat(this.renderValues(),this.output[0])}}class ee extends Q{constructor(e){super(e),this.type="NumberTexture"}toArray(){return R.erect2DPackedFloat(this.renderValues(),this.output[0],this.output[1])}}class te extends Q{constructor(e){super(e),this.type="NumberTexture"}toArray(){return R.erect3DPackedFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}class re extends Q{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return this.renderValues()}}class ne extends I{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 get testCanvas(){throw new Error(`"testCanvas" not defined on ${this.name}`)}static get testContext(){throw new Error(`"testContext" not defined on ${this.name}`)}static get features(){throw new Error(`"features" not defined on ${this.name}`)}static setupFeatureChecks(){throw new Error(`"setupFeatureChecks" not defined on ${this.name}`)}setFixIntegerDivisionAccuracy(e){return this.fixIntegerDivisionAccuracy=e,this}setPrecision(e){return this.precision=e,this}setFloatTextures(e){return R.warnDeprecated("method","setFloatTextures","setOptimizeFloatMemory"),this.floatTextures=e,this}static nativeFunctionArguments(e){const t=[],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(se[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 se[e.match(/int|float|vec[2-4]/)[0]]}static combineKernels(e,t){e.apply(null,arguments);const{texSize:r,context:n,threadDim:i}=t.texSize;let s;if("single"===t.precision){const e=r[0],t=Math.ceil(r[1]/4);s=new Float32Array(e*t*4*4),n.readPixels(0,0,e,4*t,n.RGBA,n.FLOAT,s)}else{const e=new Uint8Array(r[0]*r[1]*4);n.readPixels(0,0,r[0],r[1],n.RGBA,n.UNSIGNED_BYTE,e),s=new Float32Array(e.buffer)}if(s=s.subarray(0,i[0]*i[1]*i[2]),1===t.output.length)return s;if(2===t.output.length)return R.splitArray(s,t.output[0]);if(3===t.output.length){return R.splitArray(s,t.output[0]*t.output[1]).map((function(e){return R.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.renderStrategy=null,this.compiledFragmentShader=null,this.compiledVertexShader=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=re,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=te,this.renderStrategy=ie.PackedPixelTo3DFloat,null):this.output[1]>0?(this.TextureConstructor=ee,this.renderStrategy=ie.PackedPixelTo2DFloat,null):(this.TextureConstructor=Q,this.renderStrategy=ie.PackedPixelToFloat,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=te,this.renderStrategy=ie.PackedPixelTo3DFloat,this.formatValues=R.erect3DPackedFloat,null):this.output[1]>0?(this.TextureConstructor=ee,this.renderStrategy=ie.PackedPixelTo2DFloat,this.formatValues=R.erect2DPackedFloat,null):(this.TextureConstructor=Q,this.renderStrategy=ie.PackedPixelToFloat,this.formatValues=R.erectPackedFloat,null);case"Array(2)":case"Array(3)":case"Array(4)":return this.requestFallback(e)}else{if("single"!==this.precision)throw new Error(`unhandled precision of "${this.precision}"`);if(this.renderRawOutput=this.readFloatPixelsToFloat32Array,this.transferValues=this.readFloatPixelsToFloat32Array,this.pipeline)switch(this.renderStrategy=ie.FloatTexture,this.renderOutput=this.renderTexture,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToTextures),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.optimizeFloatMemory?this.output[2]>0?(this.TextureConstructor=Z,null):this.output[1]>0?(this.TextureConstructor=J,null):(this.TextureConstructor=Y,null):this.output[2]>0?(this.TextureConstructor=q,null):this.output[1]>0?(this.TextureConstructor=W,null):(this.TextureConstructor=U,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=V,null):this.output[1]>0?(this.TextureConstructor=L,null):(this.TextureConstructor=P,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=B,null):this.output[1]>0?(this.TextureConstructor=G,null):(this.TextureConstructor=K,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=H,null):this.output[1]>0?(this.TextureConstructor=j,null):(this.TextureConstructor=X,null)}if(this.renderOutput=this.renderValues,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToArrays),this.optimizeFloatMemory)switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=Z,this.renderStrategy=ie.MemoryOptimizedFloatPixelToMemoryOptimized3DFloat,this.formatValues=R.erectMemoryOptimized3DFloat,null):this.output[1]>0?(this.TextureConstructor=J,this.renderStrategy=ie.MemoryOptimizedFloatPixelToMemoryOptimized2DFloat,this.formatValues=R.erectMemoryOptimized2DFloat,null):(this.TextureConstructor=Y,this.renderStrategy=ie.MemoryOptimizedFloatPixelToMemoryOptimizedFloat,this.formatValues=R.erectMemoryOptimizedFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=V,this.renderStrategy=ie.FloatPixelTo3DArray2,this.formatValues=R.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=L,this.renderStrategy=ie.FloatPixelTo2DArray2,this.formatValues=R.erect2DArray2,null):(this.TextureConstructor=P,this.renderStrategy=ie.FloatPixelToArray2,this.formatValues=R.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=B,this.renderStrategy=ie.FloatPixelTo3DArray3,this.formatValues=R.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=G,this.renderStrategy=ie.FloatPixelTo2DArray3,this.formatValues=R.erect2DArray3,null):(this.TextureConstructor=K,this.renderStrategy=ie.FloatPixelToArray3,this.formatValues=R.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=H,this.renderStrategy=ie.FloatPixelTo3DArray4,this.formatValues=R.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=j,this.renderStrategy=ie.FloatPixelTo2DArray4,this.formatValues=R.erect2DArray4,null):(this.TextureConstructor=X,this.renderStrategy=ie.FloatPixelToArray4,this.formatValues=R.erectArray4,null)}else switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=q,this.renderStrategy=ie.FloatPixelTo3DFloat,this.formatValues=R.erect3DFloat,null):this.output[1]>0?(this.TextureConstructor=W,this.renderStrategy=ie.FloatPixelTo2DFloat,this.formatValues=R.erect2DFloat,null):(this.TextureConstructor=U,this.renderStrategy=ie.FloatPixelToFloat,this.formatValues=R.erectFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=V,this.renderStrategy=ie.FloatPixelTo3DArray2,this.formatValues=R.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=L,this.renderStrategy=ie.FloatPixelTo2DArray2,this.formatValues=R.erect2DArray2,null):(this.TextureConstructor=P,this.renderStrategy=ie.FloatPixelToArray2,this.formatValues=R.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=B,this.renderStrategy=ie.FloatPixelTo3DArray3,this.formatValues=R.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=G,this.renderStrategy=ie.FloatPixelTo2DArray3,this.formatValues=R.erect2DArray3,null):(this.TextureConstructor=K,this.renderStrategy=ie.FloatPixelToArray3,this.formatValues=R.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=H,this.renderStrategy=ie.FloatPixelTo3DArray4,this.formatValues=R.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=j,this.renderStrategy=ie.FloatPixelTo2DArray4,this.formatValues=R.erect2DArray4,null):(this.TextureConstructor=X,this.renderStrategy=ie.FloatPixelToArray4,this.formatValues=R.erectArray4,null)}}throw new Error(`unhandled return type "${this.returnType}"`)}getKernelString(){throw new Error("abstract method call")}getMainResultTexture(){switch(this.returnType){case"LiteralInteger":case"Float":case"Integer":case"Number":return this.getMainResultNumberTexture();case"Array(2)":return this.getMainResultArray2Texture();case"Array(3)":return this.getMainResultArray3Texture();case"Array(4)":return this.getMainResultArray4Texture();default:throw new Error(`unhandled returnType type ${this.returnType}`)}}getMainResultKernelNumberTexture(){throw new Error("abstract method call")}getMainResultSubKernelNumberTexture(){throw new Error("abstract method call")}getMainResultKernelArray2Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray2Texture(){throw new Error("abstract method call")}getMainResultKernelArray3Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray3Texture(){throw new Error("abstract method call")}getMainResultKernelArray4Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray4Texture(){throw new Error("abstract method call")}getMainResultGraphical(){throw new Error("abstract method call")}getMainResultMemoryOptimizedFloats(){throw new Error("abstract method call")}getMainResultPackedPixels(){throw new Error("abstract method call")}getMainResultString(){return this.graphical?this.getMainResultGraphical():"single"===this.precision?this.optimizeFloatMemory?this.getMainResultMemoryOptimizedFloats():this.getMainResultTexture():this.getMainResultPackedPixels()}getMainResultNumberTexture(){return R.linesToString(this.getMainResultKernelNumberTexture())+R.linesToString(this.getMainResultSubKernelNumberTexture())}getMainResultArray2Texture(){return R.linesToString(this.getMainResultKernelArray2Texture())+R.linesToString(this.getMainResultSubKernelArray2Texture())}getMainResultArray3Texture(){return R.linesToString(this.getMainResultKernelArray3Texture())+R.linesToString(this.getMainResultSubKernelArray3Texture())}getMainResultArray4Texture(){return R.linesToString(this.getMainResultKernelArray4Texture())+R.linesToString(this.getMainResultSubKernelArray4Texture())}getFloatTacticDeclaration(){switch(this.tactic){case"speed":return"precision lowp float;\n";case"performance":return"precision highp float;\n";case"balanced":default:return"precision mediump float;\n"}}getIntTacticDeclaration(){switch(this.tactic){case"speed":return"precision lowp int;\n";case"performance":return"precision highp int;\n";case"balanced":default:return"precision mediump int;\n"}}getSampler2DTacticDeclaration(){switch(this.tactic){case"speed":return"precision lowp sampler2D;\n";case"performance":return"precision highp sampler2D;\n";case"balanced":default:return"precision mediump sampler2D;\n"}}getSampler2DArrayTacticDeclaration(){switch(this.tactic){case"speed":return"precision lowp sampler2DArray;\n";case"performance":return"precision highp sampler2DArray;\n";case"balanced":default:return"precision mediump sampler2DArray;\n"}}renderTexture(){return new this.TextureConstructor({texture:this.outputTexture,size:this.texSize,dimensions:this.threadDim,output:this.output,context:this.context})}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}readMemoryOptimizedFloatPixelsToFloat32Array(){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,i]=r,s=new Uint8Array(n*i*4);return t.readPixels(0,0,n,i,t.RGBA,t.UNSIGNED_BYTE,s),new Uint8ClampedArray((e?s:R.flipPixels(s,n,i)).buffer)}renderKernelsToArrays(){const e={result:this.renderOutput()};for(let t=0;t0&&this._setupSubOutputTextures()}return this}renderValues(){return this.formatValues(this.transferValues(),this.output[0],this.output[1],this.output[2])}}const ie=Object.freeze({PackedPixelToUint8Array:Symbol("PackedPixelToUint8Array"),PackedPixelToFloat:Symbol("PackedPixelToFloat"),PackedPixelTo2DFloat:Symbol("PackedPixelTo2DFloat"),PackedPixelTo3DFloat:Symbol("PackedPixelTo3DFloat"),PackedTexture:Symbol("PackedTexture"),FloatPixelToFloat32Array:Symbol("FloatPixelToFloat32Array"),FloatPixelToFloat:Symbol("FloatPixelToFloat"),FloatPixelTo2DFloat:Symbol("FloatPixelTo2DFloat"),FloatPixelTo3DFloat:Symbol("FloatPixelTo3DFloat"),FloatPixelToArray2:Symbol("FloatPixelToArray2"),FloatPixelTo2DArray2:Symbol("FloatPixelTo2DArray2"),FloatPixelTo3DArray2:Symbol("FloatPixelTo3DArray2"),FloatPixelToArray3:Symbol("FloatPixelToArray3"),FloatPixelTo2DArray3:Symbol("FloatPixelTo2DArray3"),FloatPixelTo3DArray3:Symbol("FloatPixelTo3DArray3"),FloatPixelToArray4:Symbol("FloatPixelToArray4"),FloatPixelTo2DArray4:Symbol("FloatPixelTo2DArray4"),FloatPixelTo3DArray4:Symbol("FloatPixelTo3DArray4"),FloatTexture:Symbol("FloatTexture"),MemoryOptimizedFloatPixelToMemoryOptimizedFloat:Symbol("MemoryOptimizedFloatPixelToFloat"),MemoryOptimizedFloatPixelToMemoryOptimized2DFloat:Symbol("MemoryOptimizedFloatPixelTo2DFloat"),MemoryOptimizedFloatPixelToMemoryOptimized3DFloat:Symbol("MemoryOptimizedFloatPixelTo3DFloat")}),se={int:"Integer",float:"Number",vec2:"Array(2)",vec3:"Array(3)",vec4:"Array(4)"};class ae extends O{constructor(e,t){super(e,t),t&&t.hasOwnProperty("fixIntegerDivisionAccuracy")&&(this.fixIntegerDivisionAccuracy=t.fixIntegerDivisionAccuracy)}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=oe[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 i=this.argumentTypes[this.argumentNames.indexOf(n)];if(!i)throw this.astErrorOutput(`Unknown argument ${n} type`,e);"LiteralInteger"===i&&(this.argumentTypes[r]=i="Number");const s=oe[i];if(!s)throw this.astErrorOutput("Unexpected expression",e);t.push(s),t.push(" "),t.push("user_"),t.push(n)}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(ue[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(ue[e.operator]||e.operator),this.pushState("casting-to-integer"),"Literal"===e.right.type){const r=[];if(this.astGeneric(e.right,r),"Integer"!==this.getType(e.right))throw this.astErrorOutput("Unhandled binary expression with literal",e);t.push(r.join(""))}else t.push("int("),this.astGeneric(e.right,t),t.push(")");this.popState("casting-to-integer"),this.popState("building-integer");break;case"Integer & LiteralInteger":this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(ue[e.operator]||e.operator),this.castLiteralToInteger(e.right,t),this.popState("building-integer");break;case"Number & Integer":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(ue[e.operator]||e.operator),this.castValueToFloat(e.right,t),this.popState("building-float");break;case"Float & LiteralInteger":case"Number & LiteralInteger":this.isState("in-for-loop-test")?(this.pushState("building-integer"),t.push("int("),this.astGeneric(e.left,t),t.push(")"),t.push(ue[e.operator]||e.operator),this.castLiteralToInteger(e.right,t),this.popState("building-integer")):(this.pushState("building-float"),this.astGeneric(e.left,t),t.push(ue[e.operator]||e.operator),this.castLiteralToFloat(e.right,t),this.popState("building-float"));break;case"LiteralInteger & Float":case"LiteralInteger & Number":this.isState("in-for-loop-test")||this.isState("in-for-loop-init")||this.isState("casting-to-integer")?(this.pushState("building-integer"),this.castLiteralToInteger(e.left,t),t.push(ue[e.operator]||e.operator),this.castValueToInteger(e.right,t),this.popState("building-integer")):(this.pushState("building-float"),this.astGeneric(e.left,t),t.push(ue[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(ue[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(ue[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-boolean");break;case"Float & Integer":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(ue[e.operator]||e.operator),this.castValueToFloat(e.right,t),this.popState("building-float");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={"%":"mod","**":"pow"}[e.operator];if(!n)return null;switch(t.push(n),t.push("("),this.getType(e.left)){case"Integer":this.castValueToFloat(e.left,t);break;case"LiteralInteger":this.castLiteralToFloat(e.left,t);break;default:this.astGeneric(e.left,t)}switch(t.push(","),this.getType(e.right)){case"Integer":this.castValueToFloat(e.right,t);break;case"LiteralInteger":this.castLiteralToFloat(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseOperators(e,t){const r={"&":"bitwiseAnd","|":"bitwiseOr","^":"bitwiseXOR","<<":"bitwiseZeroFillLeftShift",">>":"bitwiseSignedRightShift",">>>":"bitwiseZeroFillRightShift"}[e.operator];if(!r)return null;switch(t.push(r),t.push("("),this.getType(e.left)){case"Number":case"Float":this.castValueToInteger(e.left,t);break;case"LiteralInteger":this.castLiteralToInteger(e.left,t);break;default:this.astGeneric(e.left,t)}switch(t.push(","),this.getType(e.right)){case"Number":case"Float":this.castValueToInteger(e.right,t);break;case"LiteralInteger":this.castLiteralToInteger(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseUnary(e,t){const r={"~":"bitwiseNot"}[e.operator];if(!r)return null;switch(t.push(r),t.push("("),this.getType(e.argument)){case"Number":case"Float":this.castValueToInteger(e.argument,t);break;case"LiteralInteger":this.castLiteralToInteger(e.argument,t);break;default:this.astGeneric(e.argument,t)}return t.push(")"),t}castLiteralToInteger(e,t){return this.pushState("casting-to-integer"),this.astGeneric(e,t),this.popState("casting-to-integer"),t}castLiteralToFloat(e,t){return this.pushState("casting-to-float"),this.astGeneric(e,t),this.popState("casting-to-float"),t}castValueToInteger(e,t){return this.pushState("casting-to-integer"),t.push("int("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-integer"),t}castValueToFloat(e,t){return this.pushState("casting-to-float"),t.push("float("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-float"),t}astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const r=this.getType(e);return"Infinity"===e.name?t.push("3.402823466e+38"):"Boolean"===r&&this.argumentNames.indexOf(e.name)>-1?t.push(`bool(user_${e.name})`):t.push(`user_${e.name}`),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){this.pushState("in-for-loop-init"),this.astGeneric(e.init,r);const{declarations:t}=e.init;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}e+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:n,signature:i,origin:s,type:a,xProperty:o,yProperty:u,zProperty:l}=this.getMemberExpressionDetails(e);switch(i){case"value.thread.value":case"this.thread.value":if("x"!==n&&"y"!==n&&"z"!==n)throw this.astErrorOutput("Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`",e);return t.push(`threadId.${n}`),t;case"this.output.value":if(this.dynamicOutput)switch(n){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(n){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"===s)return t.push(Math[n]),t;switch(r){case"r":return t.push(`user_${n}.r`),t;case"g":return t.push(`user_${n}.g`),t;case"b":return t.push(`user_${n}.b`),t;case"a":return t.push(`user_${n}.a`),t}break;case"this.constants.value":if(void 0===o)switch(a){case"Array(2)":case"Array(3)":case"Array(4)":return t.push(`constants_${n}`),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"[][]":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(a){case"Number":case"Integer":case"Float":case"Boolean":return t.push(`${s}_${n}`),t}const h=`${s}_${n}`;switch(a){case"Array(2)":case"Array(3)":case"Array(4)":this.astGeneric(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(o)),t.push("]");break;case"HTMLImageArray":t.push(`getImage3D(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"ArrayTexture(1)":t.push(`getFloatFromSampler2D(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"Array1D(2)":case"Array2D(2)":case"Array3D(2)":t.push(`getMemoryOptimizedVec2(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"ArrayTexture(2)":t.push(`getVec2FromSampler2D(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"Array1D(3)":case"Array2D(3)":case"Array3D(3)":t.push(`getMemoryOptimizedVec3(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"ArrayTexture(3)":t.push(`getVec3FromSampler2D(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"Array1D(4)":case"Array2D(4)":case"Array3D(4)":t.push(`getMemoryOptimizedVec4(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"ArrayTexture(4)":case"HTMLImage":case"HTMLVideo":t.push(`getVec4FromSampler2D(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"NumberTexture":case"Array":case"Array2D":case"Array3D":case"Array4D":case"Input":case"Number":case"Float":case"Integer":if("single"===this.precision)t.push(`getMemoryOptimized32(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");else{const e="user"===s?this.lookupFunctionArgumentBitRatio(this.name,n):this.constantBitRatios[n];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(o,u,l,t),t.push(")")}break;case"MemoryOptimizedNumberTexture":t.push(`getMemoryOptimized32(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;default:throw new Error(`unhandled member expression "${a}"`)}return t}astCallExpression(e,t){if(!e.callee)throw this.astErrorOutput("Unknown CallExpression",e);let r=null;const n=this.isAstMathFunction(e);if(!(r=n||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))throw this.astErrorOutput("Unhandled function, couldn't find name",e);if("atan2"===r&&(r="atan"),this.calledFunctions.indexOf(r)<0&&this.calledFunctions.push(r),"random"===r&&this.plugins&&this.plugins.length>0)for(let e=0;e0&&t.push(", "),i){case"Integer":this.castValueToFloat(n,t);break;default:this.astGeneric(n,t)}}else{const n=this.lookupFunctionArgumentTypes(r)||[];for(let i=0;i0&&t.push(", ");const o=this.getType(s);switch(a||(this.triggerImplyArgumentType(r,i,o,this),a=o),o){case"Number":case"Float":if("Integer"===a){t.push("int("),this.astGeneric(s,t),t.push(")");continue}if("Number"===a||"Float"===a){this.astGeneric(s,t);continue}if("LiteralInteger"===a){this.castLiteralToFloat(s,t);continue}break;case"Integer":if("Number"===a||"Float"===a){t.push("float("),this.astGeneric(s,t),t.push(")");continue}if("Integer"===a){this.astGeneric(s,t);continue}break;case"LiteralInteger":if("Integer"===a){this.castLiteralToInteger(s,t);continue}if("Number"===a||"Float"===a){this.castLiteralToFloat(s,t);continue}if("LiteralInteger"===a){this.astGeneric(s,t);continue}break;case"Array(2)":case"Array(3)":case"Array(4)":if(a===o){if("Identifier"!==s.type)throw this.astErrorOutput(`Unhandled argument type ${s.type}`,e);this.triggerImplyArgumentBitRatio(this.name,s.name,r,i),t.push(`user_${s.name}`);continue}break;case"HTMLImage":case"HTMLImageArray":case"HTMLVideo":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":case"Array":case"Input":if(a===o){if("Identifier"!==s.type)throw this.astErrorOutput(`Unhandled argument type ${s.type}`,e);this.triggerImplyArgumentBitRatio(this.name,s.name,r,i),t.push(`user_${s.name},user_${s.name}Size,user_${s.name}Dim`);continue}}throw this.astErrorOutput(`Unhandled argument combination of ${o} and ${a} for argument named "${s.name}"`,e)}}return t.push(")"),t}astArrayExpression(e,t){const r=e.elements.length;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,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("")}}const oe={Array:"sampler2D","Array(2)":"vec2","Array(3)":"vec3","Array(4)":"vec4",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",HTMLImage:"sampler2D",HTMLImageArray:"sampler2DArray"},ue={"===":"==","!==":"!="};var le={name:"triangle-noise-noise",onBeforeRun:e=>{e.setUniform1f("triangle_noise_seed",Math.random())},functionMatch:"Math.random()",functionReplace:"n4rand(vTexCoord)",functionReturnType:"Number",source:"\n\nuniform highp float triangle_noise_seed;\nhighp float triangle_noise_shift = 0.000001;\n\n//https://www.shadertoy.com/view/4t2SDh\n//note: uniformly distributed, normalized rand, [0;1[\nfloat nrand( vec2 n )\n{\n return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453);\n}\n//note: remaps v to [0;1] in interval [a;b]\nfloat remap( float a, float b, float v )\n{\n return clamp( (v-a) / (b-a), 0.0, 1.0 );\n}\n\nfloat n4rand( vec2 n )\n{\n float t = fract( triangle_noise_seed + triangle_noise_shift );\n float nrnd0 = nrand( n + 0.07*t );\n float nrnd1 = nrand( n + 0.11*t );\n float nrnd2 = nrand( n + 0.13*t );\n float nrnd3 = nrand( n + 0.17*t );\n float result = (nrnd0+nrnd1+nrnd2+nrnd3) / 4.0;\n triangle_noise_shift = result + 0.000001;\n return result;\n}"};const he="__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\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\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}",ce="__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}";var pe=function(e,t){return e(t={exports:{}},t.exports),t.exports}((function(e){function t(e,t={}){const{contextName:s="gl",throwGetError:a,useTrackablePrimitives:o,readPixelsFile:u,recording:l=[],variables:h={},onReadPixels:c,onUnrecognizedArgumentLookup:p}=t,d=new Proxy(e,{get:function(t,d){switch(d){case"addComment":return D;case"checkThrowError":return $;case"getReadPixelsVariableName":return f;case"insertVariable":return A;case"reset":return b;case"setIndent":return S;case"toString":return T;case"getContextVariableName":return I}if("function"==typeof e[d])return function(){switch(d){case"getError":return a?l.push(`${y}if (${s}.getError() !== ${s}.NONE) throw new Error('error');`):l.push(`${y}${s}.getError();`),e.getError();case"getExtension":{const t=`${s}Variables${m.length}`;l.push(`${y}const ${t} = ${s}.getExtension('${arguments[0]}');`);const n=e.getExtension(arguments[0]);if(n&&"object"==typeof n){const e=r(n,{getEntity:E,useTrackablePrimitives:o,recording:l,contextName:t,contextVariables:m,variables:h,indent:y,onUnrecognizedArgumentLookup:p});return m.push(e),e}return m.push(null),n}case"readPixels":const t=m.indexOf(arguments[6]);let i;if(-1===t){const e=R(arguments[6]);e?(i=e,l.push(`${y}${e}`)):(i=`${s}Variable${m.length}`,m.push(arguments[6]),l.push(`${y}const ${i} = new ${arguments[6].constructor.name}(${arguments[6].length});`))}else i=`${s}Variable${t}`;f=i;const d=[arguments[0],arguments[1],arguments[2],arguments[3],E(arguments[4]),E(arguments[5]),i];return l.push(`${y}${s}.readPixels(${d.join(", ")});`),u&&v(arguments[2],arguments[3]),c&&c(i,d),e.readPixels.apply(e,arguments);case"drawBuffers":return l.push(`${y}${s}.drawBuffers([${n(arguments[0],{contextName:s,contextVariables:m,getEntity:E,addVariable:_,variables:h,onUnrecognizedArgumentLookup:p})}]);`),e.drawBuffers(arguments[0])}let t=e[d].apply(e,arguments);switch(typeof t){case"undefined":return void l.push(`${y}${w(d,arguments)};`);case"number":case"boolean":if(o&&-1===m.indexOf(i(t))){l.push(`${y}const ${s}Variable${m.length} = ${w(d,arguments)};`),m.push(t=i(t));break}default:null===t?l.push(`${w(d,arguments)};`):l.push(`${y}const ${s}Variable${m.length} = ${w(d,arguments)};`),m.push(t)}return t};return g[e[d]]=d,e[d]}}),m=[],g={};let f,x=0,y="";return d;function T(){return l.join("\n")}function b(){for(;l.length>0;)l.pop()}function A(e,t){h[e]=t}function E(e){const t=g[e];return t?s+"."+t:e}function S(e){y=" ".repeat(e)}function _(e,t){const r=`${s}Variable${m.length}`;return l.push(`${y}const ${r} = ${t};`),m.push(e),r}function v(e,t){const r=`${s}Variable${m.length}`,n=`imageDatum${x}`;l.push(`${y}let ${n} = ["P3\\n# ${u}.ppm\\n", ${e}, ' ', ${t}, "\\n255\\n"].join("");`),l.push(`${y}for (let i = 0; i < ${n}.length; i += 4) {`),l.push(`${y} ${n} += ${r}[i] + ' ' + ${r}[i + 1] + ' ' + ${r}[i + 2] + ' ';`),l.push(`${y}}`),l.push(`${y}if (typeof require !== "undefined") {`),l.push(`${y} require('fs').writeFileSync('./${u}.ppm', ${n});`),l.push(`${y}}`),x++}function D(e){l.push(`${y}// ${e}`)}function $(){l.push(`${y}(() => {\n${y}const error = ${s}.getError();\n${y}if (error !== ${s}.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 (${s}[name] === error) {\n${y} throw new Error('${s} threw ' + name);\n${y} }\n${y} }\n${y}}\n${y}})();`)}function w(e,t){return`${s}.${e}(${n(t,{contextName:s,contextVariables:m,getEntity:E,addVariable:_,variables:h,onUnrecognizedArgumentLookup:p})})`}function R(e){if(h)for(const t in h)if(h[t]===e)return t;return null}function I(e){const t=m.indexOf(e);return-1!==t?`${s}Variable${t}`:null}}function r(e,t){const r=new Proxy(e,{get:function(t,r){if("function"==typeof t[r])return function(){switch(r){case"drawBuffersWEBGL":return h.push(`${p}${a}.drawBuffersWEBGL([${n(arguments[0],{contextName:a,contextVariables:o,getEntity:m,addVariable:f,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}${g(r,arguments)};`);case"number":case"boolean":l&&-1===o.indexOf(i(t))?(h.push(`${p}const ${a}Variable${o.length} = ${g(r,arguments)};`),o.push(t=i(t))):(h.push(`${p}const ${a}Variable${o.length} = ${g(r,arguments)};`),o.push(t));break;default:null===t?h.push(`${g(r,arguments)};`):h.push(`${p}const ${a}Variable${o.length} = ${g(r,arguments)};`),o.push(t)}return t};return s[e[r]]=r,e[r]}}),s={},{contextName:a,contextVariables:o,getEntity:u,useTrackablePrimitives:l,recording:h,variables:c,indent:p,onUnrecognizedArgumentLookup:d}=t;return r;function m(e){return s.hasOwnProperty(e)?`${a}.${s[e]}`:u(e)}function g(e,t){return`${a}.${e}(${n(t,{contextName:a,contextVariables:o,getEntity:m,addVariable:f,variables:c,onUnrecognizedArgumentLookup:d})})`}function f(e,t){const r=`${a}Variable${o.length}`;return o.push(e),h.push(`${p}const ${r} = ${t};`),r}}function n(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 i(e){return new e.constructor(e)}e.exports={glWiretap:t,glExtensionWiretap:r},"undefined"!=typeof window&&(t.glExtensionWiretap=r,window.glWiretap=t)})),de=pe.glWiretap;pe.glExtensionWiretap;function me(e){return e.toString().replace("=>","").replace(/^function /,"").replace(/utils[.]/g,"/*utils.*/")}function ge(e,t,r,n,i){t=t?Array.from(t).map(e=>{switch(typeof e){case"boolean":return new Boolean(e);case"number":return new Number(e);default:return e}}):null;const s=[],a=de(r.context,{useTrackablePrimitives:!0,onReadPixels:e=>{if($.subKernels){if(o){const t=$.subKernels[u++].property;s.push(` result${isNaN(t)?"."+t:`[${t}]`} = ${fe(e,$)};`)}else s.push(` const result = { result: ${fe(e,$)} };`),o=!0;u===$.subKernels.length&&s.push(" return result;")}else e?s.push(` return ${fe(e,$)};`):s.push(" return null;")},onUnrecognizedArgumentLookup:e=>{const t=ye(e,$.kernelArguments,[],a);if(t)return t;const r=ye(e,$.kernelConstants,g?Object.keys(g).map(e=>g[e]):[],a);return r||null}});let o=!1,u=0;const{source:l,canvas:h,output:c,pipeline:p,graphical:d,loopMaxIterations:m,constants:g,optimizeFloatMemory:f,precision:x,fixIntegerDivisionAccuracy:y,functions:T,nativeFunctions:b,subKernels:A,immutable:E,argumentTypes:S,constantTypes:_,kernelArguments:v,kernelConstants:D}=r,$=new e(l,{canvas:h,context:a,checkContext:!1,output:c,pipeline:p,graphical:d,loopMaxIterations:m,constants:g,optimizeFloatMemory:f,precision:x,fixIntegerDivisionAccuracy:y,functions:T,nativeFunctions:b,subKernels:A,immutable:E,argumentTypes:S,constantTypes:_});let w=[];if(a.setIndent(2),$.build.apply($,t),w.push(a.toString()),a.reset(),$.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"HTMLImage":case"HTMLVideo":a.insertVariable(`uploadValue_${e.name}`,e.uploadValue);break;case"HTMLImageArray":for(let n=0;ne.varName).join(", ")}) {`),a.setIndent(4),$.run.apply($,t),$.renderKernels?$.renderKernels():$.renderOutput&&$.renderOutput(),w.push(" /** start setup uploads for kernel values **/"),$.kernelArguments.forEach(e=>{w.push(" "+e.getStringValueHandler().split("\n").join("\n "))}),w.push(" /** end setup uploads for kernel values **/"),w.push(a.toString()),$.renderOutput===$.renderTexture){a.reset();const e=$.renderKernels(),t=a.getContextVariableName($.outputTexture);w.push(` return {\n result: {\n texture: ${t},\n type: '${e.result.type}',\n toArray: ${xe(e.result,t)}\n },`);const{subKernels:r,subKernelOutputTextures:n}=$;for(let t=0;t"utils"===e?`const ${t} = ${R[t].toString()};`:null,thisLookup:t=>{if("context"===t)return null;if(e.hasOwnProperty(t))return JSON.stringify(e[t]);throw new Error(`unhandled thisLookup ${t}`)}})}($)),w.push(" innerKernel.getPixels = getPixels;")),w.push(" return innerKernel;");let I=[];return D.forEach(e=>{I.push(`${e.getStringValueHandler()}`)}),`function kernel(settings) {\n const { context, constants } = settings;\n ${I.join("")}\n ${n||""}\n${w.join("\n")}\n}`}function fe(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 xe(e,t){const r=e.toArray.toString(),n=!/^function/.test(r);return`() => {\n ${R.flattenFunctionToString(`${n?"function ":""}${r}`,{findDependency:(t,r)=>{if("utils"===t)return`const ${r} = ${R[r].toString()};`;if("this"===t)return`${n?"function ":""}${e[r].toString()}`;throw new Error("unhandled fromObject")},thisLookup:r=>{if("texture"===r)return t;if(e.hasOwnProperty(r))return JSON.stringify(e[r]);throw new Error(`unhandled thisLookup ${r}`)}})}\n return toArray();\n }`}function ye(e,t,r,n,i){if(null===e)return null;switch(typeof e){case"boolean":case"number":return null}if("undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement){for(let i=0;ir||t>r)throw e>t?new Error(`Argument width of ${e} larger than maximum size of ${r} for your GPU`):new Error(`Argument height of ${t} larger than maximum size of ${r} for your GPU`)}requestTexture(){this.texture=this.onRequestTexture(),this.setupTexture()}setupTexture(){this.contextHandle=this.onRequestContextHandle(),this.index=this.onRequestIndex(),this.dimensionsId=this.id+"Dim",this.sizeId=this.id+"Size"}getTransferArrayType(e){if(Array.isArray(e[0]))return this.getTransferArrayType(e[0]);switch(e.constructor){case Array:case Int32Array:case Int16Array:case Int8Array:return Float32Array;case Uint8ClampedArray:case Uint8Array:case Uint16Array:case Uint32Array:case Float32Array:case Float64Array:return e.constructor}return console.warn("Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros"),e.constructor}formatArrayTransfer(e,t,r){if(R.isArray(e[0])||this.optimizeFloatMemory){const r=new Float32Array(t);return R.flattenTo(e,r),r}switch(e.constructor){case Uint8ClampedArray:case Uint8Array:case Int8Array:case Uint16Array:case Int16Array:case Float32Array:case Int32Array:{const n=new(r||e.constructor)(t);return R.flattenTo(e,n),n}default:{const r=new Float32Array(t);return R.flattenTo(e,r),r}}}getBitRatio(e){if(Array.isArray(e[0]))return this.getBitRatio(e[0]);if(e.constructor===_)return this.getBitRatio(e.value);switch(e.constructor){case Uint8ClampedArray:case Uint8Array:case Int8Array:return 1;case Uint16Array:case Int16Array:return 2;case Float32Array:case Int32Array:default:return 4}}getStringValueHandler(){throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`)}getVariablePrecisionString(){switch(this.tactic){case"speed":return"lowp";case"performance":return"highp";case"balanced":default:return"mediump"}}}class Ae extends be{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const bool ${this.id} = ${e};\n`:`uniform bool ${this.id};\n`}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}class Ee extends be{constructor(e,t){super(e,t),this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(e){return"constants"===this.origin?Number.isInteger(e)?`const float ${this.id} = ${e}.0;\n`:`const float ${this.id} = ${e};\n`:`uniform float ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1f(this.id,this.uploadValue=e)}}class Se extends be{constructor(e,t){super(e,t),this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(e){return"constants"===this.origin?`const int ${this.id} = ${parseInt(e)};\n`:`uniform int ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}class _e extends be{constructor(e,t){super(e,t);const{width:r,height:n}=e;this.checkSize(r,n),this.dimensions=[r,n,1],this.requestTexture(),this.textureSize=[r,n],this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!0),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue=e),this.kernel.setUniform1i(this.id,this.index)}}class ve extends _e{getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){const{width:t,height:r}=e;this.checkSize(t,r),this.dimensions=[t,r,1],this.textureSize=[t,r],this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}class De extends _e{}class $e extends ve{}class we extends be{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=4;let[r,n,i]=e.size;this.dimensions=new Int32Array([r||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.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return R.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}.value, uploadValue_${this.name})`])}getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;R.flattenTo(e.value,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}class Re extends be{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=this.getBitRatio(e);const[r,n,i]=e.size;this.dimensions=new Int32Array([r||1,n||1,i||1]),this.textureSize=R.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0]*(4/this.bitRatio),this.textureSize[1]*(4/this.bitRatio)),this.TranserArrayType=this.getTransferArrayType(e.value),this.preUploadValue=new this.TranserArrayType(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer)}getStringValueHandler(){return R.linesToString([`const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,`const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,`flattenTo(${this.varName}.value, preUploadValue_${this.name})`])}getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;R.flattenTo(e.value,this.preUploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}class Ie extends Re{getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,r,n]=e.size;this.dimensions=new Int32Array([t||1,r||1,n||1]),this.textureSize=R.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0]*(4/this.bitRatio),this.textureSize[1]*(4/this.bitRatio));const i=this.getTransferArrayType(e.value);this.preUploadValue=new i(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}class Fe extends be{constructor(e,t){super(e,t);const[r,n]=e.size;this.checkSize(r,n),this.setupTexture(),this.dimensions=e.dimensions,this.textureSize=e.size,this.uploadValue=e.texture,this.forceUploadEachRun=!0}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName}.texture;\n`}getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();if(this.checkContext&&e.context!==this.context)throw new Error(`Value ${this.name} (${this.type}) must be from same context`);const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.uploadValue=e.texture),this.kernel.setUniform1i(this.id,this.index)}}class ze extends Fe{getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.checkSize(e.size[0],e.size[1]),this.dimensions=e.dimensions,this.textureSize=e.size,this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}class Oe extends be{constructor(e,t){super(e,t);const[r,n]=e.size;this.checkSize(r,n),this.setupTexture();const{size:i,dimensions:s}=e;this.bitRatio=this.getBitRatio(e),this.dimensions=s,this.textureSize=i,this.uploadValue=e.texture,this.forceUploadEachRun=!0}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName}.texture;\n`}getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();if(this.checkContext&&e.context!==this.context)throw new Error(`Value ${this.name} (${this.type}) must be from same context`);const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.uploadValue=e.texture),this.kernel.setUniform1i(this.id,this.index)}}class Ce extends Oe{getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=e.dimensions,this.checkSize(e.size[0],e.size[1]),this.textureSize=e.size,this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}class Ne extends be{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=4,this.dimensions=R.getDimensions(e,!0),this.textureSize=R.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return R.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;R.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}class ke extends be{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=4,this.setShape(e)}setShape(e){const t=R.getDimensions(e,!0);this.textureSize=R.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],1,1]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return R.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;R.flatten2dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}class Me extends ke{getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}class Ue extends be{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=4,this.setShape(e)}setShape(e){const t=R.getDimensions(e,!0);this.textureSize=R.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],t[2],1]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return R.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;R.flatten3dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}class Pe extends Ue{getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}class Le extends be{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=4,this.setShape(e)}setShape(e){const t=R.getDimensions(e,!0);this.textureSize=R.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],t[2],t[3]]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return R.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;R.flatten4dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}class Ve extends Le{getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}class Ke extends be{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec2 ${this.id} = vec2(${e[0]},${e[1]});\n`:`uniform vec2 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform2fv(this.id,this.uploadValue=e)}}class Ge extends be{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec3 ${this.id} = vec3(${e[0]},${e[1]},${e[2]});\n`:`uniform vec3 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform3fv(this.id,this.uploadValue=e)}}class Be extends be{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec4 ${this.id} = vec4(${e[0]},${e[1]},${e[2]},${e[3]});\n`:`uniform vec4 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform4fv(this.id,this.uploadValue=e)}}class Xe extends be{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=this.getBitRatio(e),this.dimensions=R.getDimensions(e,!0),this.textureSize=R.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0]*(4/this.bitRatio),this.textureSize[1]*(4/this.bitRatio)),this.TranserArrayType=this.getTransferArrayType(e),this.preUploadValue=new this.TranserArrayType(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer)}getStringValueHandler(){return R.linesToString([`const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,`const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,`flattenTo(${this.varName}, preUploadValue_${this.name})`])}getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;R.flattenTo(e,this.preUploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}class je extends Xe{getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=R.getDimensions(e,!0),this.textureSize=R.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0]*(4/this.bitRatio),this.textureSize[1]*(4/this.bitRatio));const t=this.getTransferArrayType(e);this.preUploadValue=new t(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}const He={unsigned:{dynamic:{Boolean:Ae,Integer:Se,Float:Ee,Array:je,"Array(2)":!1,"Array(3)":!1,"Array(4)":!1,"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:Ie,NumberTexture:Ce,"ArrayTexture(1)":Ce,"ArrayTexture(2)":Ce,"ArrayTexture(3)":Ce,"ArrayTexture(4)":Ce,MemoryOptimizedNumberTexture:Fe,HTMLImage:ve,HTMLImageArray:!1,HTMLVideo:$e},static:{Boolean:Ae,Float:Ee,Integer:Se,Array:Xe,"Array(2)":!1,"Array(3)":!1,"Array(4)":!1,"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:Re,NumberTexture:Oe,"ArrayTexture(1)":Oe,"ArrayTexture(2)":Oe,"ArrayTexture(3)":Oe,"ArrayTexture(4)":Oe,MemoryOptimizedNumberTexture:ze,HTMLImage:_e,HTMLImageArray:!1,HTMLVideo:De}},single:{dynamic:{Boolean:Ae,Integer:Se,Float:Ee,Array:class extends Ne{getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=R.getDimensions(e,!0),this.textureSize=R.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}},"Array(2)":Ke,"Array(3)":Ge,"Array(4)":Be,"Array1D(2)":Me,"Array1D(3)":Me,"Array1D(4)":Me,"Array2D(2)":Pe,"Array2D(3)":Pe,"Array2D(4)":Pe,"Array3D(2)":Ve,"Array3D(3)":Ve,"Array3D(4)":Ve,Input:class extends we{getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,r,n]=e.size;this.dimensions=new Int32Array([t||1,r||1,n||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.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}},NumberTexture:Ce,"ArrayTexture(1)":Ce,"ArrayTexture(2)":Ce,"ArrayTexture(3)":Ce,"ArrayTexture(4)":Ce,MemoryOptimizedNumberTexture:ze,HTMLImage:ve,HTMLImageArray:!1,HTMLVideo:$e},static:{Boolean:Ae,Float:Ee,Integer:Se,Array:Ne,"Array(2)":Ke,"Array(3)":Ge,"Array(4)":Be,"Array1D(2)":ke,"Array1D(3)":ke,"Array1D(4)":ke,"Array2D(2)":Ue,"Array2D(3)":Ue,"Array2D(4)":Ue,"Array3D(2)":Le,"Array3D(3)":Le,"Array3D(4)":Le,Input:we,NumberTexture:Oe,"ArrayTexture(1)":Oe,"ArrayTexture(2)":Oe,"ArrayTexture(3)":Oe,"ArrayTexture(4)":Oe,MemoryOptimizedNumberTexture:Fe,HTMLImage:_e,HTMLImageArray:!1,HTMLVideo:De}}};let We=null,qe=null,Ye=null,Je=null,Ze=null;const Qe=[le],et=[],tt={};class rt extends ne{static get isSupported(){return null!==We?We:(this.setupFeatureChecks(),We=this.isContextMatch(Ye))}static setupFeatureChecks(){"undefined"!=typeof document?qe=document.createElement("canvas"):"undefined"!=typeof OffscreenCanvas&&(qe=new OffscreenCanvas(0,0)),qe&&(Ye=qe.getContext("webgl")||qe.getContext("experimental-webgl"))&&Ye.getExtension&&(Je={OES_texture_float:Ye.getExtension("OES_texture_float"),OES_texture_float_linear:Ye.getExtension("OES_texture_float_linear"),OES_element_index_uint:Ye.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:Ye.getExtension("WEBGL_draw_buffers")},Ze=this.getFeatures())}static isContextMatch(e){return"undefined"!=typeof WebGLRenderingContext&&e instanceof WebGLRenderingContext}static getFeatures(){const e=this.getIsDrawBuffers();return Object.freeze({isFloatRead:this.getIsFloatRead(),isIntegerDivisionAccurate:this.getIsIntegerDivisionAccurate(),isTextureFloat:this.getIsTextureFloat(),isDrawBuffers:e,kernelMap:e,channelCount:this.getChannelCount()})}static getIsTextureFloat(){return Boolean(Je.OES_texture_float)}static getIsDrawBuffers(){return Boolean(Je.WEBGL_draw_buffers)}static getChannelCount(){return Je.WEBGL_draw_buffers?Ye.getParameter(Je.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL):1}static lookupKernelValueType(e,t,r,n){return 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=He[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]}(e,t,r,n)}static get testCanvas(){return qe}static get testContext(){return Ye}static get features(){return Ze}static get fragmentShader(){return he}static get vertexShader(){return ce}constructor(e,t){super(e,t),this.program=null,this.pipeline=t.pipeline,this.endianness=R.systemEndianness(),this.extensions={},this.subKernelOutputTextures=null,this.kernelArguments=null,this.argumentTextureCount=0,this.constantTextureCount=0,this.compiledFragmentShader=null,this.compiledVertexShader=null,this.fragShader=null,this.vertShader=null,this.drawBuffersMap=null,this.outputTexture=null,this.maxTexSize=null,this.switchingKernels=!1,this.onRequestSwitchKernel=null,this.mergeSettings(e.settings||t),this.threadDim=null,this.framebuffer=null,this.buffer=null,this.textureCache={},this.programUniformLocationCache={},this.uniform1fCache={},this.uniform1iCache={},this.uniform2fCache={},this.uniform2fvCache={},this.uniform2ivCache={},this.uniform3fvCache={},this.uniform3ivCache={},this.uniform4fvCache={},this.uniform4ivCache={}}initCanvas(){if("undefined"!=typeof document){const e=document.createElement("canvas");return e.width=2,e.height=2,e}if("undefined"!=typeof OffscreenCanvas)return new OffscreenCanvas(0,0)}initContext(){const e={alpha:!1,depth:!1,antialias:!1};return this.canvas.getContext("webgl",e)||this.canvas.getContext("experimental-webgl",e)}initPlugins(e){const t=[],{source:r}=this;if("string"==typeof r)for(let e=0;ee===n.name)&&t.push(n)}return t}initExtensions(){this.extensions={OES_texture_float:this.context.getExtension("OES_texture_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear"),OES_element_index_uint:this.context.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:this.context.getExtension("WEBGL_draw_buffers"),WEBGL_color_buffer_float:this.context.getExtension("WEBGL_color_buffer_float")}}validateSettings(e){if(!this.validate)return void(this.texSize=R.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=R.getVariableType(e[0],this.strictIntegers);if("Array"===t)this.output=R.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){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=R.clone(this.output))}null===this.precision&&t.isTextureFloat&&(this.precision="single"),this.texSize=R.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output),this.checkTextureSize()}updateMaxTexSize(){const{texSize:e,canvas:t}=this;if(null===this.maxTexSize){let r=et.indexOf(t);-1===r&&(r=et.length,et.push(t),tt[r]=[e[0],e[1]]),this.maxTexSize=tt[r]}this.maxTexSize[0]Ze.channelCount)throw new Error("Too many channels!");return this.translatedSource=t}setupArguments(e){this.kernelArguments=[],this.argumentTextureCount=0;const t=null===this.argumentTypes;if(t&&(this.argumentTypes=[]),this.argumentSizes=[],this.argumentBitRatios=[],e.lengththis.argumentNames.length)throw new Error("too many arguments for kernel");const{context:r}=this;let n=0;for(let i=0;ithis.context.createTexture(),onRequestIndex:()=>n++,onUpdateValueMismatch:()=>{this.switchingKernels=!0},onRequestContextHandle:()=>r.TEXTURE0+this.constantTextureCount+this.argumentTextureCount++});this.kernelArguments.push(l),this.argumentSizes.push(l.textureSize),this.argumentBitRatios[i]=l.bitRatio}}setupConstants(e){const{context:t}=this;this.kernelConstants=[],this.forceUploadKernelConstants=[];let r=null===this.constantTypes;r&&(this.constantTypes={}),this.constantBitRatios={};let n=0;for(const i in this.constants){const s=this.constants[i];let a;r?(a=R.getVariableType(s,this.strictIntegers),this.constantTypes[i]=a):a=this.constantTypes[i];const o=this.constructor.lookupKernelValueType(a,"static",this.precision,s);if(null===o)return this.requestFallback(e);const u=new o(s,{name:i,type:a,tactic:this.tactic,origin:"constants",context:this.context,checkContext:this.checkContext,kernel:this,strictIntegers:this.strictIntegers,onRequestTexture:()=>this.context.createTexture(),onRequestIndex:()=>n++,onRequestContextHandle:()=>t.TEXTURE0+this.constantTextureCount++});this.constantBitRatios[i]=u.bitRatio,this.kernelConstants.push(u),u.forceUploadEachRun&&this.forceUploadKernelConstants.push(u)}}build(){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];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 g=r.getAttribLocation(this.program,"aTexCoord");r.enableVertexAttribArray(g),r.vertexAttribPointer(g,2,r.FLOAT,!1,0,p),r.bindFramebuffer(r.FRAMEBUFFER,this.framebuffer);let f=0;r.useProgram(this.program);for(let e in this.constants)this.kernelConstants[f++].updateValue(this.constants[e]);this.immutable||(this._setupOutputTexture(),null!==this.subKernels&&this.subKernels.length>0&&this._setupSubOutputTextures())}translateSource(){const e=F.fromKernel(this,ae,{fixIntegerDivisionAccuracy:this.fixIntegerDivisionAccuracy});if(this.translatedSource=e.getPrototypeString("kernel"),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]})`),R.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 div_with_int_check(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}":""}_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=R.linesToString(["const gl = context"]);return ge(this.constructor,arguments,this,e)}destroy(e){this.outputTexture&&this.context.deleteTexture(this.outputTexture),this.buffer&&this.context.deleteBuffer(this.buffer),this.framebuffer&&this.context.deleteFramebuffer(this.framebuffer),this.vertShader&&this.context.deleteShader(this.vertShader),this.fragShader&&this.context.deleteShader(this.fragShader),this.program&&this.context.deleteProgram(this.program);const t=Object.keys(this.textureCache);for(let e=0;e=0&&(et[e]=null,tt[e]=null)}this.destroyExtensions(),delete this.context,delete this.canvas}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=F.fromKernel(this,ae).toJSON(),e}}class nt extends ae{astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const r=this.getType(e);return"Infinity"===e.name?t.push("intBitsToFloat(2139095039)"):"Boolean"===r&&this.argumentNames.indexOf(e.name)>-1?t.push(`bool(user_${e.name})`):t.push(`user_${e.name}`),t}}const it="#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\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\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}",st="#version 300 es\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nin vec2 aPos;\nin vec2 aTexCoord;\n\nout vec2 vTexCoord;\nuniform vec2 ratio;\n\nvoid main(void) {\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\n vTexCoord = aTexCoord;\n}";class at extends Ae{}class ot extends Ee{}class ut extends Se{getSource(e){const t=this.getVariablePrecisionString();return"constants"===this.origin?`const ${t} int ${this.id} = ${parseInt(e)};\n`:`uniform ${t} int ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}class lt extends _e{getSource(){const e=this.getVariablePrecisionString();return R.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}}class ht extends ve{getSource(){const e=this.getVariablePrecisionString();return R.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}class ct extends be{constructor(e,t){super(e,t),this.checkSize(e[0].width,e[0].height),this.requestTexture(),this.dimensions=[e[0].width,e[0].height,e.length],this.textureSize=[e[0].width,e[0].height]}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.texParameteri(t.TEXTURE_2D_ARRAY,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D_ARRAY,t.TEXTURE_MIN_FILTER,t.NEAREST),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;r0)for(let t=0;te[i]),t.__defineSetter__(i,t=>{e[i]=t})))}}const Mt=[Nt,rt],Ut=["gpu","cpu"],Pt={webgl2:Nt,webgl:rt};let Lt=!0;function Vt(e){if(!e)return{};const t=Object.assign({},e);return e.hasOwnProperty("floatOutput")&&(f("setting","floatOutput","precision"),t.precision=e.floatOutput?"single":"unsigned"),e.hasOwnProperty("outputToTexture")&&(f("setting","outputToTexture","pipeline"),t.pipeline=Boolean(e.outputToTexture)),e.hasOwnProperty("outputImmutable")&&(f("setting","outputImmutable","immutable"),t.immutable=Boolean(e.outputImmutable)),e.hasOwnProperty("floatTextures")&&(f("setting","floatTextures","optimizeFloatMemory"),t.optimizeFloatMemory=Boolean(e.floatTextures)),t}const Kt=class{static disableValidation(){Lt=!1}static enableValidation(){Lt=!0}static get isGPUSupported(){return Mt.some(e=>e.isSupported)}static get isKernelMapSupported(){return Mt.some(e=>e.isSupported&&e.features.kernelMap)}static get isOffscreenCanvasSupported(){return"undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas||"undefined"!=typeof importScripts}static get isWebGLSupported(){return rt.isSupported}static get isWebGL2Supported(){return Nt.isSupported}static get isHeadlessGLSupported(){return!1}static get isCanvasSupported(){return"undefined"!=typeof HTMLCanvasElement}static get isGPUHTMLImageArraySupported(){return Nt.isSupported}static get isSinglePrecisionSupported(){return Mt.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 s=Object.assign({context:this.context,canvas:this.canvas,functions:this.functions,nativeFunctions:this.nativeFunctions,injectedNative:this.injectedNative,gpu:this,validate:Lt,onRequestFallback:i,onRequestSwitchKernel:function t(n,s){const o=new Array(n.length);for(let e=0;e{try{e(t.apply(this,arguments))}catch(e){r(e)}})},r.replaceKernel=function(t){kt(e=t,r),r.kernel=e},kt(e,r),r.kernel=e,r}(new this.Kernel(e,s));return this.canvas||(this.canvas=a.canvas),this.context||(this.context=a.context),this.kernels.push(a),a}createKernelMap(){let e,t;if("function"==typeof arguments[arguments.length-2]?(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&&Ut.indexOf(this.mode)<0)throw new Error(`kernelMap not supported on ${this.Kernel.name}`);const r=Vt(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.');r=r||{};const{argumentTypes:n,argumentNames:i}=this.Kernel.nativeFunctionArguments(t)||{};return this.nativeFunctions.push({name:e,source:t,settings:r,argumentTypes:n,argumentNames:i,returnType:r.returnType||this.Kernel.nativeFunctionReturnType(t)}),this}injectNative(e){return this.injectedNative=e,this}destroy(){this.kernels&&setTimeout(()=>{for(let e=0;e {\n kernel.output = setupOutput(output);\n if (kernel.graphical) {\n setupGraphical(kernel);\n }\n };\n kernel.toJSON = () => {\n throw new Error('Not usable with gpuMock');\n };\n kernel.setConstants = (flag) => {\n kernel.constants = flag;\n return kernel;\n };\n kernel.setGraphical = (flag) => {\n kernel.graphical = flag;\n return kernel;\n };\n kernel.setCanvas = (flag) => {\n kernel.canvas = flag;\n return kernel;\n };\n kernel.setContext = (flag) => {\n kernel.context = flag;\n return kernel;\n };\n kernel.exec = function() {\n return new Promise((resolve, reject) => {\n try {\n resolve(kernel.apply(kernel, arguments));\n } catch(e) {\n reject(e);\n }\n });\n };\n kernel.getPixels = (flip) => {\n const {x, y} = kernel.output;\n // cpu is not flipped by default\n return flip ? flipPixels(kernel._imageData.data, x, y) : kernel._imageData.data.slice(0);\n };\n kernel.color = function(r, g, b, a) {\n if (typeof a === 'undefined') {\n a = 1;\n }\n\n r = Math.floor(r * 255);\n g = Math.floor(g * 255);\n b = Math.floor(b * 255);\n a = Math.floor(a * 255);\n\n const width = kernel.output.x;\n const height = kernel.output.y;\n\n const x = kernel.thread.x;\n const y = height - kernel.thread.y - 1;\n\n const index = x + y * width;\n\n kernel._colorData[index * 4 + 0] = r;\n kernel._colorData[index * 4 + 1] = g;\n kernel._colorData[index * 4 + 2] = b;\n kernel._colorData[index * 4 + 3] = a;\n };\n\n // these are added for api compatibility, but have no affect\n kernel.setWarnVarUsage = () => {\n return kernel;\n };\n kernel.setOptimizeFloatMemory = () => {\n return kernel;\n };\n kernel.setArgumentTypes = () => {\n return kernel;\n };\n kernel.setDebug = () => {\n return kernel;\n };\n kernel.setLoopMaxIterations = () => {\n return kernel;\n };\n kernel.setPipeline = () => {\n return kernel;\n };\n kernel.setPrecision = () => {\n return kernel;\n };\n kernel.setImmutable = () => {\n return kernel;\n };\n kernel.setFunctions = () => {\n return kernel;\n };\n kernel.addSubKernel = () => {\n return kernel;\n };\n kernel.destroy = () => {};\n kernel.validateSettings = () => {};\n if (kernel.graphical && kernel.output) {\n setupGraphical(kernel);\n }\n return kernel;\n}\n\nfunction setupGraphical(kernel) {\n const {x, y} = kernel.output;\n if (kernel.context && kernel.context.createImageData) {\n const data = new Uint8ClampedArray(x * y * 4);\n kernel._imageData = kernel.context.createImageData(x, y);\n kernel._colorData = data;\n } else {\n const data = new Uint8ClampedArray(x * y * 4);\n kernel._imageData = { data };\n kernel._colorData = data;\n }\n}\n\nfunction setupOutput(output) {\n let result = null;\n if (output.length) {\n if (output.length === 3) {\n const [x,y,z] = output;\n result = { x, y, z };\n } else if (output.length === 2) {\n const [x,y] = output;\n result = { x, y };\n } else {\n const [x] = output;\n result = { x };\n }\n } else {\n result = output;\n }\n return result;\n}\n\nfunction gpuMock(fn, settings = {}) {\n const output = settings.output ? setupOutput(settings.output) : null;\n function kernel() {\n if (kernel.output.z) {\n return mock3D.apply(kernel, arguments);\n } else if (kernel.output.y) {\n if (kernel.graphical) {\n return mock2DGraphical.apply(kernel, arguments);\n }\n return mock2D.apply(kernel, arguments);\n } else {\n return mock1D.apply(kernel, arguments);\n }\n }\n kernel._fn = fn;\n kernel.constants = settings.constants || null;\n kernel.context = settings.context || null;\n kernel.canvas = settings.canvas || null;\n kernel.graphical = settings.graphical || false;\n kernel._imageData = null;\n kernel._colorData = null;\n kernel.output = output;\n kernel.thread = {\n x: 0,\n y: 0,\n z: 0\n };\n return apiDecorate(kernel);\n}\n\nfunction flipPixels(pixels, width, height) {\n // https://stackoverflow.com/a/41973289/1324039\n const halfHeight = height / 2 | 0; // the | 0 keeps the result an int\n const bytesPerRow = width * 4;\n // make a temp buffer to hold one row\n const temp = new Uint8ClampedArray(width * 4);\n const result = pixels.slice(0);\n for (let y = 0; y < halfHeight; ++y) {\n const topOffset = y * bytesPerRow;\n const bottomOffset = (height - y - 1) * bytesPerRow;\n\n // make copy of a row on the top half\n temp.set(result.subarray(topOffset, topOffset + bytesPerRow));\n\n // copy a row from the bottom half to the top\n result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow);\n\n // copy the copy of the top half row to the bottom half\n result.set(temp, bottomOffset);\n }\n return result;\n}\n\nmodule.exports = {\n gpuMock\n};\n","/**\r\n * @fileoverview Branch of utils to prevent circular dependencies.\r\n */\r\n\r\nconst ARGUMENT_NAMES = /([^\\s,]+)/g;\r\nconst FUNCTION_NAME = /function ([^(]*)/;\r\nconst STRIP_COMMENTS = /((\\/\\/.*$)|(\\/\\*[\\s\\S]*?\\*\\/))/mg;\r\n\r\n/**\r\n * @descReturn TRUE, on a JS function\r\n * @param {Function} funcObj - Object to validate if its a function\r\n * @returns {Boolean} TRUE if the object is a JS function\r\n */\r\nexport function isFunction(funcObj) {\r\n return typeof(funcObj) === 'function';\r\n};\r\n\r\n/**\r\n * @desc Return the function name from a JS function string\r\n * @param {String} funcStr - String of JS function to validate\r\n * @returns {String} Function name string (if found)\r\n */\r\nexport function getFunctionNameFromString(funcStr) {\r\n return FUNCTION_NAME.exec(funcStr)[1].trim();\r\n};\r\n\r\n/**\r\n *\r\n * @param {String|Function} source\r\n * @param {IFunctionSettings} [settings]\r\n * @returns {IFunction}\r\n */\r\nexport function functionToIFunction(source, settings) {\r\n settings = settings || {};\r\n if (typeof source !== 'string' && typeof source !== 'function') throw new Error('source not a string or function');\r\n const sourceString = typeof source === 'string' ? source : source.toString();\r\n\r\n let argumentTypes = [];\r\n\r\n if (Array.isArray(settings.argumentTypes)) {\r\n argumentTypes = settings.argumentTypes;\r\n } else if (typeof settings.argumentTypes === 'object') {\r\n argumentTypes = getArgumentNamesFromString(sourceString)\r\n .map(name => settings.argumentTypes[name]) || [];\r\n } else {\r\n argumentTypes = settings.argumentTypes || [];\r\n }\r\n\r\n return {\r\n source: sourceString,\r\n argumentTypes,\r\n returnType: settings.returnType || null,\r\n };\r\n};\r\n\r\nexport function warnDeprecated(type, oldName, newName) {\r\n const msg = newName\r\n ? `It has been replaced with \"${ newName }\"`\r\n : 'It has been removed';\r\n console.warn(`You are using a deprecated ${ type } \"${ oldName }\". ${msg}. Fixing, but please upgrade as it will soon be removed.`)\r\n};\r\n\r\n/**\r\n * @desc Return TRUE, on a valid JS function string\r\n * Note: This does just a VERY simply sanity check. And may give false positives.\r\n *\r\n * @param {String} fn - String of JS function to validate\r\n * @returns {Boolean} TRUE if the string passes basic validation\r\n */\r\nexport function isFunctionString(fn) {\r\n if (typeof fn === 'string') {\r\n return (fn\r\n .slice(0, 'function'.length)\r\n .toLowerCase() === 'function');\r\n }\r\n return false;\r\n};\r\n\r\n/**\r\n * @desc Return list of argument names extracted from a javascript function\r\n * @param {String} fn - String of JS function to validate\r\n * @returns {String[]} Array representing all the parameter names\r\n */\r\nexport function getArgumentNamesFromString(fn) {\r\n const fnStr = fn.replace(STRIP_COMMENTS, '');\r\n let result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);\r\n if (result === null) {\r\n result = [];\r\n }\r\n return result;\r\n};\r\n\r\n/**\r\n * @desc Checks if is an array or Array-like object\r\n * @param {Object} array - The argument object to check if is array\r\n * @returns {Boolean} true if is array or Array-like object\r\n */\r\nexport function isArray(array) {\r\n return !isNaN(array.length);\r\n};\r\n\r\nexport function erectMemoryOptimized2DFloat(array, width, height) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const offset = y * width;\r\n yResults[y] = array.subarray(offset, offset + width);\r\n }\r\n return yResults;\r\n};\r\n\r\nexport function erectMemoryOptimized3DFloat(array, width, height, depth) {\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const offset = (z * height * width) + (y * width);\r\n yResults[y] = array.subarray(offset, offset + width);\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n};\r\n\r\nexport function getAstString(source, ast) {\r\n const lines = Array.isArray(source) ? source : source.split(/\\r?\\n/g);\r\n const start = ast.loc.start;\r\n const end = ast.loc.end;\r\n const result = [];\r\n if (start.line === end.line) {\r\n result.push(lines[start.line - 1].substring(start.column, end.column));\r\n } else {\r\n result.push(lines[start.line - 1].slice(start.column));\r\n for (let i = start.line; i < end.line; i++) {\r\n result.push(lines[i]);\r\n }\r\n result.push(lines[end.line - 1].slice(0, end.column));\r\n }\r\n return result.join('\\n');\r\n};\r\n","import { erectMemoryOptimized2DFloat, erectMemoryOptimized3DFloat } from './common';\r\n\r\nexport class Input {\r\n constructor(value, size) {\r\n this.value = value;\r\n if (Array.isArray(size)) {\r\n this.size = size;\r\n } else {\r\n this.size = new Int32Array(3);\r\n if (size.z) {\r\n this.size = new Int32Array([size.x, size.y, size.z]);\r\n } else if (size.y) {\r\n this.size = new Int32Array([size.x, size.y]);\r\n } else {\r\n this.size = new Int32Array([size.x]);\r\n }\r\n }\r\n\r\n const [w, h, d] = this.size;\r\n if (d) {\r\n if (this.value.length !== (w * h * d)) {\r\n throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} * ${d} = ${(h * w * d)}`);\r\n }\r\n } else if (h) {\r\n if (this.value.length !== (w * h)) {\r\n throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} = ${(h * w)}`);\r\n }\r\n } else {\r\n if (this.value.length !== w) {\r\n throw new Error(`Input size ${this.value.length} does not match ${w}`);\r\n }\r\n }\r\n\r\n }\r\n\r\n toArray() {\r\n const [ w, h, d ] = this.size;\r\n if (d) {\r\n return erectMemoryOptimized3DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h, d);\r\n } else if (h) {\r\n return erectMemoryOptimized2DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h);\r\n } else {\r\n return this.value;\r\n }\r\n }\r\n};\r\n\r\nexport function input(value, size) {\r\n return new Input(value, size);\r\n};\r\n","/**\r\n * @desc WebGl Texture implementation in JS\r\n * @param {ITextureSettings} settings\r\n */\r\nexport class Texture {\r\n constructor(settings) {\r\n const {\r\n texture,\r\n size,\r\n dimensions,\r\n output,\r\n context,\r\n type = 'NumberTexture',\r\n } = settings;\r\n if (!output) throw new Error('settings property \"output\" required.');\r\n if (!context) throw new Error('settings property \"context\" required.');\r\n this.texture = texture;\r\n this.size = size;\r\n this.dimensions = dimensions;\r\n this.output = output;\r\n this.context = context;\r\n this.kernel = null;\r\n this.type = type;\r\n }\r\n\r\n /**\r\n * @desc Converts the Texture into a JavaScript Array\r\n * @returns {Number[]|Number[][]|Number[][][]}\r\n */\r\n toArray() {\r\n throw new Error(`Not implemented on ${this.constructor.name}`);\r\n }\r\n\r\n /**\r\n * @desc Deletes the Texture\r\n */\r\n delete() {\r\n return this.context.deleteTexture(this.texture);\r\n }\r\n};\r\n","import { parse } from 'acorn';\r\nimport { Texture } from './texture';\r\nimport { Input } from './input';\r\nimport {\r\n getAstString,\r\n erectMemoryOptimized2DFloat,\r\n erectMemoryOptimized3DFloat,\r\n functionToIFunction,\r\n getArgumentNamesFromString,\r\n getFunctionNameFromString,\r\n isArray,\r\n isFunction,\r\n isFunctionString,\r\n warnDeprecated\r\n} from './common';\r\n\r\nexport function getSystemEndianness() {\r\n const b = new ArrayBuffer(4);\r\n const a = new Uint32Array(b);\r\n const c = new Uint8Array(b);\r\n a[0] = 0xdeadbeef;\r\n if (c[0] === 0xef) return 'LE';\r\n if (c[0] === 0xde) return 'BE';\r\n throw new Error('unknown endianness');\r\n};\r\n\r\nconst _systemEndianness = getSystemEndianness();\r\n\r\n/**\r\n *\r\n * @desc Gets the system endianness, and cache it\r\n * @returns {String} 'LE' or 'BE' depending on system architecture\r\n * Credit: https://gist.github.com/TooTallNate/4750953\r\n */\r\nexport function systemEndianness() {\r\n return _systemEndianness;\r\n};\r\n\r\n/**\r\n * @desc Evaluate the argument type, to apply respective logic for it\r\n * @param {Object} value - The argument object to evaluate type\r\n * @returns {String} Argument type Array/Number/Float/Texture/Unknown\r\n */\r\nexport function getVariableType(value, strictIntegers) {\r\n if (isArray(value)) {\r\n if (value[0].nodeName === 'IMG') {\r\n return 'HTMLImageArray';\r\n }\r\n return 'Array';\r\n }\r\n\r\n switch (value.constructor) {\r\n case Boolean:\r\n return 'Boolean';\r\n case Number:\r\n return strictIntegers && Number.isInteger(value) ? 'Integer' : 'Float';\r\n case Texture:\r\n return value.type;\r\n case Input:\r\n return 'Input';\r\n }\r\n\r\n switch (value.nodeName) {\r\n case 'IMG':\r\n return 'HTMLImage';\r\n case 'VIDEO':\r\n return 'HTMLVideo';\r\n }\r\n\r\n return value.hasOwnProperty('type') ? value.type : 'Unknown';\r\n};\r\n\r\n/**\r\n * @desc Various utility functions / snippets of code that GPU.JS uses internally.\r\n * This covers various snippets of code that is not entirely gpu.js specific (ie. may find uses elsewhere)\r\n */\r\nconst utils = {\r\n systemEndianness,\r\n getSystemEndianness,\r\n isFunction,\r\n isFunctionString,\r\n getFunctionNameFromString,\r\n\r\n getFunctionBodyFromString(funcStr) {\r\n return funcStr.substring(funcStr.indexOf('{') + 1, funcStr.lastIndexOf('}'));\r\n },\r\n\r\n getArgumentNamesFromString,\r\n\r\n /**\r\n * @desc Returns a clone\r\n * @param {Object} obj - Object to clone\r\n * @returns {Object|Array} Cloned object\r\n */\r\n clone(obj) {\r\n if (obj === null || typeof obj !== 'object' || obj.hasOwnProperty('isActiveClone')) return obj;\r\n\r\n const temp = obj.constructor(); // changed\r\n\r\n for (let key in obj) {\r\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\r\n obj.isActiveClone = null;\r\n temp[key] = utils.clone(obj[key]);\r\n delete obj.isActiveClone;\r\n }\r\n }\r\n\r\n return temp;\r\n },\r\n\r\n isArray,\r\n getVariableType,\r\n\r\n getKernelTextureSize(settings, dimensions) {\r\n let [w, h, d] = dimensions;\r\n let texelCount = (w || 1) * (h || 1) * (d || 1);\r\n\r\n if (settings.optimizeFloatMemory && settings.precision === 'single') {\r\n w = texelCount = Math.ceil(texelCount / 4);\r\n }\r\n // if given dimensions == a 2d image\r\n if (h > 1 && w * h === texelCount) {\r\n return new Int32Array([w, h]);\r\n }\r\n return utils.closestSquareDimensions(texelCount);\r\n },\r\n\r\n /**\r\n *\r\n * @param {Number} length\r\n * @returns {TextureDimensions}\r\n */\r\n closestSquareDimensions(length) {\r\n const sqrt = Math.sqrt(length);\r\n let high = Math.ceil(sqrt);\r\n let low = Math.floor(sqrt);\r\n while (high * low < length) {\r\n high--;\r\n low = Math.ceil(length / high);\r\n }\r\n return new Int32Array([low, Math.ceil(length / low)]);\r\n },\r\n\r\n /**\r\n * A texture takes up four\r\n * @param {OutputDimensions} dimensions\r\n * @param {Number} bitRatio\r\n * @returns {TextureDimensions}\r\n */\r\n getMemoryOptimizedFloatTextureSize(dimensions, bitRatio) {\r\n const totalArea = utils.roundTo((dimensions[0] || 1) * (dimensions[1] || 1) * (dimensions[2] || 1) * (dimensions[3] || 1), 4);\r\n const texelCount = totalArea / bitRatio;\r\n return utils.closestSquareDimensions(texelCount);\r\n },\r\n\r\n /**\r\n *\r\n * @param dimensions\r\n * @param bitRatio\r\n * @returns {*|TextureDimensions}\r\n */\r\n getMemoryOptimizedPackedTextureSize(dimensions, bitRatio) {\r\n const [w, h, d] = dimensions;\r\n const totalArea = utils.roundTo((w || 1) * (h || 1) * (d || 1), 4);\r\n const texelCount = totalArea / (4 / bitRatio);\r\n return utils.closestSquareDimensions(texelCount);\r\n },\r\n\r\n roundTo(n, d) {\r\n return Math.floor((n + d - 1) / d) * d;\r\n },\r\n /**\r\n * @desc Return the dimension of an array.\r\n * @param {Array|String|Texture|Input} x - The array\r\n * @param {Boolean} [pad] - To include padding in the dimension calculation\r\n * @returns {OutputDimensions}\r\n */\r\n getDimensions(x, pad) {\r\n let ret;\r\n if (isArray(x)) {\r\n const dim = [];\r\n let temp = x;\r\n while (isArray(temp)) {\r\n dim.push(temp.length);\r\n temp = temp[0];\r\n }\r\n ret = dim.reverse();\r\n } else if (x instanceof Texture) {\r\n ret = x.output;\r\n } else if (x instanceof Input) {\r\n ret = x.size;\r\n } else {\r\n throw new Error(`Unknown dimensions of ${x}`);\r\n }\r\n\r\n if (pad) {\r\n ret = Array.from(ret);\r\n while (ret.length < 3) {\r\n ret.push(1);\r\n }\r\n }\r\n\r\n return new Int32Array(ret);\r\n },\r\n\r\n /**\r\n * Puts a nested 2d array into a one-dimensional target array\r\n * @param {Array|*} array\r\n * @param {Float32Array|Float64Array} target\r\n */\r\n flatten2dArrayTo(array, target) {\r\n let offset = 0;\r\n for (let y = 0; y < array.length; y++) {\r\n target.set(array[y], offset);\r\n offset += array[y].length;\r\n }\r\n },\r\n\r\n /**\r\n * Puts a nested 3d array into a one-dimensional target array\r\n * @param {Array|*} array\r\n * @param {Float32Array|Float64Array} target\r\n */\r\n flatten3dArrayTo(array, target) {\r\n let offset = 0;\r\n for (let z = 0; z < array.length; z++) {\r\n for (let y = 0; y < array[z].length; y++) {\r\n target.set(array[z][y], offset);\r\n offset += array[z][y].length;\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Puts a nested 4d array into a one-dimensional target array\r\n * @param {Array|*} array\r\n * @param {Float32Array|Float64Array} target\r\n */\r\n flatten4dArrayTo(array, target) {\r\n let offset = 0;\r\n for (let l = 0; l < array.length; l++) {\r\n for (let z = 0; z < array[l].length; z++) {\r\n for (let y = 0; y < array[l][z].length; y++) {\r\n target.set(array[l][z][y], offset);\r\n offset += array[l][z][y].length;\r\n }\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Puts a nested 1d, 2d, or 3d array into a one-dimensional target array\r\n * @param {Float32Array|Uint16Array|Uint8Array} array\r\n * @param {Float32Array} target\r\n */\r\n flattenTo(array, target) {\r\n if (isArray(array[0])) {\r\n if (isArray(array[0][0])) {\r\n if (isArray(array[0][0][0])) {\r\n utils.flatten4dArrayTo(array, target);\r\n } else {\r\n utils.flatten3dArrayTo(array, target);\r\n }\r\n } else {\r\n utils.flatten2dArrayTo(array, target);\r\n }\r\n } else {\r\n target.set(array);\r\n }\r\n },\r\n\r\n /**\r\n *\r\n * @desc Splits an array into smaller arrays.\r\n * Number of elements in one small chunk is given by `part`\r\n *\r\n * @param {Number[]} array - The array to split into chunks\r\n * @param {Number} part - elements in one chunk\r\n *\r\n * @returns {Number[]} An array of smaller chunks\r\n */\r\n splitArray(array, part) {\r\n const result = [];\r\n for (let i = 0; i < array.length; i += part) {\r\n result.push(new array.constructor(array.buffer, i * 4 + array.byteOffset, part));\r\n }\r\n return result;\r\n },\r\n\r\n getAstString,\r\n\r\n allPropertiesOf(obj) {\r\n const props = [];\r\n\r\n do {\r\n props.push.apply(props, Object.getOwnPropertyNames(obj));\r\n } while (obj = Object.getPrototypeOf(obj));\r\n\r\n return props;\r\n },\r\n\r\n /**\r\n * @param {Array} lines - An Array of strings\r\n * @returns {String} Single combined String, separated by *\\n*\r\n */\r\n linesToString(lines) {\r\n if (lines.length > 0) {\r\n return lines.join(';\\n') + ';\\n';\r\n } else {\r\n return '\\n';\r\n }\r\n },\r\n\r\n warnDeprecated,\r\n functionToIFunction,\r\n\r\n flipPixels(pixels, width, height) {\r\n // https://stackoverflow.com/a/41973289/1324039\r\n const halfHeight = height / 2 | 0; // the | 0 keeps the result an int\r\n const bytesPerRow = width * 4;\r\n // make a temp buffer to hold one row\r\n const temp = new Uint8ClampedArray(width * 4);\r\n const result = pixels.slice(0);\r\n for (let y = 0; y < halfHeight; ++y) {\r\n const topOffset = y * bytesPerRow;\r\n const bottomOffset = (height - y - 1) * bytesPerRow;\r\n\r\n // make copy of a row on the top half\r\n temp.set(result.subarray(topOffset, topOffset + bytesPerRow));\r\n\r\n // copy a row from the bottom half to the top\r\n result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow);\r\n\r\n // copy the copy of the top half row to the bottom half\r\n result.set(temp, bottomOffset);\r\n }\r\n return result;\r\n },\r\n\r\n erectPackedFloat: (array, width) => {\r\n return array.subarray(0, width);\r\n },\r\n erect2DPackedFloat: (array, width, height) => {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xStart = y * width;\r\n const xEnd = xStart + width;\r\n yResults[y] = array.subarray(xStart, xEnd);\r\n }\r\n return yResults;\r\n },\r\n erect3DPackedFloat: (array, width, height, depth) => {\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xStart = (z * height * width) + y * width;\r\n const xEnd = xStart + width;\r\n yResults[y] = array.subarray(xStart, xEnd);\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n },\r\n erectMemoryOptimizedFloat: (array, width) => {\r\n return array.subarray(0, width);\r\n },\r\n erectMemoryOptimized2DFloat,\r\n erectMemoryOptimized3DFloat,\r\n erectFloat: (array, width) => {\r\n const xResults = new Float32Array(width);\r\n let i = 0;\r\n for (let x = 0; x < width; x++) {\r\n xResults[x] = array[i];\r\n i += 4;\r\n }\r\n return xResults;\r\n },\r\n erect2DFloat: (array, width, height) => {\r\n const yResults = new Array(height);\r\n let i = 0;\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Float32Array(width);\r\n for (let x = 0; x < width; x++) {\r\n xResults[x] = array[i];\r\n i += 4;\r\n }\r\n yResults[y] = xResults;\r\n }\r\n return yResults;\r\n },\r\n erect3DFloat: (array, width, height, depth) => {\r\n const zResults = new Array(depth);\r\n let i = 0;\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Float32Array(width);\r\n for (let x = 0; x < width; x++) {\r\n xResults[x] = array[i];\r\n i += 4;\r\n }\r\n yResults[y] = xResults;\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n },\r\n erectArray2: (array, width) => {\r\n const xResults = new Array(width);\r\n const xResultsMax = width * 4;\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x, x + 2);\r\n }\r\n return xResults;\r\n },\r\n erect2DArray2: (array, width, height) => {\r\n const yResults = new Array(height);\r\n const XResultsMax = width * 4;\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = y * XResultsMax;\r\n let i = 0;\r\n for (let x = 0; x < XResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 2);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n return yResults;\r\n },\r\n erect3DArray2: (array, width, height, depth) => {\r\n const xResultsMax = width * 4;\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = (z * xResultsMax * height) + (y * xResultsMax);\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 2);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n },\r\n erectArray3: (array, width) => {\r\n const xResults = new Array(width);\r\n const xResultsMax = width * 4;\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x, x + 3);\r\n }\r\n return xResults;\r\n },\r\n erect2DArray3: (array, width, height) => {\r\n const xResultsMax = width * 4;\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = y * xResultsMax;\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 3);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n return yResults;\r\n },\r\n erect3DArray3: (array, width, height, depth) => {\r\n const xResultsMax = width * 4;\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = (z * xResultsMax * height) + (y * xResultsMax);\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 3);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n },\r\n erectArray4: (array, width) => {\r\n const xResults = new Array(array);\r\n const xResultsMax = width * 4;\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x, x + 4);\r\n }\r\n return xResults;\r\n },\r\n erect2DArray4: (array, width, height) => {\r\n const xResultsMax = width * 4;\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = y * xResultsMax;\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 4);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n return yResults;\r\n },\r\n erect3DArray4: (array, width, height, depth) => {\r\n const xResultsMax = width * 4;\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = (z * xResultsMax * height) + (y * xResultsMax);\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 4);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n },\r\n\r\n /**\r\n * @param {String} source\r\n * @param {Object} settings\r\n * @return {String}\r\n */\r\n flattenFunctionToString: (source, settings) => {\r\n const { findDependency, thisLookup, doNotDefine } = settings;\r\n let flattened = settings.flattened;\r\n if (!flattened) {\r\n flattened = settings.flattened = {};\r\n }\r\n\r\n const ast = parse(source);\r\n const functionDependencies = [];\r\n\r\n function flatten(ast) {\r\n if (Array.isArray(ast)) {\r\n const results = [];\r\n for (let i = 0; i < ast.length; i++) {\r\n results.push(flatten(ast[i]));\r\n }\r\n return results.join('');\r\n }\r\n switch (ast.type) {\r\n case 'Program':\r\n return flatten(ast.body);\r\n case 'FunctionDeclaration':\r\n return `function ${ast.id.name}(${ast.params.map(flatten).join(', ')}) ${ flatten(ast.body) }`;\r\n case 'BlockStatement': {\r\n const result = [];\r\n for (let i = 0; i < ast.body.length; i++) {\r\n result.push(flatten(ast.body[i]), ';\\n');\r\n }\r\n return `{\\n${result.join('')}}`;\r\n }\r\n case 'VariableDeclaration':\r\n switch (ast.declarations[0].id.type) {\r\n case 'ObjectPattern': {\r\n const source = flatten(ast.declarations[0].init);\r\n const properties = ast.declarations.map(declaration => declaration.id.properties.map(flatten))[0];\r\n if (/this/.test(source)) {\r\n const result = [];\r\n const lookups = properties.map(thisLookup);\r\n for (let i = 0; i < lookups.length; i++) {\r\n const lookup = lookups[i];\r\n if (lookup === null) continue;\r\n const property = properties[i];\r\n result.push(`${ast.kind} ${ property } = ${ lookup };\\n`);\r\n }\r\n\r\n return result.join('');\r\n }\r\n return `${ast.kind} { ${properties} } = ${source}`;\r\n }\r\n case 'ArrayPattern':\r\n return `${ast.kind} [ ${ ast.declarations.map(declaration => flatten(declaration.id)).join(', ') } ] = ${flatten(ast.declarations[0].init)}`;\r\n }\r\n if (doNotDefine && doNotDefine.indexOf(ast.declarations[0].id.name) !== -1) {\r\n return '';\r\n }\r\n return `${ast.kind} ${ast.declarations[0].id.name} = ${flatten(ast.declarations[0].init)}`;\r\n case 'CallExpression': {\r\n if (ast.callee.property.name === 'subarray') {\r\n return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n }\r\n if (ast.callee.object.name === 'gl' || ast.callee.object.name === 'context') {\r\n return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n }\r\n if (ast.callee.object.type === 'ThisExpression') {\r\n functionDependencies.push(findDependency('this', ast.callee.property.name));\r\n return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n } else if (ast.callee.object.name) {\r\n const foundSource = findDependency(ast.callee.object.name, ast.callee.property.name);\r\n if (foundSource === null) {\r\n // we're not flattening it\r\n return `${ast.callee.object.name}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n } else {\r\n functionDependencies.push(foundSource);\r\n // we're flattening it\r\n return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n }\r\n } else if (ast.callee.object.type === 'MemberExpression') {\r\n return `${flatten(ast.callee.object)}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n } else {\r\n throw new Error('unknown ast.callee');\r\n }\r\n }\r\n case 'ReturnStatement':\r\n return `return ${flatten(ast.argument)}`;\r\n case 'BinaryExpression':\r\n return `(${flatten(ast.left)}${ast.operator}${flatten(ast.right)})`;\r\n case 'UnaryExpression':\r\n if (ast.prefix) {\r\n return `${ast.operator} ${flatten(ast.argument)}`;\r\n } else {\r\n return `${flatten(ast.argument)} ${ast.operator}`;\r\n }\r\n case 'ExpressionStatement':\r\n return `(${flatten(ast.expression)})`;\r\n case 'ArrowFunctionExpression':\r\n return `(${ast.params.map(flatten).join(', ')}) => ${flatten(ast.body)}`;\r\n case 'Literal':\r\n return ast.raw;\r\n case 'Identifier':\r\n return ast.name;\r\n case 'MemberExpression':\r\n if (ast.object.type === 'ThisExpression') {\r\n return thisLookup(ast.property.name);\r\n }\r\n if (ast.computed) {\r\n return `${flatten(ast.object)}[${flatten(ast.property)}]`;\r\n }\r\n return flatten(ast.object) + '.' + flatten(ast.property);\r\n case 'ThisExpression':\r\n return 'this';\r\n case 'NewExpression':\r\n return `new ${flatten(ast.callee)}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n case 'ForStatement':\r\n return `for (${flatten(ast.init)};${flatten(ast.test)};${flatten(ast.update)}) ${flatten(ast.body)}`;\r\n case 'AssignmentExpression':\r\n return `${flatten(ast.left)}${ast.operator}${flatten(ast.right)}`;\r\n case 'UpdateExpression':\r\n return `${flatten(ast.argument)}${ast.operator}`;\r\n case 'IfStatement':\r\n return `if (${flatten(ast.test)}) ${flatten(ast.consequent)}`;\r\n case 'ThrowStatement':\r\n return `throw ${flatten(ast.argument)}`;\r\n case 'ObjectPattern':\r\n return ast.properties.map(flatten).join(', ');\r\n case 'ArrayPattern':\r\n return ast.elements.map(flatten).join(', ');\r\n case 'DebuggerStatement':\r\n return 'debugger;';\r\n case 'ConditionalExpression':\r\n return `${flatten(ast.test)}?${flatten(ast.consequent)}:${flatten(ast.alternate)}`;\r\n case 'Property':\r\n if (ast.kind === 'init') {\r\n return flatten(ast.key);\r\n }\r\n }\r\n throw new Error(`unhandled ast.type of ${ ast.type }`);\r\n }\r\n const result = flatten(ast);\r\n if (functionDependencies.length > 0) {\r\n const flattenedFunctionDependencies = [];\r\n for (let i = 0; i < functionDependencies.length; i++) {\r\n const functionDependency = functionDependencies[i];\r\n if (!flattened[functionDependency]) {\r\n flattened[functionDependency] = true;\r\n }\r\n flattenedFunctionDependencies.push(utils.flattenFunctionToString(functionDependency, settings) + ';\\n');\r\n }\r\n return flattenedFunctionDependencies.join('') + result;\r\n }\r\n return result;\r\n },\r\n};\r\n\r\nexport { utils };\r\n","import { Input } from '../input';\r\nimport {\r\n functionToIFunction,\r\n getArgumentNamesFromString,\r\n isArray,\r\n isFunctionString,\r\n warnDeprecated\r\n} from '../common';\r\nimport { getVariableType } from '../utils';\r\n\r\nexport class Kernel {\r\n /**\r\n * @type {Boolean}\r\n */\r\n static get isSupported() {\r\n throw new Error(`\"isSupported\" not implemented on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @type {Boolean}\r\n */\r\n static isContextMatch(context) {\r\n throw new Error(`\"isContextMatch\" not implemented on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @type {IKernelFeatures}\r\n * Used internally to populate the kernel.feature, which is a getter for the output of this value\r\n */\r\n static getFeatures() {\r\n throw new Error(`\"getFeatures\" not implemented on ${ this.name }`);\r\n }\r\n\r\n static destroyContext(context) {\r\n throw new Error(`\"destroyContext\" called on ${ this.name }`);\r\n }\r\n\r\n static nativeFunctionArguments() {\r\n throw new Error(`\"nativeFunctionArguments\" called on ${ this.name }`);\r\n }\r\n\r\n static nativeFunctionReturnType() {\r\n throw new Error(`\"nativeFunctionReturnType\" called on ${ this.name }`);\r\n }\r\n\r\n static combineKernels() {\r\n throw new Error(`\"combineKernels\" called on ${ this.name }`);\r\n }\r\n\r\n /**\r\n *\r\n * @param {string|object} source\r\n * @param [settings]\r\n */\r\n constructor(source, settings) {\r\n if (typeof source !== 'object') {\r\n if (typeof source !== 'string') {\r\n throw new Error('source not a string');\r\n }\r\n if (!isFunctionString(source)) {\r\n throw new Error('source not a function string');\r\n }\r\n }\r\n this.useLegacyEncoder = false;\r\n this.fallbackRequested = false;\r\n this.onRequestFallback = null;\r\n\r\n /**\r\n * Name of the arguments found from parsing source argument\r\n * @type {String[]}\r\n */\r\n this.argumentNames = typeof source === 'string' ? getArgumentNamesFromString(source) : null;\r\n this.argumentTypes = null;\r\n this.argumentSizes = null;\r\n this.argumentBitRatios = null;\r\n this.kernelArguments = null;\r\n this.kernelConstants = null;\r\n\r\n\r\n /**\r\n * The function source\r\n * @type {String}\r\n */\r\n this.source = source;\r\n\r\n /**\r\n * The size of the kernel's output\r\n * @type {Number[]}\r\n */\r\n this.output = null;\r\n\r\n /**\r\n * Debug mode\r\n * @type {Boolean}\r\n */\r\n this.debug = false;\r\n\r\n /**\r\n * Graphical mode\r\n * @type {Boolean}\r\n */\r\n this.graphical = false;\r\n\r\n /**\r\n * Maximum loops when using argument values to prevent infinity\r\n * @type {Number}\r\n */\r\n this.loopMaxIterations = 0;\r\n\r\n /**\r\n * Constants used in kernel via `this.constants`\r\n * @type {Object}\r\n */\r\n this.constants = null;\r\n this.constantTypes = null;\r\n this.constantBitRatios = null;\r\n this.dynamicArguments = false;\r\n this.dynamicOutput = false;\r\n\r\n /**\r\n *\r\n * @type {Object}\r\n */\r\n this.canvas = null;\r\n\r\n /**\r\n *\r\n * @type {WebGLRenderingContext}\r\n */\r\n this.context = null;\r\n\r\n /**\r\n *\r\n * @type {Boolean}\r\n */\r\n this.checkContext = null;\r\n\r\n /**\r\n *\r\n * @type {GPU}\r\n */\r\n this.gpu = null;\r\n\r\n /**\r\n *\r\n * @type {IGPUFunction[]}\r\n */\r\n this.functions = null;\r\n\r\n /**\r\n *\r\n * @type {IGPUNativeFunction[]}\r\n */\r\n this.nativeFunctions = null;\r\n\r\n /**\r\n *\r\n * @type {String}\r\n */\r\n this.injectedNative = null;\r\n\r\n /**\r\n *\r\n * @type {ISubKernel[]}\r\n */\r\n this.subKernels = null;\r\n\r\n /**\r\n *\r\n * @type {Boolean}\r\n */\r\n this.validate = true;\r\n\r\n /**\r\n * Enforces kernel to write to a new array or texture on run\r\n * @type {Boolean}\r\n */\r\n this.immutable = false;\r\n\r\n /**\r\n * Enforces kernel to write to a texture on run\r\n * @type {Boolean}\r\n */\r\n this.pipeline = false;\r\n\r\n /**\r\n * Make GPU use single precison or unsigned. Acceptable values: 'single' or 'unsigned'\r\n * @type {String|null}\r\n * @enum 'single' | 'unsigned'\r\n */\r\n this.precision = null;\r\n\r\n /**\r\n *\r\n * @type {String|null}\r\n * @enum 'speed' | 'balanced' | 'precision'\r\n */\r\n this.tactic = 'balanced';\r\n\r\n this.plugins = null;\r\n\r\n this.returnType = null;\r\n this.leadingReturnStatement = null;\r\n this.followingReturnStatement = null;\r\n this.optimizeFloatMemory = null;\r\n this.strictIntegers = false;\r\n this.fixIntegerDivisionAccuracy = null;\r\n this.warnVarUsage = true;\r\n }\r\n\r\n mergeSettings(settings) {\r\n for (let p in settings) {\r\n if (!settings.hasOwnProperty(p) || !this.hasOwnProperty(p)) continue;\r\n switch (p) {\r\n case 'output':\r\n if (!Array.isArray(settings.output)) {\r\n this.setOutput(settings.output); // Flatten output object\r\n continue;\r\n }\r\n break;\r\n case 'functions':\r\n if (typeof settings.functions[0] === 'function') {\r\n this.functions = settings.functions.map(source => functionToIFunction(source));\r\n continue;\r\n }\r\n break;\r\n case 'graphical':\r\n if (settings[p] && !settings.hasOwnProperty('precision')) {\r\n this.precision = 'unsigned';\r\n }\r\n this[p] = settings[p];\r\n continue;\r\n }\r\n this[p] = settings[p];\r\n }\r\n\r\n if (!this.canvas) this.canvas = this.initCanvas();\r\n if (!this.context) this.context = this.initContext();\r\n if (!this.plugins) this.plugins = this.initPlugins(settings);\r\n }\r\n /**\r\n * @desc Builds the Kernel, by compiling Fragment and Vertical Shaders,\r\n * and instantiates the program.\r\n * @abstract\r\n */\r\n build() {\r\n throw new Error(`\"build\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @desc Run the kernel program, and send the output to renderOutput\r\n *

This method calls a helper method *renderOutput* to return the result.

\r\n * @returns {Float32Array|Float32Array[]|Float32Array[][]|void} Result The final output of the program, as float, and as Textures for reuse.\r\n * @abstract\r\n */\r\n run() {\r\n throw new Error(`\"run\" not defined on ${ this.constructor.name }`)\r\n }\r\n\r\n /**\r\n * @abstract\r\n * @return {Object}\r\n */\r\n initCanvas() {\r\n throw new Error(`\"initCanvas\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @abstract\r\n * @return {Object}\r\n */\r\n initContext() {\r\n throw new Error(`\"initContext\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @param {IFunctionSettings} settings\r\n * @return {Object};\r\n * @abstract\r\n */\r\n initPlugins(settings) {\r\n throw new Error(`\"initPlugins\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @desc Setup the parameter types for the parameters\r\n * supplied to the Kernel function\r\n *\r\n * @param {IArguments} args - The actual parameters sent to the Kernel\r\n */\r\n setupArguments(args) {\r\n this.kernelArguments = [];\r\n if (!this.argumentTypes) {\r\n if (!this.argumentTypes) {\r\n this.argumentTypes = [];\r\n for (let i = 0; i < args.length; i++) {\r\n const argType = getVariableType(args[i], this.strictIntegers);\r\n const type = argType === 'Integer' ? 'Number' : argType;\r\n this.argumentTypes.push(type);\r\n this.kernelArguments.push({\r\n type\r\n });\r\n }\r\n }\r\n } else {\r\n for (let i = 0; i < this.argumentTypes.length; i++) {\r\n this.kernelArguments.push({\r\n type: this.argumentTypes[i]\r\n });\r\n }\r\n }\r\n\r\n // setup sizes\r\n this.argumentSizes = new Array(args.length);\r\n this.argumentBitRatios = new Int32Array(args.length);\r\n\r\n for (let i = 0; i < args.length; i++) {\r\n const arg = args[i];\r\n this.argumentSizes[i] = arg.constructor === Input ? arg.size : null;\r\n this.argumentBitRatios[i] = this.getBitRatio(arg);\r\n }\r\n\r\n if (this.argumentNames.length !== args.length) {\r\n throw new Error(`arguments are miss-aligned`);\r\n }\r\n }\r\n\r\n /**\r\n * Setup constants\r\n */\r\n setupConstants() {\r\n this.kernelConstants = [];\r\n let needsConstantTypes = this.constantTypes === null;\r\n if (needsConstantTypes) {\r\n this.constantTypes = {};\r\n }\r\n this.constantBitRatios = {};\r\n if (this.constants) {\r\n for (let name in this.constants) {\r\n if (needsConstantTypes) {\r\n const type = getVariableType(this.constants[name], this.strictIntegers);\r\n this.constantTypes[name] = type;\r\n this.kernelConstants.push({\r\n name,\r\n type\r\n });\r\n } else {\r\n this.kernelConstants.push({\r\n name,\r\n type: this.constantTypes[name]\r\n });\r\n }\r\n this.constantBitRatios[name] = this.getBitRatio(this.constants[name]);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setOptimizeFloatMemory(flag) {\r\n this.optimizeFloatMemory = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Set output dimensions of the kernel function\r\n * @param {Array|Object} output - The output array to set the kernel output size to\r\n */\r\n setOutput(output) {\r\n if (output.hasOwnProperty('x')) {\r\n if (output.hasOwnProperty('y')) {\r\n if (output.hasOwnProperty('z')) {\r\n this.output = [output.x, output.y, output.z];\r\n } else {\r\n this.output = [output.x, output.y];\r\n }\r\n } else {\r\n this.output = [output.x];\r\n }\r\n } else {\r\n this.output = output;\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Toggle debug mode\r\n * @param {Boolean} flag - true to enable debug\r\n */\r\n setDebug(flag) {\r\n this.debug = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Toggle graphical output mode\r\n * @param {Boolean} flag - true to enable graphical output\r\n */\r\n setGraphical(flag) {\r\n this.graphical = flag;\r\n this.precision = 'unsigned';\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Set the maximum number of loop iterations\r\n * @param {number} max - iterations count\r\n *\r\n */\r\n setLoopMaxIterations(max) {\r\n this.loopMaxIterations = max;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Set Constants\r\n */\r\n setConstants(constants) {\r\n this.constants = constants;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param [IKernelValueTypes] constantTypes\r\n * @return {Kernel}\r\n */\r\n setConstantTypes(constantTypes) {\r\n this.constantTypes = constantTypes;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param {IFunction[]|KernelFunction[]} functions\r\n * @return {Kernel}\r\n */\r\n setFunctions(functions) {\r\n if (typeof functions[0] === 'function') {\r\n this.functions = functions.map(source => functionToIFunction(source));\r\n } else {\r\n this.functions = functions;\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param {IGPUNativeFunction} nativeFunctions\r\n * @return {Kernel}\r\n */\r\n setNativeFunctions(nativeFunctions) {\r\n this.nativeFunctions = nativeFunctions;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param {String} injectedNative\r\n * @return {Kernel}\r\n */\r\n setInjectedNative(injectedNative) {\r\n this.injectedNative = injectedNative;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set writing to texture on/off\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setPipeline(flag) {\r\n this.pipeline = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set precision to 'unsigned' or 'single'\r\n * @param {String} flag 'unsigned' or 'single'\r\n * @return {Kernel}\r\n */\r\n setPrecision(flag) {\r\n this.precision = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param flag\r\n * @return {Kernel}\r\n * @deprecated\r\n */\r\n setOutputToTexture(flag) {\r\n warnDeprecated('method', 'setOutputToTexture', 'setPipeline');\r\n this.pipeline = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set to immutable\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setImmutable(flag) {\r\n this.immutable = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Bind the canvas to kernel\r\n * @param {Object} canvas\r\n */\r\n setCanvas(canvas) {\r\n this.canvas = canvas;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param {Boolean} flag\r\n * @return {Kernel}\r\n */\r\n setStrictIntegers(flag) {\r\n this.strictIntegers = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setDynamicOutput(flag) {\r\n this.dynamicOutput = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @deprecated\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setHardcodeConstants(flag) {\r\n warnDeprecated('method', 'setHardcodeConstants');\r\n this.setDynamicOutput(flag);\r\n this.setDynamicArguments(flag);\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setDynamicArguments(flag) {\r\n this.dynamicArguments = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param {Boolean} flag\r\n * @return {Kernel}\r\n */\r\n setUseLegacyEncoder(flag) {\r\n this.useLegacyEncoder = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Boolean} flag\r\n * @return {Kernel}\r\n */\r\n setWarnVarUsage(flag) {\r\n this.warnVarUsage = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @deprecated\r\n * @returns {Object}\r\n */\r\n getCanvas() {\r\n warnDeprecated('method', 'getCanvas');\r\n return this.canvas;\r\n }\r\n\r\n /**\r\n * @deprecated\r\n * @returns {Object}\r\n */\r\n getWebGl() {\r\n warnDeprecated('method', 'getWebGl');\r\n return this.context;\r\n }\r\n\r\n /**\r\n * @desc Bind the webGL instance to kernel\r\n * @param {WebGLRenderingContext} context - webGl instance to bind\r\n */\r\n setContext(context) {\r\n this.context = context;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param [IKernelValueTypes|GPUVariableType[]] argumentTypes\r\n * @return {Kernel}\r\n */\r\n setArgumentTypes(argumentTypes) {\r\n if (Array.isArray(argumentTypes)) {\r\n this.argumentTypes = argumentTypes;\r\n } else {\r\n this.argumentTypes = [];\r\n for (const p in argumentTypes) {\r\n const argumentIndex = this.argumentNames.indexOf(p);\r\n if (argumentIndex === -1) throw new Error(`unable to find argument ${ p }`);\r\n this.argumentTypes[argumentIndex] = argumentTypes[p];\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param [Tactic] tactic\r\n * @return {Kernel}\r\n */\r\n setTactic(tactic) {\r\n this.tactic = tactic;\r\n return this;\r\n }\r\n\r\n requestFallback(args) {\r\n if (!this.onRequestFallback) {\r\n throw new Error(`\"onRequestFallback\" not defined on ${ this.constructor.name }`);\r\n }\r\n this.fallbackRequested = true;\r\n return this.onRequestFallback(args);\r\n }\r\n\r\n /**\r\n * @desc Validate settings\r\n * @abstract\r\n */\r\n validateSettings() {\r\n throw new Error(`\"validateSettings\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @desc Add a sub kernel to the root kernel instance.\r\n * This is what `createKernelMap` uses.\r\n *\r\n * @param {ISubKernel} subKernel - function (as a String) of the subKernel to add\r\n */\r\n addSubKernel(subKernel) {\r\n if (this.subKernels === null) {\r\n this.subKernels = [];\r\n }\r\n if (!subKernel.source) throw new Error('subKernel missing \"source\" property');\r\n if (!subKernel.property && isNaN(subKernel.property)) throw new Error('subKernel missing \"property\" property');\r\n if (!subKernel.name) throw new Error('subKernel missing \"name\" property');\r\n this.subKernels.push(subKernel);\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Destroys all memory associated with this kernel\r\n * @param {Boolean} [removeCanvasReferences] remove any associated canvas references\r\n */\r\n destroy(removeCanvasReferences) {\r\n throw new Error(`\"destroy\" called on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * bit storage ratio of source to target 'buffer', i.e. if 8bit array -> 32bit tex = 4\r\n * @param value\r\n * @returns {number}\r\n */\r\n getBitRatio(value) {\r\n if (this.precision === 'single') {\r\n // 8 and 16 are upconverted to float32\r\n return 4;\r\n } else if (Array.isArray(value[0])) {\r\n return this.getBitRatio(value[0]);\r\n } else if (value.constructor === Input) {\r\n return this.getBitRatio(value.value);\r\n }\r\n switch (value.constructor) {\r\n case Uint8ClampedArray:\r\n case Uint8Array:\r\n case Int8Array:\r\n return 1;\r\n case Uint16Array:\r\n case Int16Array:\r\n return 2;\r\n case Float32Array:\r\n case Int32Array:\r\n default:\r\n return 4;\r\n }\r\n }\r\n\r\n /**\r\n * @returns {number[]}\r\n */\r\n getPixels() {\r\n throw new Error(`\"getPixels\" called on ${ this.constructor.name }`);\r\n }\r\n\r\n checkOutput() {\r\n if (!this.output || !isArray(this.output)) throw new Error('kernel.output not an array');\r\n if (this.output.length < 1) throw new Error('kernel.output is empty, needs at least 1 value');\r\n for (let i = 0; i < this.output.length; i++) {\r\n if (isNaN(this.output[i]) || this.output[i] < 1) {\r\n throw new Error(`${ this.constructor.name }.output[${ i }] incorrectly defined as \\`${ this.output[i] }\\`, needs to be numeric, and greater than 0`);\r\n }\r\n }\r\n }\r\n\r\n toJSON() {\r\n const settings = {\r\n output: this.output,\r\n threadDim: this.threadDim,\r\n pipeline: this.pipeline,\r\n argumentNames: this.argumentNames,\r\n argumentsTypes: this.argumentTypes,\r\n constants: this.constants,\r\n pluginNames: this.plugins ? this.plugins.map(plugin => plugin.name) : null,\r\n returnType: this.returnType,\r\n };\r\n return {\r\n settings\r\n };\r\n }\r\n}\r\n","/**\r\n * @desc This handles all the raw state, converted state, etc. of a single function.\r\n * [INTERNAL] A collection of functionNodes.\r\n * @class\r\n */\r\nexport class FunctionBuilder {\r\n /**\r\n *\r\n * @param {Kernel} kernel\r\n * @param {FunctionNode} FunctionNode\r\n * @param {object} [extraNodeOptions]\r\n * @returns {FunctionBuilder}\r\n * @static\r\n */\r\n static fromKernel(kernel, FunctionNode, extraNodeOptions) {\r\n const {\r\n kernelArguments,\r\n kernelConstants,\r\n argumentNames,\r\n argumentSizes,\r\n argumentBitRatios,\r\n constants,\r\n constantBitRatios,\r\n debug,\r\n loopMaxIterations,\r\n nativeFunctions,\r\n output,\r\n optimizeFloatMemory,\r\n precision,\r\n plugins,\r\n source,\r\n subKernels,\r\n functions,\r\n leadingReturnStatement,\r\n followingReturnStatement,\r\n dynamicArguments,\r\n dynamicOutput,\r\n warnVarUsage,\r\n } = kernel;\r\n\r\n const argumentTypes = new Array(kernelArguments.length);\r\n const constantTypes = {};\r\n\r\n for (let i = 0; i < kernelArguments.length; i++) {\r\n argumentTypes[i] = kernelArguments[i].type;\r\n }\r\n\r\n for (let i = 0; i < kernelConstants.length; i++) {\r\n const kernelConstant = kernelConstants[i]\r\n constantTypes[kernelConstant.name] = kernelConstant.type;\r\n }\r\n\r\n const needsArgumentType = (functionName, index) => {\r\n return functionBuilder.needsArgumentType(functionName, index);\r\n };\r\n\r\n const assignArgumentType = (functionName, index, type) => {\r\n functionBuilder.assignArgumentType(functionName, index, type);\r\n };\r\n\r\n const lookupReturnType = (functionName, ast, requestingNode) => {\r\n return functionBuilder.lookupReturnType(functionName, ast, requestingNode);\r\n };\r\n\r\n const lookupFunctionArgumentTypes = (functionName) => {\r\n return functionBuilder.lookupFunctionArgumentTypes(functionName);\r\n };\r\n\r\n const lookupFunctionArgumentName = (functionName, argumentIndex) => {\r\n return functionBuilder.lookupFunctionArgumentName(functionName, argumentIndex);\r\n };\r\n\r\n const lookupFunctionArgumentBitRatio = (functionName, argumentName) => {\r\n return functionBuilder.lookupFunctionArgumentBitRatio(functionName, argumentName);\r\n };\r\n\r\n const triggerImplyArgumentType = (functionName, i, argumentType, requestingNode) => {\r\n functionBuilder.assignArgumentType(functionName, i, argumentType, requestingNode);\r\n };\r\n\r\n const triggerTrackArgumentSynonym = (functionName, argumentName, calleeFunctionName, argumentIndex) => {\r\n functionBuilder.trackArgumentSynonym(functionName, argumentName, calleeFunctionName, argumentIndex);\r\n };\r\n\r\n const lookupArgumentSynonym = (originFunctionName, functionName, argumentName) => {\r\n return functionBuilder.lookupArgumentSynonym(originFunctionName, functionName, argumentName);\r\n };\r\n\r\n const onFunctionCall = (functionName, calleeFunctionName, args) => {\r\n functionBuilder.trackFunctionCall(functionName, calleeFunctionName, args);\r\n };\r\n\r\n const onNestedFunction = (ast, returnType) => {\r\n const argumentNames = [];\r\n for (let i = 0; i < ast.params.length; i++) {\r\n argumentNames.push(ast.params[i].name);\r\n }\r\n const nestedFunction = new FunctionNode(null, Object.assign({}, nodeOptions, {\r\n returnType: null,\r\n ast,\r\n name: ast.id.name,\r\n argumentNames,\r\n lookupReturnType,\r\n lookupFunctionArgumentTypes,\r\n lookupFunctionArgumentName,\r\n lookupFunctionArgumentBitRatio,\r\n needsArgumentType,\r\n assignArgumentType,\r\n triggerImplyArgumentType,\r\n triggerTrackArgumentSynonym,\r\n lookupArgumentSynonym,\r\n onFunctionCall,\r\n warnVarUsage,\r\n }));\r\n nestedFunction.traceFunctionAST(ast);\r\n functionBuilder.addFunctionNode(nestedFunction);\r\n };\r\n\r\n const nodeOptions = Object.assign({\r\n isRootKernel: false,\r\n onNestedFunction,\r\n lookupReturnType,\r\n lookupFunctionArgumentTypes,\r\n lookupFunctionArgumentName,\r\n lookupFunctionArgumentBitRatio,\r\n needsArgumentType,\r\n assignArgumentType,\r\n triggerImplyArgumentType,\r\n triggerTrackArgumentSynonym,\r\n lookupArgumentSynonym,\r\n onFunctionCall,\r\n optimizeFloatMemory,\r\n precision,\r\n constants,\r\n constantTypes,\r\n constantBitRatios,\r\n debug,\r\n loopMaxIterations,\r\n output,\r\n plugins,\r\n dynamicArguments,\r\n dynamicOutput,\r\n }, extraNodeOptions || {});\r\n\r\n const rootNodeOptions = Object.assign({}, nodeOptions, {\r\n isRootKernel: true,\r\n name: 'kernel',\r\n argumentNames,\r\n argumentTypes,\r\n argumentSizes,\r\n argumentBitRatios,\r\n leadingReturnStatement,\r\n followingReturnStatement,\r\n });\r\n\r\n if (typeof source === 'object' && source.functionNodes) {\r\n return new FunctionBuilder().fromJSON(source.functionNodes, FunctionNode);\r\n }\r\n\r\n const rootNode = new FunctionNode(source, rootNodeOptions);\r\n\r\n let functionNodes = null;\r\n if (functions) {\r\n functionNodes = functions.map((fn) => new FunctionNode(fn.source, {\r\n returnType: fn.returnType,\r\n argumentTypes: fn.argumentTypes,\r\n output,\r\n plugins,\r\n constants,\r\n constantTypes,\r\n constantBitRatios,\r\n optimizeFloatMemory,\r\n precision,\r\n lookupReturnType,\r\n lookupFunctionArgumentTypes,\r\n lookupFunctionArgumentName,\r\n lookupFunctionArgumentBitRatio,\r\n needsArgumentType,\r\n assignArgumentType,\r\n triggerImplyArgumentType,\r\n triggerTrackArgumentSynonym,\r\n lookupArgumentSynonym,\r\n onFunctionCall,\r\n }));\r\n }\r\n\r\n let subKernelNodes = null;\r\n if (subKernels) {\r\n subKernelNodes = subKernels.map((subKernel) => {\r\n const { name, source } = subKernel;\r\n return new FunctionNode(source, Object.assign({}, nodeOptions, {\r\n name,\r\n isSubKernel: true,\r\n isRootKernel: false,\r\n }));\r\n });\r\n }\r\n\r\n const functionBuilder = new FunctionBuilder({\r\n kernel,\r\n rootNode,\r\n functionNodes,\r\n nativeFunctions,\r\n subKernelNodes\r\n });\r\n\r\n return functionBuilder;\r\n }\r\n\r\n /**\r\n *\r\n * @param {IFunctionBuilderSettings} [settings]\r\n */\r\n constructor(settings) {\r\n settings = settings || {};\r\n this.kernel = settings.kernel;\r\n this.rootNode = settings.rootNode;\r\n this.functionNodes = settings.functionNodes || [];\r\n this.subKernelNodes = settings.subKernelNodes || [];\r\n this.nativeFunctions = settings.nativeFunctions || [];\r\n this.functionMap = {};\r\n this.nativeFunctionNames = [];\r\n this.lookupChain = [];\r\n this.argumentChain = [];\r\n this.functionNodeDependencies = {};\r\n this.functionCalls = {};\r\n\r\n if (this.rootNode) {\r\n this.functionMap['kernel'] = this.rootNode;\r\n }\r\n\r\n if (this.functionNodes) {\r\n for (let i = 0; i < this.functionNodes.length; i++) {\r\n this.functionMap[this.functionNodes[i].name] = this.functionNodes[i];\r\n }\r\n }\r\n\r\n if (this.subKernelNodes) {\r\n for (let i = 0; i < this.subKernelNodes.length; i++) {\r\n this.functionMap[this.subKernelNodes[i].name] = this.subKernelNodes[i];\r\n }\r\n }\r\n\r\n if (this.nativeFunctions) {\r\n for (let i = 0; i < this.nativeFunctions.length; i++) {\r\n const nativeFunction = this.nativeFunctions[i];\r\n this.nativeFunctionNames.push(nativeFunction.name);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @desc Add the function node directly\r\n *\r\n * @param {FunctionNode} functionNode - functionNode to add\r\n *\r\n */\r\n addFunctionNode(functionNode) {\r\n if (!functionNode.name) throw new Error('functionNode.name needs set');\r\n this.functionMap[functionNode.name] = functionNode;\r\n if (functionNode.isRootKernel) {\r\n this.rootNode = functionNode;\r\n }\r\n }\r\n\r\n /**\r\n * @desc Trace all the depending functions being called, from a single function\r\n *\r\n * This allow for 'unneeded' functions to be automatically optimized out.\r\n * Note that the 0-index, is the starting function trace.\r\n *\r\n * @param {String} functionName - Function name to trace from, default to 'kernel'\r\n * @param {String[]} [retList] - Returning list of function names that is traced. Including itself.\r\n *\r\n * @returns {String[]} Returning list of function names that is traced. Including itself.\r\n */\r\n traceFunctionCalls(functionName, retList) {\r\n functionName = functionName || 'kernel';\r\n retList = retList || [];\r\n\r\n if (this.nativeFunctionNames.indexOf(functionName) > -1) {\r\n if (retList.indexOf(functionName) === -1) {\r\n retList.push(functionName);\r\n }\r\n return retList;\r\n }\r\n\r\n const functionNode = this.functionMap[functionName];\r\n if (functionNode) {\r\n // Check if function already exists\r\n const functionIndex = retList.indexOf(functionName);\r\n if (functionIndex === -1) {\r\n retList.push(functionName);\r\n functionNode.toString(); //ensure JS trace is done\r\n for (let i = 0; i < functionNode.calledFunctions.length; ++i) {\r\n this.traceFunctionCalls(functionNode.calledFunctions[i], retList);\r\n }\r\n } else {\r\n /**\r\n * https://github.com/gpujs/gpu.js/issues/207\r\n * if dependent function is already in the list, because a function depends on it, and because it has\r\n * already been traced, we know that we must move the dependent function to the end of the the retList.\r\n * */\r\n const dependantFunctionName = retList.splice(functionIndex, 1)[0];\r\n retList.push(dependantFunctionName);\r\n }\r\n }\r\n\r\n return retList;\r\n }\r\n\r\n /**\r\n * @desc Return the string for a function\r\n * @param {String} functionName - Function name to trace from. If null, it returns the WHOLE builder stack\r\n * @returns {String} The full string, of all the various functions. Trace optimized if functionName given\r\n */\r\n getPrototypeString(functionName) {\r\n return this.getPrototypes(functionName).join('\\n');\r\n }\r\n\r\n /**\r\n * @desc Return the string for a function\r\n * @param {String} [functionName] - Function name to trace from. If null, it returns the WHOLE builder stack\r\n * @returns {Array} The full string, of all the various functions. Trace optimized if functionName given\r\n */\r\n getPrototypes(functionName) {\r\n if (this.rootNode) {\r\n this.rootNode.toString();\r\n }\r\n if (functionName) {\r\n return this.getPrototypesFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse());\r\n }\r\n return this.getPrototypesFromFunctionNames(Object.keys(this.functionMap));\r\n }\r\n\r\n /**\r\n * @desc Get string from function names\r\n * @param {String[]} functionList - List of function to build string\r\n * @returns {String} The string, of all the various functions. Trace optimized if functionName given\r\n */\r\n getStringFromFunctionNames(functionList) {\r\n const ret = [];\r\n for (let i = 0; i < functionList.length; ++i) {\r\n const node = this.functionMap[functionList[i]];\r\n if (node) {\r\n ret.push(this.functionMap[functionList[i]].toString());\r\n }\r\n }\r\n return ret.join('\\n');\r\n }\r\n\r\n /**\r\n * @desc Return string of all functions converted\r\n * @param {String[]} functionList - List of function names to build the string.\r\n * @returns {Array} Prototypes of all functions converted\r\n */\r\n getPrototypesFromFunctionNames(functionList) {\r\n const ret = [];\r\n for (let i = 0; i < functionList.length; ++i) {\r\n const functionName = functionList[i];\r\n const functionIndex = this.nativeFunctionNames.indexOf(functionName);\r\n if (functionIndex > -1) {\r\n ret.push(this.nativeFunctions[functionIndex].source);\r\n continue;\r\n }\r\n const node = this.functionMap[functionName];\r\n if (node) {\r\n ret.push(node.toString());\r\n }\r\n }\r\n return ret;\r\n }\r\n\r\n toJSON() {\r\n return this.traceFunctionCalls(this.rootNode.name).reverse().map(name => {\r\n const nativeIndex = this.nativeFunctions.indexOf(name);\r\n if (nativeIndex > -1) {\r\n return {\r\n name,\r\n source: this.nativeFunctions[nativeIndex].source\r\n };\r\n } else if (this.functionMap[name]) {\r\n return this.functionMap[name].toJSON();\r\n } else {\r\n throw new Error(`function ${ name } not found`);\r\n }\r\n });\r\n }\r\n\r\n fromJSON(jsonFunctionNodes, FunctionNode) {\r\n this.functionMap = {};\r\n for (let i = 0; i < jsonFunctionNodes.length; i++) {\r\n const jsonFunctionNode = jsonFunctionNodes[i];\r\n this.functionMap[jsonFunctionNode.settings.name] = new FunctionNode(jsonFunctionNode.ast, jsonFunctionNode.settings);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Get string for a particular function name\r\n * @param {String} functionName - Function name to trace from. If null, it returns the WHOLE builder stack\r\n * @returns {String} settings - The string, of all the various functions. Trace optimized if functionName given\r\n */\r\n getString(functionName) {\r\n if (functionName) {\r\n return this.getStringFromFunctionNames(this.traceFunctionCalls(functionName).reverse());\r\n }\r\n return this.getStringFromFunctionNames(Object.keys(this.functionMap));\r\n }\r\n\r\n lookupReturnType(functionName, ast, requestingNode) {\r\n if (ast.type !== 'CallExpression') {\r\n throw new Error(`expected ast type of \"CallExpression\", but is ${ ast.type }`);\r\n }\r\n if (this._isNativeFunction(functionName)) {\r\n return this._lookupNativeFunctionReturnType(functionName);\r\n } else if (this._isFunction(functionName)) {\r\n const node = this._getFunction(functionName);\r\n if (node.returnType) {\r\n return node.returnType;\r\n } else {\r\n for (let i = 0; i < this.lookupChain.length; i++) {\r\n // detect circlical logic\r\n if (this.lookupChain[i].ast === ast) {\r\n // detect if arguments have not resolved, preventing a return type\r\n // if so, go ahead and resolve them, so we can resolve the return type\r\n if (node.argumentTypes.length === 0 && ast.arguments.length > 0) {\r\n const args = ast.arguments;\r\n for (let j = 0; j < args.length; j++) {\r\n this.lookupChain.push({\r\n name: requestingNode.name,\r\n ast: args[i],\r\n requestingNode\r\n });\r\n node.argumentTypes[j] = requestingNode.getType(args[j]);\r\n this.lookupChain.pop();\r\n }\r\n return node.returnType = node.getType(node.getJsAST());\r\n }\r\n\r\n throw new Error('circlical logic detected!');\r\n }\r\n }\r\n // get ready for a ride!\r\n this.lookupChain.push({\r\n name: requestingNode.name,\r\n ast,\r\n requestingNode\r\n });\r\n const type = node.getType(node.getJsAST());\r\n this.lookupChain.pop();\r\n return node.returnType = type;\r\n }\r\n }\r\n\r\n // function not found, maybe native?\r\n return null;\r\n\r\n /**\r\n * first iteration\r\n * kernel.outputs = Array\r\n * kernel.targets = Array\r\n * kernel.returns = null\r\n * kernel.calls.calcErrorOutput = [kernel.output, kernel.targets]\r\n * kernel.calls.calcDeltas = [calcErrorOutput.returns, kernel.output]\r\n * calcErrorOutput.output = null\r\n * calcErrorOutput.targets = null\r\n * calcErrorOutput.returns = null\r\n * calcDeltasSigmoid.error = null\r\n * calcDeltasSigmoid.output = Number\r\n * calcDeltasSigmoid.returns = null\r\n *\r\n * resolvable are:\r\n * calcErrorOutput.output\r\n * calcErrorOutput.targets\r\n * calcErrorOutput.returns\r\n *\r\n * second iteration\r\n * kernel.outputs = Array\r\n * kernel.targets = Array\r\n * kernel.returns = null\r\n * kernel.calls.calcErrorOutput = [kernel.output, kernel.targets]\r\n * kernel.calls.calcDeltas = [calcErrorOutput.returns, kernel.output]\r\n * calcErrorOutput.output = Number\r\n * calcErrorOutput.targets = Array\r\n * calcErrorOutput.returns = Number\r\n * calcDeltasSigmoid.error = null\r\n * calcDeltasSigmoid.output = Number\r\n * calcDeltasSigmoid.returns = null\r\n *\r\n * resolvable are:\r\n * calcDeltasSigmoid.error\r\n * calcDeltasSigmoid.returns\r\n * kernel.returns\r\n *\r\n * third iteration\r\n * kernel.outputs = Array\r\n * kernel.targets = Array\r\n * kernel.returns = Number\r\n * kernel.calls.calcErrorOutput = [kernel.output, kernel.targets]\r\n * kernel.calls.calcDeltas = [calcErrorOutput.returns, kernel.output]\r\n * calcErrorOutput.output = Number\r\n * calcErrorOutput.targets = Array\r\n * calcErrorOutput.returns = Number\r\n * calcDeltasSigmoid.error = Number\r\n * calcDeltasSigmoid.output = Number\r\n * calcDeltasSigmoid.returns = Number\r\n *\r\n *\r\n */\r\n }\r\n\r\n _getFunction(functionName) {\r\n if (!this._isFunction(functionName)) {\r\n new Error(`Function ${functionName} not found`);\r\n }\r\n return this.functionMap[functionName];\r\n }\r\n\r\n _isFunction(functionName) {\r\n return Boolean(this.functionMap[functionName]);\r\n }\r\n\r\n _getNativeFunction(functionName) {\r\n for (let i = 0; i < this.nativeFunctions.length; i++) {\r\n if (this.nativeFunctions[i].name === functionName) return this.nativeFunctions[i];\r\n }\r\n return null;\r\n }\r\n\r\n _isNativeFunction(functionName) {\r\n return Boolean(this._getNativeFunction(functionName));\r\n }\r\n\r\n _lookupNativeFunctionReturnType(functionName) {\r\n let nativeFunction = this._getNativeFunction(functionName);\r\n if (nativeFunction) {\r\n return nativeFunction.returnType;\r\n }\r\n throw new Error(`Native function ${ functionName } not found`);\r\n }\r\n\r\n lookupFunctionArgumentTypes(functionName) {\r\n if (this._isNativeFunction(functionName)) {\r\n return this._getNativeFunction(functionName).argumentTypes;\r\n } else if (this._isFunction(functionName)) {\r\n return this._getFunction(functionName).argumentTypes;\r\n }\r\n return null;\r\n }\r\n\r\n lookupFunctionArgumentName(functionName, argumentIndex) {\r\n return this._getFunction(functionName).argumentNames[argumentIndex];\r\n }\r\n\r\n lookupFunctionArgumentBitRatio(functionName, argumentName) {\r\n if (!this._isFunction(functionName)) {\r\n throw new Error('function not found');\r\n }\r\n if (this.rootNode.name === functionName) {\r\n const i = this.rootNode.argumentNames.indexOf(argumentName);\r\n if (i !== -1) {\r\n return this.rootNode.argumentBitRatios[i];\r\n } else {\r\n throw new Error('argument bit ratio not found');\r\n }\r\n } else {\r\n const node = this._getFunction(functionName);\r\n const argumentSynonym = node.argumentSynonym[node.synonymIndex];\r\n if (!argumentSynonym) {\r\n throw new Error('argument synonym not found');\r\n }\r\n return this.lookupFunctionArgumentBitRatio(argumentSynonym.functionName, argumentSynonym.argumentName);\r\n }\r\n }\r\n\r\n needsArgumentType(functionName, i) {\r\n if (!this._isFunction(functionName)) return false;\r\n const fnNode = this._getFunction(functionName);\r\n return !fnNode.argumentTypes[i];\r\n }\r\n\r\n assignArgumentType(functionName, i, argumentType, requestingNode) {\r\n if (!this._isFunction(functionName)) return;\r\n const fnNode = this._getFunction(functionName);\r\n if (!fnNode.argumentTypes[i]) {\r\n fnNode.argumentTypes[i] = argumentType;\r\n }\r\n }\r\n\r\n trackArgumentSynonym(functionName, argumentName, calleeFunctionName, argumentIndex) {\r\n if (!this._isFunction(calleeFunctionName)) return;\r\n const node = this._getFunction(calleeFunctionName);\r\n if (!node.argumentSynonym) {\r\n node.argumentSynonym = {};\r\n }\r\n const calleeArgumentName = node.argumentNames[argumentIndex];\r\n if (!node.argumentSynonym[calleeArgumentName]) {\r\n node.argumentSynonym[calleeArgumentName] = {};\r\n }\r\n node.synonymIndex++;\r\n node.argumentSynonym[node.synonymIndex] = {\r\n functionName,\r\n argumentName,\r\n calleeArgumentName,\r\n calleeFunctionName,\r\n };\r\n }\r\n\r\n lookupArgumentSynonym(originFunctionName, functionName, argumentName) {\r\n if (originFunctionName === functionName) return argumentName;\r\n if (!this._isFunction(functionName)) return null;\r\n const node = this._getFunction(functionName);\r\n const argumentSynonym = node.argumentSynonym[node.synonymUseIndex];\r\n if (!argumentSynonym) return null;\r\n if (argumentSynonym.calleeArgumentName !== argumentName) return null;\r\n node.synonymUseIndex++;\r\n if (originFunctionName !== functionName) {\r\n return this.lookupArgumentSynonym(originFunctionName, argumentSynonym.functionName, argumentSynonym.argumentName);\r\n }\r\n return argumentSynonym.argumentName;\r\n }\r\n\r\n trackFunctionCall(functionName, calleeFunctionName, args) {\r\n if (!this.functionNodeDependencies[functionName]) {\r\n this.functionNodeDependencies[functionName] = new Set();\r\n this.functionCalls[functionName] = [];\r\n }\r\n this.functionNodeDependencies[functionName].add(calleeFunctionName);\r\n this.functionCalls[functionName].push(args);\r\n }\r\n\r\n getKernelResultType() {\r\n return this.rootNode.returnType || this.rootNode.getType(this.rootNode.ast);\r\n }\r\n\r\n getSubKernelResultType(index) {\r\n const subKernelNode = this.subKernelNodes[index];\r\n let called = false;\r\n for (let functionCallIndex = 0; functionCallIndex < this.rootNode.functionCalls.length; functionCallIndex++) {\r\n const functionCall = this.rootNode.functionCalls[functionCallIndex];\r\n if (functionCall.ast.callee.name === subKernelNode.name) {\r\n called = true;\r\n }\r\n }\r\n if (!called) {\r\n throw new Error(`SubKernel ${ subKernelNode.name } never called by kernel`);\r\n }\r\n return subKernelNode.returnType || subKernelNode.getType(subKernelNode.getJsAST());\r\n }\r\n\r\n getReturnTypes() {\r\n const result = {\r\n [this.rootNode.name]: this.rootNode.getType(this.rootNode.ast),\r\n };\r\n const list = this.traceFunctionCalls(this.rootNode.name);\r\n for (let i = 0; i < list.length; i++) {\r\n const functionName = list[i];\r\n const functionNode = this.functionMap[functionName];\r\n result[functionName] = functionNode.getType(functionNode.ast);\r\n }\r\n return result;\r\n }\r\n}\r\n","export class FunctionTracer {\r\n constructor(ast) {\r\n this.runningContexts = [];\r\n this.contexts = [];\r\n this.functionCalls = [];\r\n this.declarations = [];\r\n this.identifiers = [];\r\n this.functions = [];\r\n this.returnStatements = [];\r\n this.inLoopInit = false;\r\n this.scan(ast);\r\n }\r\n\r\n get currentContext() {\r\n return this.runningContexts.length > 0 ? this.runningContexts[this.runningContexts.length - 1] : null;\r\n }\r\n\r\n newContext(run) {\r\n const newContext = Object.assign({}, this.currentContext);\r\n this.contexts.push(newContext);\r\n this.runningContexts.push(newContext);\r\n run();\r\n this.runningContexts.pop();\r\n }\r\n\r\n /**\r\n * Recursively scans AST for declarations and functions, and add them to their respective context\r\n * @param ast\r\n */\r\n scan(ast) {\r\n if (Array.isArray(ast)) {\r\n for (let i = 0; i < ast.length; i++) {\r\n this.scan(ast[i]);\r\n }\r\n return;\r\n }\r\n switch (ast.type) {\r\n case 'Program':\r\n this.scan(ast.body);\r\n break;\r\n case 'BlockStatement':\r\n this.newContext(() => {\r\n this.scan(ast.body);\r\n });\r\n break;\r\n case 'AssignmentExpression':\r\n case 'LogicalExpression':\r\n this.scan(ast.left);\r\n this.scan(ast.right);\r\n break;\r\n case 'BinaryExpression':\r\n this.scan(ast.left);\r\n this.scan(ast.right);\r\n break;\r\n case 'UpdateExpression':\r\n case 'UnaryExpression':\r\n this.scan(ast.argument);\r\n break;\r\n case 'VariableDeclaration':\r\n this.scan(ast.declarations);\r\n break;\r\n case 'VariableDeclarator':\r\n const { currentContext } = this;\r\n const declaration = {\r\n ast: ast,\r\n context: currentContext,\r\n name: ast.id.name,\r\n origin: 'declaration',\r\n forceInteger: this.inLoopInit,\r\n assignable: !this.inLoopInit && !currentContext.hasOwnProperty(ast.id.name),\r\n };\r\n currentContext[ast.id.name] = declaration;\r\n this.declarations.push(declaration);\r\n this.scan(ast.id);\r\n this.scan(ast.init);\r\n break;\r\n case 'FunctionExpression':\r\n case 'FunctionDeclaration':\r\n if (this.runningContexts.length === 0) {\r\n this.scan(ast.body);\r\n } else {\r\n this.functions.push(ast);\r\n }\r\n break;\r\n case 'IfStatement':\r\n this.scan(ast.test);\r\n this.scan(ast.consequent);\r\n if (ast.alternate) this.scan(ast.alternate);\r\n break;\r\n case 'ForStatement':\r\n this.newContext(() => {\r\n this.inLoopInit = true;\r\n this.scan(ast.init);\r\n this.inLoopInit = false;\r\n this.scan(ast.test);\r\n this.scan(ast.update);\r\n this.newContext(() => {\r\n this.scan(ast.body);\r\n });\r\n });\r\n break;\r\n case 'DoWhileStatement':\r\n case 'WhileStatement':\r\n this.newContext(() => {\r\n this.scan(ast.body);\r\n this.scan(ast.test);\r\n });\r\n break;\r\n case 'Identifier':\r\n this.identifiers.push({\r\n context: this.currentContext,\r\n ast,\r\n });\r\n break;\r\n case 'ReturnStatement':\r\n this.returnStatements.push(ast);\r\n this.scan(ast.argument);\r\n break;\r\n case 'MemberExpression':\r\n this.scan(ast.object);\r\n this.scan(ast.property);\r\n break;\r\n case 'ExpressionStatement':\r\n this.scan(ast.expression);\r\n break;\r\n case 'CallExpression':\r\n this.functionCalls.push({\r\n context: this.currentContext,\r\n ast,\r\n });\r\n this.scan(ast.arguments);\r\n break;\r\n case 'ArrayExpression':\r\n this.scan(ast.elements);\r\n break;\r\n case 'ConditionalExpression':\r\n this.scan(ast.test);\r\n this.scan(ast.alternate);\r\n this.scan(ast.consequent);\r\n break;\r\n case 'SwitchStatement':\r\n this.scan(ast.discriminant);\r\n this.scan(ast.cases);\r\n break;\r\n case 'SwitchCase':\r\n this.scan(ast.test);\r\n this.scan(ast.consequent);\r\n break;\r\n case 'ThisExpression':\r\n this.scan(ast.left);\r\n this.scan(ast.right);\r\n break;\r\n case 'Literal':\r\n case 'DebuggerStatement':\r\n case 'EmptyStatement':\r\n case 'BreakStatement':\r\n case 'ContinueStatement':\r\n break;\r\n default:\r\n throw new Error(`unhandled type \"${ast.type}\"`);\r\n }\r\n }\r\n}\r\n","import { parse } from 'acorn';\r\nimport { FunctionTracer } from './function-tracer';\r\nimport {\r\n getArgumentNamesFromString,\r\n getAstString,\r\n getFunctionNameFromString,\r\n isFunctionString,\r\n} from '../common';\r\n\r\n/**\r\n *\r\n * @desc Represents a single function, inside JS, webGL, or openGL.\r\n *

This handles all the raw state, converted state, etc. Of a single function.

\r\n */\r\nexport class FunctionNode {\r\n /**\r\n *\r\n * @param {string|object} source\r\n * @param {IFunctionSettings} [settings]\r\n */\r\n constructor(source, settings) {\r\n if (!source && !settings.ast) {\r\n throw new Error('source parameter is missing');\r\n }\r\n settings = settings || {};\r\n this.source = source;\r\n this.ast = null;\r\n this.name = typeof source === 'string' ? settings.isRootKernel ?\r\n 'kernel' :\r\n (settings.name || getFunctionNameFromString(source)) : null;\r\n this.calledFunctions = [];\r\n this.constants = {};\r\n this.constantTypes = {};\r\n this.constantBitRatios = {};\r\n this.isRootKernel = false;\r\n this.isSubKernel = false;\r\n this.debug = null;\r\n this.declarations = null;\r\n this.functions = null;\r\n this.identifiers = null;\r\n this.contexts = null;\r\n this.functionCalls = null;\r\n this.states = [];\r\n this.needsArgumentType = null;\r\n this.assignArgumentType = null;\r\n this.lookupReturnType = null;\r\n this.lookupFunctionArgumentTypes = null;\r\n this.lookupFunctionArgumentBitRatio = null;\r\n this.triggerImplyArgumentType = null;\r\n this.triggerImplyArgumentBitRatio = null;\r\n this.onNestedFunction = null;\r\n this.onFunctionCall = null;\r\n this.optimizeFloatMemory = null;\r\n this.precision = null;\r\n this.loopMaxIterations = null;\r\n this.argumentNames = (typeof this.source === 'string' ? getArgumentNamesFromString(this.source) : null);\r\n this.argumentTypes = [];\r\n this.argumentSizes = [];\r\n this.argumentBitRatios = null;\r\n this.returnType = null;\r\n this.output = [];\r\n this.plugins = null;\r\n this.leadingReturnStatement = null;\r\n this.followingReturnStatement = null;\r\n this.dynamicOutput = null;\r\n this.dynamicArguments = null;\r\n this.strictTypingChecking = false;\r\n this.fixIntegerDivisionAccuracy = null;\r\n this.warnVarUsage = true;\r\n\r\n if (settings) {\r\n for (const p in settings) {\r\n if (!settings.hasOwnProperty(p)) continue;\r\n if (!this.hasOwnProperty(p)) continue;\r\n this[p] = settings[p];\r\n }\r\n }\r\n\r\n this.literalTypes = {};\r\n\r\n this.validate();\r\n this._string = null;\r\n this._internalVariableNames = {};\r\n }\r\n\r\n validate() {\r\n if (typeof this.source !== 'string' && !this.ast) {\r\n throw new Error('this.source not a string');\r\n }\r\n\r\n if (!this.ast && !isFunctionString(this.source)) {\r\n throw new Error('this.source not a function string');\r\n }\r\n\r\n if (!this.name) {\r\n throw new Error('this.name could not be set');\r\n }\r\n\r\n if (this.argumentTypes.length > 0 && this.argumentTypes.length !== this.argumentNames.length) {\r\n throw new Error(`argumentTypes count of ${ this.argumentTypes.length } exceeds ${ this.argumentNames.length }`);\r\n }\r\n\r\n if (this.output.length < 1) {\r\n throw new Error('this.output is not big enough');\r\n }\r\n }\r\n\r\n /**\r\n * @param {String} name\r\n * @returns {boolean}\r\n */\r\n isIdentifierConstant(name) {\r\n if (!this.constants) return false;\r\n return this.constants.hasOwnProperty(name);\r\n }\r\n\r\n isInput(argumentName) {\r\n return this.argumentTypes[this.argumentNames.indexOf(argumentName)] === 'Input';\r\n }\r\n\r\n pushState(state) {\r\n this.states.push(state);\r\n }\r\n\r\n popState(state) {\r\n if (this.state !== state) {\r\n throw new Error(`Cannot popState ${ state } when in ${ this.state }`);\r\n }\r\n this.states.pop();\r\n }\r\n\r\n isState(state) {\r\n return this.state === state;\r\n }\r\n\r\n get state() {\r\n return this.states[this.states.length - 1];\r\n }\r\n\r\n /**\r\n * @function\r\n * @name astMemberExpressionUnroll\r\n * @desc Parses the abstract syntax tree for binary expression.\r\n *\r\n *

Utility function for astCallExpression.

\r\n *\r\n * @param {Object} ast - the AST object to parse\r\n *\r\n * @returns {String} the function namespace call, unrolled\r\n */\r\n astMemberExpressionUnroll(ast) {\r\n if (ast.type === 'Identifier') {\r\n return ast.name;\r\n } else if (ast.type === 'ThisExpression') {\r\n return 'this';\r\n }\r\n\r\n if (ast.type === 'MemberExpression') {\r\n if (ast.object && ast.property) {\r\n //babel sniffing\r\n if (ast.object.hasOwnProperty('name') && ast.object.name[0] === '_') {\r\n return this.astMemberExpressionUnroll(ast.property);\r\n }\r\n\r\n return (\r\n this.astMemberExpressionUnroll(ast.object) +\r\n '.' +\r\n this.astMemberExpressionUnroll(ast.property)\r\n );\r\n }\r\n }\r\n\r\n //babel sniffing\r\n if (ast.hasOwnProperty('expressions')) {\r\n const firstExpression = ast.expressions[0];\r\n if (firstExpression.type === 'Literal' && firstExpression.value === 0 && ast.expressions.length === 2) {\r\n return this.astMemberExpressionUnroll(ast.expressions[1]);\r\n }\r\n }\r\n\r\n // Failure, unknown expression\r\n throw this.astErrorOutput('Unknown astMemberExpressionUnroll', ast);\r\n }\r\n\r\n /**\r\n * @desc Parses the class function JS, and returns its Abstract Syntax Tree object.\r\n * This is used internally to convert to shader code\r\n *\r\n * @param {Object} [inParser] - Parser to use, assumes in scope 'parser' if null or undefined\r\n *\r\n * @returns {Object} The function AST Object, note that result is cached under this.ast;\r\n */\r\n getJsAST(inParser) {\r\n if (this.ast) {\r\n return this.ast;\r\n }\r\n if (typeof this.source === 'object') {\r\n this.traceFunctionAST(this.source);\r\n return this.ast = this.source;\r\n }\r\n\r\n const parser = inParser && inParser.hasOwnProperty('parse') ? inParser.parse : parse\r\n if (inParser === null) {\r\n throw new Error('Missing JS to AST parser');\r\n }\r\n\r\n const ast = Object.freeze(parser(`const parser_${ this.name } = ${ this.source };`, {\r\n locations: true\r\n }));\r\n // take out the function object, outside the var declarations\r\n const functionAST = ast.body[0].declarations[0].init;\r\n this.traceFunctionAST(functionAST);\r\n\r\n if (!ast) {\r\n throw new Error('Failed to parse JS code');\r\n }\r\n\r\n return this.ast = functionAST;\r\n }\r\n\r\n traceFunctionAST(ast) {\r\n const { contexts, declarations, functions, identifiers, functionCalls } = new FunctionTracer(ast);\r\n this.contexts = contexts;\r\n this.identifiers = identifiers;\r\n this.functionCalls = functionCalls;\r\n this.declarations = [];\r\n this.functions = functions;\r\n for (let i = 0; i < declarations.length; i++) {\r\n const declaration = declarations[i];\r\n const { ast, context, name, origin, forceInteger, assignable } = declaration;\r\n const { init } = ast;\r\n const dependencies = this.getDependencies(init);\r\n let valueType = null;\r\n\r\n if (forceInteger) {\r\n valueType = 'Integer';\r\n } else {\r\n if (init) {\r\n const realType = this.getType(init);\r\n switch (realType) {\r\n case 'Integer':\r\n case 'Float':\r\n case 'Number':\r\n if (init.type === 'MemberExpression') {\r\n valueType = realType;\r\n } else {\r\n valueType = 'Number';\r\n }\r\n break;\r\n case 'LiteralInteger':\r\n valueType = 'Number';\r\n break;\r\n default:\r\n valueType = realType;\r\n }\r\n }\r\n }\r\n this.declarations.push({\r\n valueType,\r\n dependencies,\r\n isSafe: this.isSafeDependencies(dependencies),\r\n ast,\r\n name,\r\n context,\r\n origin,\r\n assignable,\r\n });\r\n }\r\n\r\n for (let i = 0; i < functions.length; i++) {\r\n this.onNestedFunction(functions[i]);\r\n }\r\n }\r\n\r\n getDeclaration(ast) {\r\n for (let i = 0; i < this.identifiers.length; i++) {\r\n const identifier = this.identifiers[i];\r\n if (ast === identifier.ast && identifier.context.hasOwnProperty(ast.name)) {\r\n for (let j = 0; j < this.declarations.length; j++) {\r\n const declaration = this.declarations[j];\r\n if (declaration.name === ast.name && declaration.context[ast.name] === identifier.context[ast.name]) {\r\n return declaration;\r\n }\r\n }\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * @desc Return the type of parameter sent to subKernel/Kernel.\r\n * @param {Object} ast - Identifier\r\n * @returns {String} Type of the parameter\r\n */\r\n getVariableType(ast) {\r\n if (ast.type !== 'Identifier') {\r\n throw new Error(`ast of ${ast.type} not \"Identifier\"`);\r\n }\r\n let type = null;\r\n const argumentIndex = this.argumentNames.indexOf(ast.name);\r\n if (argumentIndex === -1) {\r\n const declaration = this.getDeclaration(ast);\r\n if (declaration) {\r\n return declaration.valueType;\r\n }\r\n } else {\r\n const argumentType = this.argumentTypes[argumentIndex];\r\n if (argumentType) {\r\n type = argumentType;\r\n }\r\n }\r\n if (!type && this.strictTypingChecking) {\r\n throw new Error(`Declaration of ${name} not found`);\r\n }\r\n return type;\r\n }\r\n\r\n /**\r\n * Generally used to lookup the value type returned from a member expressions\r\n * @param {String} type\r\n * @return {String}\r\n */\r\n getLookupType(type) {\r\n if (!typeLookupMap.hasOwnProperty(type)) {\r\n throw new Error(`unknown typeLookupMap ${ type }`);\r\n }\r\n return typeLookupMap[type];\r\n }\r\n\r\n getConstantType(constantName) {\r\n if (this.constantTypes[constantName]) {\r\n const type = this.constantTypes[constantName];\r\n if (type === 'Float') {\r\n return 'Number';\r\n } else {\r\n return type;\r\n }\r\n }\r\n throw new Error(`Type for constant \"${ constantName }\" not declared`);\r\n }\r\n\r\n toString() {\r\n if (this._string) return this._string;\r\n return this._string = this.astGeneric(this.getJsAST(), []).join('').trim();\r\n }\r\n\r\n toJSON() {\r\n const settings = {\r\n source: this.source,\r\n name: this.name,\r\n constants: this.constants,\r\n constantTypes: this.constantTypes,\r\n isRootKernel: this.isRootKernel,\r\n isSubKernel: this.isSubKernel,\r\n debug: this.debug,\r\n output: this.output,\r\n loopMaxIterations: this.loopMaxIterations,\r\n argumentNames: this.argumentNames,\r\n argumentTypes: this.argumentTypes,\r\n argumentSizes: this.argumentSizes,\r\n returnType: this.returnType,\r\n leadingReturnStatement: this.leadingReturnStatement,\r\n followingReturnStatement: this.followingReturnStatement,\r\n };\r\n\r\n return {\r\n ast: this.ast,\r\n settings\r\n };\r\n }\r\n\r\n /**\r\n * Recursively looks up type for ast expression until it's found\r\n * @param ast\r\n * @returns {String|null}\r\n */\r\n getType(ast) {\r\n if (Array.isArray(ast)) {\r\n return this.getType(ast[ast.length - 1]);\r\n }\r\n switch (ast.type) {\r\n case 'BlockStatement':\r\n return this.getType(ast.body);\r\n case 'ArrayExpression':\r\n return `Array(${ ast.elements.length })`;\r\n case 'Literal':\r\n const literalKey = `${ast.start},${ast.end}`;\r\n if (this.literalTypes[literalKey]) {\r\n return this.literalTypes[literalKey];\r\n }\r\n if (Number.isInteger(ast.value)) {\r\n return 'LiteralInteger';\r\n } else if (ast.value === true || ast.value === false) {\r\n return 'Boolean';\r\n } else {\r\n return 'Number';\r\n }\r\n case 'AssignmentExpression':\r\n return this.getType(ast.left);\r\n case 'CallExpression':\r\n if (this.isAstMathFunction(ast)) {\r\n return 'Number';\r\n }\r\n if (!ast.callee || !ast.callee.name) {\r\n if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[ast.callee.expressions.length - 1].property.name) {\r\n const functionName = ast.callee.expressions[ast.callee.expressions.length - 1].property.name;\r\n this.inferArgumentTypesIfNeeded(functionName, ast.arguments);\r\n return this.lookupReturnType(functionName, ast, this);\r\n }\r\n throw this.astErrorOutput('Unknown call expression', ast);\r\n }\r\n if (ast.callee && ast.callee.name) {\r\n const functionName = ast.callee.name;\r\n this.inferArgumentTypesIfNeeded(functionName, ast.arguments);\r\n return this.lookupReturnType(functionName, ast, this);\r\n }\r\n throw this.astErrorOutput(`Unhandled getType Type \"${ ast.type }\"`, ast);\r\n case 'BinaryExpression':\r\n // modulos is Number\r\n switch (ast.operator) {\r\n case '%':\r\n case '/':\r\n if (this.fixIntegerDivisionAccuracy) {\r\n return 'Number';\r\n } else {\r\n break;\r\n }\r\n case '>':\r\n case '<':\r\n return 'Boolean';\r\n case '&':\r\n case '|':\r\n case '^':\r\n case '<<':\r\n case '>>':\r\n case '>>>':\r\n return 'Integer';\r\n }\r\n const type = this.getType(ast.left);\r\n if (this.isState('skip-literal-correction')) return type;\r\n if (type === 'LiteralInteger') {\r\n const rightType = this.getType(ast.right);\r\n if (rightType === 'LiteralInteger') {\r\n if (ast.left.value % 1 === 0) {\r\n return 'Integer';\r\n } else {\r\n return 'Float';\r\n }\r\n }\r\n return rightType;\r\n }\r\n return typeLookupMap[type] || type;\r\n case 'UpdateExpression':\r\n return this.getType(ast.argument);\r\n case 'UnaryExpression':\r\n if (ast.operator === '~') {\r\n return 'Integer';\r\n }\r\n return this.getType(ast.argument);\r\n case 'VariableDeclaration': {\r\n const declarations = ast.declarations;\r\n let lastType;\r\n for (let i = 0; i < declarations.length; i++) {\r\n const declaration = declarations[i];\r\n lastType = this.getType(declaration);\r\n }\r\n if (!lastType) {\r\n throw this.astErrorOutput(`Unable to find type for declaration`, ast);\r\n }\r\n return lastType;\r\n }\r\n case 'VariableDeclarator':\r\n const declaration = this.getDeclaration(ast.id);\r\n if (!declaration) {\r\n throw this.astErrorOutput(`Unable to find declarator`, ast);\r\n }\r\n\r\n if (!declaration.valueType) {\r\n throw this.astErrorOutput(`Unable to find declarator valueType`, ast);\r\n }\r\n\r\n return declaration.valueType;\r\n case 'Identifier':\r\n if (ast.name === 'Infinity') {\r\n return 'Number';\r\n }\r\n if (this.isAstVariable(ast)) {\r\n const signature = this.getVariableSignature(ast);\r\n if (signature === 'value') {\r\n const type = this.getVariableType(ast);\r\n if (!type) {\r\n throw this.astErrorOutput(`Unable to find identifier valueType`, ast);\r\n }\r\n return type;\r\n }\r\n }\r\n const origin = this.findIdentifierOrigin(ast);\r\n if (origin && origin.init) {\r\n return this.getType(origin.init);\r\n }\r\n return null;\r\n case 'ReturnStatement':\r\n return this.getType(ast.argument);\r\n case 'MemberExpression':\r\n if (this.isAstMathFunction(ast)) {\r\n switch (ast.property.name) {\r\n case 'ceil':\r\n return 'Integer';\r\n case 'floor':\r\n return 'Integer';\r\n case 'round':\r\n return 'Integer';\r\n }\r\n return 'Number';\r\n }\r\n if (this.isAstVariable(ast)) {\r\n const variableSignature = this.getVariableSignature(ast);\r\n switch (variableSignature) {\r\n case 'value[]':\r\n return this.getLookupType(this.getVariableType(ast.object));\r\n case 'value[][]':\r\n return this.getLookupType(this.getVariableType(ast.object.object));\r\n case 'value[][][]':\r\n return this.getLookupType(this.getVariableType(ast.object.object.object));\r\n case 'value[][][][]':\r\n return this.getLookupType(this.getVariableType(ast.object.object.object.object));\r\n case 'value.thread.value':\r\n case 'this.thread.value':\r\n return 'Integer';\r\n case 'this.output.value':\r\n return this.dynamicOutput ? 'Integer' : 'LiteralInteger';\r\n case 'this.constants.value':\r\n return this.getConstantType(ast.property.name);\r\n case 'this.constants.value[]':\r\n return this.getLookupType(this.getConstantType(ast.object.property.name));\r\n case 'this.constants.value[][]':\r\n return this.getLookupType(this.getConstantType(ast.object.object.property.name));\r\n case 'this.constants.value[][][]':\r\n return this.getLookupType(this.getConstantType(ast.object.object.object.property.name));\r\n case 'this.constants.value[][][][]':\r\n return this.getLookupType(this.getConstantType(ast.object.object.object.object.property.name));\r\n case 'fn()[]':\r\n return this.getLookupType(this.getType(ast.object));\r\n case 'fn()[][]':\r\n return this.getLookupType(this.getType(ast.object));\r\n case 'fn()[][][]':\r\n return this.getLookupType(this.getType(ast.object));\r\n case 'value.value':\r\n if (this.isAstMathVariable(ast)) {\r\n return 'Number';\r\n }\r\n switch (ast.property.name) {\r\n case 'r':\r\n return this.getLookupType(this.getVariableType(ast.object));\r\n case 'g':\r\n return this.getLookupType(this.getVariableType(ast.object));\r\n case 'b':\r\n return this.getLookupType(this.getVariableType(ast.object));\r\n case 'a':\r\n return this.getLookupType(this.getVariableType(ast.object));\r\n }\r\n case '[][]':\r\n return 'Number';\r\n }\r\n throw this.astErrorOutput('Unhandled getType MemberExpression', ast);\r\n }\r\n throw this.astErrorOutput('Unhandled getType MemberExpression', ast);\r\n case 'ConditionalExpression':\r\n return this.getType(ast.consequent);\r\n case 'FunctionDeclaration':\r\n case 'FunctionExpression':\r\n const lastReturn = this.findLastReturn(ast.body);\r\n if (lastReturn) {\r\n return this.getType(lastReturn);\r\n }\r\n return null;\r\n case 'IfStatement':\r\n return this.getType(ast.consequent);\r\n default:\r\n throw this.astErrorOutput(`Unhandled getType Type \"${ ast.type }\"`, ast);\r\n }\r\n }\r\n\r\n inferArgumentTypesIfNeeded(functionName, args) {\r\n // ensure arguments are filled in, so when we lookup return type, we already can infer it\r\n for (let i = 0; i < args.length; i++) {\r\n if (!this.needsArgumentType(functionName, i)) continue;\r\n const type = this.getType(args[i]);\r\n if (!type) {\r\n throw this.astErrorOutput(`Unable to infer argument ${i}`, args[i]);\r\n }\r\n this.assignArgumentType(functionName, i, type);\r\n }\r\n }\r\n\r\n isAstMathVariable(ast) {\r\n const mathProperties = [\r\n 'E',\r\n 'PI',\r\n 'SQRT2',\r\n 'SQRT1_2',\r\n 'LN2',\r\n 'LN10',\r\n 'LOG2E',\r\n 'LOG10E',\r\n ];\r\n return ast.type === 'MemberExpression' &&\r\n ast.object && ast.object.type === 'Identifier' &&\r\n ast.object.name === 'Math' &&\r\n ast.property &&\r\n ast.property.type === 'Identifier' &&\r\n mathProperties.indexOf(ast.property.name) > -1;\r\n }\r\n\r\n isAstMathFunction(ast) {\r\n const mathFunctions = [\r\n 'abs',\r\n 'acos',\r\n 'asin',\r\n 'atan',\r\n 'atan2',\r\n 'ceil',\r\n 'cos',\r\n 'exp',\r\n 'floor',\r\n 'log',\r\n 'log2',\r\n 'max',\r\n 'min',\r\n 'pow',\r\n 'random',\r\n 'round',\r\n 'sign',\r\n 'sin',\r\n 'sqrt',\r\n 'tan',\r\n ];\r\n return ast.type === 'CallExpression' &&\r\n ast.callee &&\r\n ast.callee.type === 'MemberExpression' &&\r\n ast.callee.object &&\r\n ast.callee.object.type === 'Identifier' &&\r\n ast.callee.object.name === 'Math' &&\r\n ast.callee.property &&\r\n ast.callee.property.type === 'Identifier' &&\r\n mathFunctions.indexOf(ast.callee.property.name) > -1;\r\n }\r\n\r\n isAstVariable(ast) {\r\n return ast.type === 'Identifier' || ast.type === 'MemberExpression';\r\n }\r\n\r\n isSafe(ast) {\r\n return this.isSafeDependencies(this.getDependencies(ast));\r\n }\r\n\r\n isSafeDependencies(dependencies) {\r\n return dependencies && dependencies.every ? dependencies.every(dependency => dependency.isSafe) : true;\r\n }\r\n\r\n /**\r\n *\r\n * @param ast\r\n * @param dependencies\r\n * @param isNotSafe\r\n * @return {Array}\r\n */\r\n getDependencies(ast, dependencies, isNotSafe) {\r\n if (!dependencies) {\r\n dependencies = [];\r\n }\r\n if (!ast) return null;\r\n if (Array.isArray(ast)) {\r\n for (let i = 0; i < ast.length; i++) {\r\n this.getDependencies(ast[i], dependencies, isNotSafe);\r\n }\r\n return dependencies;\r\n }\r\n switch (ast.type) {\r\n case 'AssignmentExpression':\r\n this.getDependencies(ast.left, dependencies, isNotSafe);\r\n this.getDependencies(ast.right, dependencies, isNotSafe);\r\n return dependencies;\r\n case 'ConditionalExpression':\r\n this.getDependencies(ast.test, dependencies, isNotSafe);\r\n this.getDependencies(ast.alternate, dependencies, isNotSafe);\r\n this.getDependencies(ast.consequent, dependencies, isNotSafe);\r\n return dependencies;\r\n case 'Literal':\r\n dependencies.push({\r\n origin: 'literal',\r\n value: ast.value,\r\n isSafe: isNotSafe === true ? false : ast.value > -Infinity && ast.value < Infinity && !isNaN(ast.value)\r\n });\r\n break;\r\n case 'VariableDeclarator':\r\n return this.getDependencies(ast.init, dependencies, isNotSafe);\r\n case 'Identifier':\r\n const declaration = this.getDeclaration(ast);\r\n if (declaration) {\r\n dependencies.push({\r\n name: ast.name,\r\n origin: 'declaration',\r\n isSafe: isNotSafe ? false : this.isSafeDependencies(declaration.dependencies),\r\n });\r\n } else if (this.argumentNames.indexOf(ast.name) > -1) {\r\n dependencies.push({\r\n name: ast.name,\r\n origin: 'argument',\r\n isSafe: false,\r\n });\r\n } else if (this.strictTypingChecking) {\r\n throw new Error(`Cannot find identifier origin \"${ast.name}\"`);\r\n }\r\n break;\r\n case 'FunctionDeclaration':\r\n return this.getDependencies(ast.body.body[ast.body.body.length - 1], dependencies, isNotSafe);\r\n case 'ReturnStatement':\r\n return this.getDependencies(ast.argument, dependencies);\r\n case 'BinaryExpression':\r\n isNotSafe = (ast.operator === '/' || ast.operator === '*');\r\n this.getDependencies(ast.left, dependencies, isNotSafe);\r\n this.getDependencies(ast.right, dependencies, isNotSafe);\r\n return dependencies;\r\n case 'UnaryExpression':\r\n case 'UpdateExpression':\r\n return this.getDependencies(ast.argument, dependencies, isNotSafe);\r\n case 'VariableDeclaration':\r\n return this.getDependencies(ast.declarations, dependencies, isNotSafe);\r\n case 'ArrayExpression':\r\n dependencies.push({\r\n origin: 'declaration',\r\n isSafe: true,\r\n });\r\n return dependencies;\r\n case 'CallExpression':\r\n dependencies.push({\r\n origin: 'function',\r\n isSafe: true,\r\n });\r\n return dependencies;\r\n case 'MemberExpression':\r\n const details = this.getMemberExpressionDetails(ast);\r\n switch (details.signature) {\r\n case 'value[]':\r\n this.getDependencies(ast.object, dependencies, isNotSafe);\r\n break;\r\n case 'value[][]':\r\n this.getDependencies(ast.object.object, dependencies, isNotSafe);\r\n break;\r\n case 'value[][][]':\r\n this.getDependencies(ast.object.object.object, dependencies, isNotSafe);\r\n break;\r\n case 'this.output.value':\r\n if (this.dynamicOutput) {\r\n dependencies.push({\r\n name: details.name,\r\n origin: 'output',\r\n isSafe: false,\r\n });\r\n }\r\n break;\r\n }\r\n if (details) {\r\n if (details.property) {\r\n this.getDependencies(details.property, dependencies, isNotSafe);\r\n }\r\n if (details.xProperty) {\r\n this.getDependencies(details.xProperty, dependencies, isNotSafe);\r\n }\r\n if (details.yProperty) {\r\n this.getDependencies(details.yProperty, dependencies, isNotSafe);\r\n }\r\n if (details.zProperty) {\r\n this.getDependencies(details.zProperty, dependencies, isNotSafe);\r\n }\r\n return dependencies;\r\n }\r\n default:\r\n throw this.astErrorOutput(`Unhandled type ${ ast.type } in getDependencies`, ast);\r\n }\r\n return dependencies;\r\n }\r\n\r\n getVariableSignature(ast) {\r\n if (!this.isAstVariable(ast)) {\r\n throw new Error(`ast of type \"${ ast.type }\" is not a variable signature`);\r\n }\r\n if (ast.type === 'Identifier') {\r\n return 'value';\r\n }\r\n const signature = [];\r\n while (true) {\r\n if (!ast) break;\r\n if (ast.computed) {\r\n signature.push('[]');\r\n } else if (ast.type === 'ThisExpression') {\r\n signature.unshift('this');\r\n } else if (ast.property && ast.property.name) {\r\n if (\r\n ast.property.name === 'x' ||\r\n ast.property.name === 'y' ||\r\n ast.property.name === 'z'\r\n ) {\r\n signature.unshift('.value');\r\n } else if (\r\n ast.property.name === 'constants' ||\r\n ast.property.name === 'thread' ||\r\n ast.property.name === 'output'\r\n ) {\r\n signature.unshift('.' + ast.property.name);\r\n } else {\r\n signature.unshift('.value');\r\n }\r\n } else if (ast.name) {\r\n signature.unshift('value');\r\n } else if (ast.callee && ast.callee.name) {\r\n signature.unshift('fn()');\r\n } else if (ast.elements) {\r\n signature.unshift('[]');\r\n } else {\r\n signature.unshift('unknown');\r\n }\r\n ast = ast.object;\r\n }\r\n\r\n const signatureString = signature.join('');\r\n const allowedExpressions = [\r\n 'value',\r\n 'value[]',\r\n 'value[][]',\r\n 'value[][][]',\r\n 'value[][][][]',\r\n 'value.value',\r\n 'value.thread.value',\r\n 'this.thread.value',\r\n 'this.output.value',\r\n 'this.constants.value',\r\n 'this.constants.value[]',\r\n 'this.constants.value[][]',\r\n 'this.constants.value[][][]',\r\n 'this.constants.value[][][][]',\r\n 'fn()[]',\r\n 'fn()[][]',\r\n 'fn()[][][]',\r\n '[][]',\r\n ];\r\n if (allowedExpressions.indexOf(signatureString) > -1) {\r\n return signatureString;\r\n }\r\n return null;\r\n }\r\n\r\n build() {\r\n return this.toString().length > 0;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for generically to its respective function\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed string array\r\n */\r\n astGeneric(ast, retArr) {\r\n if (ast === null) {\r\n throw this.astErrorOutput('NULL ast', ast);\r\n } else {\r\n if (Array.isArray(ast)) {\r\n for (let i = 0; i < ast.length; i++) {\r\n this.astGeneric(ast[i], retArr);\r\n }\r\n return retArr;\r\n }\r\n\r\n switch (ast.type) {\r\n case 'FunctionDeclaration':\r\n return this.astFunctionDeclaration(ast, retArr);\r\n case 'FunctionExpression':\r\n return this.astFunctionExpression(ast, retArr);\r\n case 'ReturnStatement':\r\n return this.astReturnStatement(ast, retArr);\r\n case 'Literal':\r\n return this.astLiteral(ast, retArr);\r\n case 'BinaryExpression':\r\n return this.astBinaryExpression(ast, retArr);\r\n case 'Identifier':\r\n return this.astIdentifierExpression(ast, retArr);\r\n case 'AssignmentExpression':\r\n return this.astAssignmentExpression(ast, retArr);\r\n case 'ExpressionStatement':\r\n return this.astExpressionStatement(ast, retArr);\r\n case 'EmptyStatement':\r\n return this.astEmptyStatement(ast, retArr);\r\n case 'BlockStatement':\r\n return this.astBlockStatement(ast, retArr);\r\n case 'IfStatement':\r\n return this.astIfStatement(ast, retArr);\r\n case 'SwitchStatement':\r\n return this.astSwitchStatement(ast, retArr);\r\n case 'BreakStatement':\r\n return this.astBreakStatement(ast, retArr);\r\n case 'ContinueStatement':\r\n return this.astContinueStatement(ast, retArr);\r\n case 'ForStatement':\r\n return this.astForStatement(ast, retArr);\r\n case 'WhileStatement':\r\n return this.astWhileStatement(ast, retArr);\r\n case 'DoWhileStatement':\r\n return this.astDoWhileStatement(ast, retArr);\r\n case 'VariableDeclaration':\r\n return this.astVariableDeclaration(ast, retArr);\r\n case 'VariableDeclarator':\r\n return this.astVariableDeclarator(ast, retArr);\r\n case 'ThisExpression':\r\n return this.astThisExpression(ast, retArr);\r\n case 'SequenceExpression':\r\n return this.astSequenceExpression(ast, retArr);\r\n case 'UnaryExpression':\r\n return this.astUnaryExpression(ast, retArr);\r\n case 'UpdateExpression':\r\n return this.astUpdateExpression(ast, retArr);\r\n case 'LogicalExpression':\r\n return this.astLogicalExpression(ast, retArr);\r\n case 'MemberExpression':\r\n return this.astMemberExpression(ast, retArr);\r\n case 'CallExpression':\r\n return this.astCallExpression(ast, retArr);\r\n case 'ArrayExpression':\r\n return this.astArrayExpression(ast, retArr);\r\n case 'DebuggerStatement':\r\n return this.astDebuggerStatement(ast, retArr);\r\n case 'ConditionalExpression':\r\n return this.astConditionalExpression(ast, retArr);\r\n }\r\n\r\n throw this.astErrorOutput('Unknown ast type : ' + ast.type, ast);\r\n }\r\n }\r\n /**\r\n * @desc To throw the AST error, with its location.\r\n * @param {string} error - the error message output\r\n * @param {Object} ast - the AST object where the error is\r\n */\r\n astErrorOutput(error, ast) {\r\n if (typeof this.source !== 'string') {\r\n return new Error(error);\r\n }\r\n\r\n const debugString = getAstString(this.source, ast);\r\n const leadingSource = this.source.substr(ast.start);\r\n const splitLines = leadingSource.split(/\\n/);\r\n const lineBefore = splitLines.length > 0 ? splitLines[splitLines.length - 1] : 0;\r\n return new Error(`${error} on line ${ splitLines.length }, position ${ lineBefore.length }:\\n ${ debugString }`);\r\n }\r\n\r\n astDebuggerStatement(arrNode, retArr) {\r\n return retArr;\r\n }\r\n\r\n astConditionalExpression(ast, retArr) {\r\n if (ast.type !== 'ConditionalExpression') {\r\n throw this.astErrorOutput('Not a conditional expression', ast);\r\n }\r\n retArr.push('(');\r\n this.astGeneric(ast.test, retArr);\r\n retArr.push('?');\r\n this.astGeneric(ast.consequent, retArr);\r\n retArr.push(':');\r\n this.astGeneric(ast.alternate, retArr);\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @abstract\r\n * @param {Object} ast\r\n * @param {String[]} retArr\r\n * @returns {String[]}\r\n */\r\n astFunction(ast, retArr) {\r\n throw new Error(`\"astFunction\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for to its *named function declaration*\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astFunctionDeclaration(ast, retArr) {\r\n if (this.isChildFunction(ast)) {\r\n return retArr;\r\n }\r\n return this.astFunction(ast, retArr);\r\n }\r\n astFunctionExpression(ast, retArr) {\r\n if (this.isChildFunction(ast)) {\r\n return retArr;\r\n }\r\n return this.astFunction(ast, retArr);\r\n }\r\n isChildFunction(ast) {\r\n for (let i = 0; i < this.functions.length; i++) {\r\n if (this.functions[i] === ast) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n astReturnStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n astLiteral(ast, retArr) {\r\n this.literalTypes[`${ast.start},${ast.end}`] = 'Number';\r\n return retArr;\r\n }\r\n astBinaryExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n astIdentifierExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n astAssignmentExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *generic expression* statement\r\n * @param {Object} esNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astExpressionStatement(esNode, retArr) {\r\n this.astGeneric(esNode.expression, retArr);\r\n retArr.push(';');\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for an *Empty* Statement\r\n * @param {Object} eNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astEmptyStatement(eNode, retArr) {\r\n return retArr;\r\n }\r\n astBlockStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n astIfStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n astSwitchStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Break* Statement\r\n * @param {Object} brNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astBreakStatement(brNode, retArr) {\r\n retArr.push('break;');\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Continue* Statement\r\n * @param {Object} crNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astContinueStatement(crNode, retArr) {\r\n retArr.push('continue;\\n');\r\n return retArr;\r\n }\r\n astForStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n astWhileStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n astDoWhileStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Variable Declaration*\r\n * @param {Object} varDecNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astVariableDeclaration(varDecNode, retArr) {\r\n const declarations = varDecNode.declarations;\r\n if (!declarations || !declarations[0] || !declarations[0].init) {\r\n throw this.astErrorOutput('Unexpected expression', varDecNode);\r\n }\r\n const result = [];\r\n const firstDeclaration = declarations[0];\r\n const init = firstDeclaration.init;\r\n let type = this.isState('in-for-loop-init') ? 'Integer' : this.getType(init);\r\n if (type === 'LiteralInteger') {\r\n // We had the choice to go either float or int, choosing float\r\n type = 'Number';\r\n }\r\n const markupType = typeMap[type];\r\n if (!markupType) {\r\n throw this.astErrorOutput(`Markup type ${ markupType } not handled`, varDecNode);\r\n }\r\n let dependencies = this.getDependencies(firstDeclaration.init);\r\n throw new Error('remove me');\r\n this.declarations[firstDeclaration.id.name] = Object.freeze({\r\n type,\r\n dependencies,\r\n isSafe: dependencies.every(dependency => dependency.isSafe)\r\n });\r\n const initResult = [`${type} user_${firstDeclaration.id.name}=`];\r\n this.astGeneric(init, initResult);\r\n result.push(initResult.join(''));\r\n\r\n // first declaration is done, now any added ones setup\r\n for (let i = 1; i < declarations.length; i++) {\r\n const declaration = declarations[i];\r\n dependencies = this.getDependencies(declaration);\r\n throw new Error('Remove me');\r\n this.declarations[declaration.id.name] = Object.freeze({\r\n type,\r\n dependencies,\r\n isSafe: false\r\n });\r\n this.astGeneric(declaration, result);\r\n }\r\n\r\n retArr.push(retArr, result.join(','));\r\n retArr.push(';');\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Variable Declarator*\r\n * @param {Object} iVarDecNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astVariableDeclarator(iVarDecNode, retArr) {\r\n this.astGeneric(iVarDecNode.id, retArr);\r\n if (iVarDecNode.init !== null) {\r\n retArr.push('=');\r\n this.astGeneric(iVarDecNode.init, retArr);\r\n }\r\n return retArr;\r\n }\r\n astThisExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n astSequenceExpression(sNode, retArr) {\r\n for (let i = 0; i < sNode.expressions.length; i++) {\r\n if (i > 0) {\r\n retArr.push(',');\r\n }\r\n this.astGeneric(sNode.expressions, retArr);\r\n }\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Unary* Expression\r\n * @param {Object} uNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astUnaryExpression(uNode, retArr) {\r\n const unaryResult = this.checkAndUpconvertBitwiseUnary(uNode, retArr);\r\n if (unaryResult) {\r\n return retArr;\r\n }\r\n\r\n if (uNode.prefix) {\r\n retArr.push(uNode.operator);\r\n this.astGeneric(uNode.argument, retArr);\r\n } else {\r\n this.astGeneric(uNode.argument, retArr);\r\n retArr.push(uNode.operator);\r\n }\r\n\r\n return retArr;\r\n }\r\n\r\n checkAndUpconvertBitwiseUnary(uNode, retArr) {}\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Update* Expression\r\n * @param {Object} uNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astUpdateExpression(uNode, retArr) {\r\n if (uNode.prefix) {\r\n retArr.push(uNode.operator);\r\n this.astGeneric(uNode.argument, retArr);\r\n } else {\r\n this.astGeneric(uNode.argument, retArr);\r\n retArr.push(uNode.operator);\r\n }\r\n\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Logical* Expression\r\n * @param {Object} logNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astLogicalExpression(logNode, retArr) {\r\n retArr.push('(');\r\n this.astGeneric(logNode.left, retArr);\r\n retArr.push(logNode.operator);\r\n this.astGeneric(logNode.right, retArr);\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n astMemberExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n astCallExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n astArrayExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n\r\n /**\r\n *\r\n * @param ast\r\n * @return {IFunctionNodeMemberExpressionDetails}\r\n */\r\n getMemberExpressionDetails(ast) {\r\n if (ast.type !== 'MemberExpression') {\r\n throw this.astErrorOutput(`Expression ${ ast.type } not a MemberExpression`, ast);\r\n }\r\n let name = null;\r\n let type = null;\r\n const variableSignature = this.getVariableSignature(ast);\r\n switch (variableSignature) {\r\n case 'value':\r\n return null;\r\n case 'value.thread.value':\r\n case 'this.thread.value':\r\n case 'this.output.value':\r\n return {\r\n signature: variableSignature,\r\n type: 'Integer',\r\n name: ast.property.name\r\n };\r\n case 'value[]':\r\n if (typeof ast.object.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.name;\r\n return {\r\n name,\r\n origin: 'user',\r\n signature: variableSignature,\r\n type: this.getVariableType(ast.object),\r\n xProperty: ast.property\r\n };\r\n case 'value[][]':\r\n if (typeof ast.object.object.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.object.name;\r\n return {\r\n name,\r\n origin: 'user',\r\n signature: variableSignature,\r\n type: this.getVariableType(ast.object.object),\r\n yProperty: ast.object.property,\r\n xProperty: ast.property,\r\n };\r\n case 'value[][][]':\r\n if (typeof ast.object.object.object.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.object.object.name;\r\n return {\r\n name,\r\n origin: 'user',\r\n signature: variableSignature,\r\n type: this.getVariableType(ast.object.object.object),\r\n zProperty: ast.object.object.property,\r\n yProperty: ast.object.property,\r\n xProperty: ast.property,\r\n };\r\n case 'value[][][][]':\r\n if (typeof ast.object.object.object.object.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.object.object.object.name;\r\n return {\r\n name,\r\n origin: 'user',\r\n signature: variableSignature,\r\n type: this.getVariableType(ast.object.object.object.object),\r\n zProperty: ast.object.object.property,\r\n yProperty: ast.object.property,\r\n xProperty: ast.property,\r\n };\r\n case 'value.value':\r\n if (typeof ast.property.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n if (this.isAstMathVariable(ast)) {\r\n name = ast.property.name;\r\n return {\r\n name,\r\n origin: 'Math',\r\n type: 'Number',\r\n signature: variableSignature,\r\n };\r\n }\r\n switch (ast.property.name) {\r\n case 'r':\r\n case 'g':\r\n case 'b':\r\n case 'a':\r\n name = ast.object.name;\r\n return {\r\n name,\r\n property: ast.property.name,\r\n origin: 'user',\r\n signature: variableSignature,\r\n type: 'Number'\r\n };\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n case 'this.constants.value':\r\n if (typeof ast.property.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.property.name;\r\n type = this.getConstantType(name);\r\n if (!type) {\r\n throw this.astErrorOutput('Constant has no type', ast);\r\n }\r\n return {\r\n name,\r\n type,\r\n origin: 'constants',\r\n signature: variableSignature,\r\n };\r\n case 'this.constants.value[]':\r\n if (typeof ast.object.property.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.property.name;\r\n type = this.getConstantType(name);\r\n if (!type) {\r\n throw this.astErrorOutput('Constant has no type', ast);\r\n }\r\n return {\r\n name,\r\n type,\r\n origin: 'constants',\r\n signature: variableSignature,\r\n xProperty: ast.property,\r\n };\r\n case 'this.constants.value[][]': {\r\n if (typeof ast.object.object.property.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.object.property.name;\r\n type = this.getConstantType(name);\r\n if (!type) {\r\n throw this.astErrorOutput('Constant has no type', ast);\r\n }\r\n return {\r\n name,\r\n type,\r\n origin: 'constants',\r\n signature: variableSignature,\r\n yProperty: ast.object.property,\r\n xProperty: ast.property,\r\n };\r\n }\r\n case 'this.constants.value[][][]': {\r\n if (typeof ast.object.object.object.property.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.object.object.property.name;\r\n type = this.getConstantType(name);\r\n if (!type) {\r\n throw this.astErrorOutput('Constant has no type', ast);\r\n }\r\n return {\r\n name,\r\n type,\r\n origin: 'constants',\r\n signature: variableSignature,\r\n zProperty: ast.object.object.property,\r\n yProperty: ast.object.property,\r\n xProperty: ast.property,\r\n };\r\n }\r\n case 'fn()[]':\r\n case '[][]':\r\n return {\r\n signature: variableSignature,\r\n property: ast.property,\r\n };\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n }\r\n\r\n findIdentifierOrigin(astToFind) {\r\n const stack = [this.ast];\r\n\r\n while (stack.length > 0) {\r\n const atNode = stack[0];\r\n if (atNode.type === 'VariableDeclarator' && atNode.id && atNode.id.name && atNode.id.name === astToFind.name) {\r\n return atNode;\r\n }\r\n stack.shift();\r\n if (atNode.argument) {\r\n stack.push(atNode.argument);\r\n } else if (atNode.body) {\r\n stack.push(atNode.body);\r\n } else if (atNode.declarations) {\r\n stack.push(atNode.declarations);\r\n } else if (Array.isArray(atNode)) {\r\n for (let i = 0; i < atNode.length; i++) {\r\n stack.push(atNode[i]);\r\n }\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n findLastReturn(ast) {\r\n const stack = [ast || this.ast];\r\n\r\n while (stack.length > 0) {\r\n const atNode = stack.pop();\r\n if (atNode.type === 'ReturnStatement') {\r\n return atNode;\r\n }\r\n if (atNode.type === 'FunctionDeclaration') {\r\n continue;\r\n }\r\n if (atNode.argument) {\r\n stack.push(atNode.argument);\r\n } else if (atNode.body) {\r\n stack.push(atNode.body);\r\n } else if (atNode.declarations) {\r\n stack.push(atNode.declarations);\r\n } else if (Array.isArray(atNode)) {\r\n for (let i = 0; i < atNode.length; i++) {\r\n stack.push(atNode[i]);\r\n }\r\n } else if (atNode.consequent) {\r\n stack.push(atNode.consequent);\r\n } else if (atNode.cases) {\r\n stack.push(atNode.cases);\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n getInternalVariableName(name) {\r\n if (!this._internalVariableNames.hasOwnProperty(name)) {\r\n this._internalVariableNames[name] = 0;\r\n }\r\n this._internalVariableNames[name]++;\r\n if (this._internalVariableNames[name] === 1) {\r\n return name;\r\n }\r\n return name + this._internalVariableNames[name];\r\n }\r\n\r\n varWarn() {\r\n console.warn('var declarations are deprecated, weird things happen when falling back to CPU because var scope differs in javascript than in most languages. Use const or let');\r\n }\r\n}\r\n\r\nconst typeLookupMap = {\r\n 'Number': 'Number',\r\n 'Float': 'Float',\r\n 'Integer': 'Integer',\r\n 'Array': 'Number',\r\n 'Array(2)': 'Number',\r\n 'Array(3)': 'Number',\r\n 'Array(4)': 'Number',\r\n 'Array2D': 'Number',\r\n 'Array3D': 'Number',\r\n 'Input': 'Number',\r\n 'HTMLImage': 'Array(4)',\r\n 'HTMLVideo': 'Array(4)',\r\n 'HTMLImageArray': 'Array(4)',\r\n 'NumberTexture': 'Number',\r\n 'MemoryOptimizedNumberTexture': 'Number',\r\n 'Array1D(2)': 'Array(2)',\r\n 'Array1D(3)': 'Array(3)',\r\n 'Array1D(4)': 'Array(4)',\r\n 'Array2D(2)': 'Array(2)',\r\n 'Array2D(3)': 'Array(3)',\r\n 'Array2D(4)': 'Array(4)',\r\n 'Array3D(2)': 'Array(2)',\r\n 'Array3D(3)': 'Array(3)',\r\n 'Array3D(4)': 'Array(4)',\r\n 'ArrayTexture(1)': 'Number',\r\n 'ArrayTexture(2)': 'Array(2)',\r\n 'ArrayTexture(3)': 'Array(3)',\r\n 'ArrayTexture(4)': 'Array(4)',\r\n};\r\n","import { FunctionNode } from '../function-node';\r\n\r\n/**\r\n * @desc [INTERNAL] Represents a single function, inside JS\r\n *\r\n *

This handles all the raw state, converted state, etc. Of a single function.

\r\n */\r\nexport class CPUFunctionNode extends FunctionNode {\r\n /**\r\n * @desc Parses the abstract syntax tree for to its *named function*\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astFunction(ast, retArr) {\r\n\r\n // Setup function return type and name\r\n if (!this.isRootKernel) {\r\n retArr.push('function');\r\n retArr.push(' ');\r\n retArr.push(this.name);\r\n retArr.push('(');\r\n\r\n // Arguments handling\r\n for (let i = 0; i < this.argumentNames.length; ++i) {\r\n const argumentName = this.argumentNames[i];\r\n\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n retArr.push('user_');\r\n retArr.push(argumentName);\r\n }\r\n\r\n // Function opening\r\n retArr.push(') {\\n');\r\n }\r\n\r\n // Body statement iteration\r\n for (let i = 0; i < ast.body.body.length; ++i) {\r\n this.astGeneric(ast.body.body[i], retArr);\r\n retArr.push('\\n');\r\n }\r\n\r\n if (!this.isRootKernel) {\r\n // Function closing\r\n retArr.push('}\\n');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for to *return* statement\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astReturnStatement(ast, retArr) {\r\n const type = this.returnType || this.getType(ast.argument);\r\n\r\n if (!this.returnType) {\r\n this.returnType = type;\r\n }\r\n\r\n if (this.isRootKernel) {\r\n retArr.push(this.leadingReturnStatement);\r\n this.astGeneric(ast.argument, retArr);\r\n retArr.push(';\\n');\r\n retArr.push(this.followingReturnStatement);\r\n retArr.push('continue;\\n');\r\n } else if (this.isSubKernel) {\r\n retArr.push(`subKernelResult_${ this.name } = `);\r\n this.astGeneric(ast.argument, retArr);\r\n retArr.push(';');\r\n retArr.push(`return subKernelResult_${ this.name };`);\r\n } else {\r\n retArr.push('return ');\r\n this.astGeneric(ast.argument, retArr);\r\n retArr.push(';');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *literal value*\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astLiteral(ast, retArr) {\r\n\r\n // Reject non numeric literals\r\n if (isNaN(ast.value)) {\r\n throw this.astErrorOutput(\r\n 'Non-numeric literal not supported : ' + ast.value,\r\n ast\r\n );\r\n }\r\n\r\n retArr.push(ast.value);\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *binary* expression\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astBinaryExpression(ast, retArr) {\r\n retArr.push('(');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *identifier* expression\r\n * @param {Object} idtNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astIdentifierExpression(idtNode, retArr) {\r\n if (idtNode.type !== 'Identifier') {\r\n throw this.astErrorOutput(\r\n 'IdentifierExpression - not an Identifier',\r\n idtNode\r\n );\r\n }\r\n\r\n switch (idtNode.name) {\r\n case 'Infinity':\r\n retArr.push('Infinity');\r\n break;\r\n default:\r\n if (this.constants && this.constants.hasOwnProperty(idtNode.name)) {\r\n retArr.push('constants_' + idtNode.name);\r\n } else {\r\n retArr.push('user_' + idtNode.name);\r\n }\r\n }\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *for-loop* expression\r\n * @param {Object} forNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed webgl string\r\n */\r\n astForStatement(forNode, retArr) {\r\n if (forNode.type !== 'ForStatement') {\r\n throw this.astErrorOutput('Invalid for statement', forNode);\r\n }\r\n\r\n const initArr = [];\r\n const testArr = [];\r\n const updateArr = [];\r\n const bodyArr = [];\r\n let isSafe = null;\r\n\r\n if (forNode.init) {\r\n this.pushState('in-for-loop-init');\r\n this.astGeneric(forNode.init, initArr);\r\n for (let i = 0; i < initArr.length; i++) {\r\n if (initArr[i].includes && initArr[i].includes(',')) {\r\n isSafe = false;\r\n }\r\n }\r\n this.popState('in-for-loop-init');\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.test) {\r\n this.astGeneric(forNode.test, testArr);\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.update) {\r\n this.astGeneric(forNode.update, updateArr);\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.body) {\r\n this.pushState('loop-body');\r\n this.astGeneric(forNode.body, bodyArr);\r\n this.popState('loop-body');\r\n }\r\n\r\n // have all parts, now make them safe\r\n if (isSafe === null) {\r\n isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test);\r\n }\r\n\r\n if (isSafe) {\r\n retArr.push(`for (${initArr.join('')};${testArr.join('')};${updateArr.join('')}){\\n`);\r\n retArr.push(bodyArr.join(''));\r\n retArr.push('}\\n');\r\n } else {\r\n const iVariableName = this.getInternalVariableName('safeI');\r\n if (initArr.length > 0) {\r\n retArr.push(initArr.join(''), ';\\n');\r\n }\r\n retArr.push(`for (let ${iVariableName}=0;${iVariableName} 0) {\r\n retArr.push(`if (!${testArr.join('')}) break;\\n`);\r\n }\r\n retArr.push(bodyArr.join(''));\r\n retArr.push(`\\n${updateArr.join('')};`);\r\n retArr.push('}\\n');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *while* loop\r\n * @param {Object} whileNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed javascript string\r\n */\r\n astWhileStatement(whileNode, retArr) {\r\n if (whileNode.type !== 'WhileStatement') {\r\n throw this.astErrorOutput(\r\n 'Invalid while statement',\r\n whileNode\r\n );\r\n }\r\n\r\n retArr.push('for (let i = 0; i < LOOP_MAX; i++) {');\r\n retArr.push('if (');\r\n this.astGeneric(whileNode.test, retArr);\r\n retArr.push(') {\\n');\r\n this.astGeneric(whileNode.body, retArr);\r\n retArr.push('} else {\\n');\r\n retArr.push('break;\\n');\r\n retArr.push('}\\n');\r\n retArr.push('}\\n');\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *do while* loop\r\n * @param {Object} doWhileNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed webgl string\r\n */\r\n astDoWhileStatement(doWhileNode, retArr) {\r\n if (doWhileNode.type !== 'DoWhileStatement') {\r\n throw this.astErrorOutput(\r\n 'Invalid while statement',\r\n doWhileNode\r\n );\r\n }\r\n\r\n retArr.push('for (let i = 0; i < LOOP_MAX; i++) {');\r\n this.astGeneric(doWhileNode.body, retArr);\r\n retArr.push('if (!');\r\n this.astGeneric(doWhileNode.test, retArr);\r\n retArr.push(') {\\n');\r\n retArr.push('break;\\n');\r\n retArr.push('}\\n');\r\n retArr.push('}\\n');\r\n\r\n return retArr;\r\n\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Assignment* Expression\r\n * @param {Object} assNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astAssignmentExpression(assNode, retArr) {\r\n const declaration = this.getDeclaration(assNode.left);\r\n if (declaration && !declaration.assignable) {\r\n throw new this.astErrorOutput(`Variable ${assNode.left.name} is not assignable here`, assNode);\r\n }\r\n this.astGeneric(assNode.left, retArr);\r\n retArr.push(assNode.operator);\r\n this.astGeneric(assNode.right, retArr);\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Block* statement\r\n * @param {Object} bNode - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astBlockStatement(bNode, retArr) {\r\n if (this.isState('loop-body')) {\r\n this.pushState('block-body'); // this prevents recursive removal of braces\r\n for (let i = 0; i < bNode.body.length; i++) {\r\n this.astGeneric(bNode.body[i], retArr);\r\n }\r\n this.popState('block-body');\r\n } else {\r\n retArr.push('{\\n');\r\n for (let i = 0; i < bNode.body.length; i++) {\r\n this.astGeneric(bNode.body[i], retArr);\r\n }\r\n retArr.push('}\\n');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Variable Declaration*\r\n * @param {Object} varDecNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astVariableDeclaration(varDecNode, retArr) {\r\n if (varDecNode.kind === 'var' && this.warnVarUsage) {\r\n this.varWarn();\r\n }\r\n retArr.push(`${varDecNode.kind} `);\r\n const { declarations } = varDecNode;\r\n for (let i = 0; i < declarations.length; i++) {\r\n if (i > 0) {\r\n retArr.push(',');\r\n }\r\n this.astGeneric(declarations[i], retArr);\r\n }\r\n if (!this.isState('in-for-loop-init')) {\r\n retArr.push(';');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *If* Statement\r\n * @param {Object} ifNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astIfStatement(ifNode, retArr) {\r\n retArr.push('if (');\r\n this.astGeneric(ifNode.test, retArr);\r\n retArr.push(')');\r\n if (ifNode.consequent.type === 'BlockStatement') {\r\n this.astGeneric(ifNode.consequent, retArr);\r\n } else {\r\n retArr.push(' {\\n');\r\n this.astGeneric(ifNode.consequent, retArr);\r\n retArr.push('\\n}\\n');\r\n }\r\n\r\n if (ifNode.alternate) {\r\n retArr.push('else ');\r\n if (ifNode.alternate.type === 'BlockStatement') {\r\n this.astGeneric(ifNode.alternate, retArr);\r\n } else {\r\n retArr.push(' {\\n');\r\n this.astGeneric(ifNode.alternate, retArr);\r\n retArr.push('\\n}\\n');\r\n }\r\n }\r\n return retArr;\r\n\r\n }\r\n\r\n astSwitchStatement(ast, retArr) {\r\n const { discriminant, cases } = ast;\r\n retArr.push('switch (');\r\n this.astGeneric(discriminant, retArr);\r\n retArr.push(') {\\n');\r\n for (let i = 0; i < cases.length; i++) {\r\n if (cases[i].test === null) {\r\n retArr.push('default:\\n');\r\n this.astGeneric(cases[i].consequent, retArr);\r\n if (cases[i].consequent && cases[i].consequent.length > 0) {\r\n retArr.push('break;\\n');\r\n }\r\n continue;\r\n }\r\n retArr.push('case ');\r\n this.astGeneric(cases[i].test, retArr);\r\n retArr.push(':\\n');\r\n if (cases[i].consequent && cases[i].consequent.length > 0) {\r\n this.astGeneric(cases[i].consequent, retArr);\r\n retArr.push('break;\\n');\r\n }\r\n }\r\n retArr.push('\\n}');\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *This* expression\r\n * @param {Object} tNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astThisExpression(tNode, retArr) {\r\n retArr.push('_this');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Member* Expression\r\n * @param {Object} mNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astMemberExpression(mNode, retArr) {\r\n const {\r\n signature,\r\n type,\r\n property,\r\n xProperty,\r\n yProperty,\r\n zProperty,\r\n name,\r\n origin\r\n } = this.getMemberExpressionDetails(mNode);\r\n switch (signature) {\r\n case 'this.thread.value':\r\n retArr.push(`_this.thread.${ name }`);\r\n return retArr;\r\n case 'this.output.value':\r\n switch (name) {\r\n case 'x':\r\n retArr.push('outputX');\r\n break;\r\n case 'y':\r\n retArr.push('outputY');\r\n break;\r\n case 'z':\r\n retArr.push('outputZ');\r\n break;\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n }\r\n return retArr;\r\n case 'value':\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n case 'value[]':\r\n case 'value[][]':\r\n case 'value[][][]':\r\n case 'value.value':\r\n if (origin === 'Math') {\r\n retArr.push(Math[name]);\r\n return retArr;\r\n }\r\n switch (property) {\r\n case 'r':\r\n retArr.push(`user_${ name }[0]`);\r\n return retArr;\r\n case 'g':\r\n retArr.push(`user_${ name }[1]`);\r\n return retArr;\r\n case 'b':\r\n retArr.push(`user_${ name }[2]`);\r\n return retArr;\r\n case 'a':\r\n retArr.push(`user_${ name }[3]`);\r\n return retArr;\r\n }\r\n break;\r\n case 'this.constants.value':\r\n case 'this.constants.value[]':\r\n case 'this.constants.value[][]':\r\n case 'this.constants.value[][][]':\r\n break;\r\n case 'fn()[]':\r\n this.astGeneric(mNode.object, retArr);\r\n retArr.push('[');\r\n this.astGeneric(mNode.property, retArr);\r\n retArr.push(']');\r\n return retArr;\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n }\r\n\r\n if (!mNode.computed) {\r\n // handle simple types\r\n switch (type) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n case 'Boolean':\r\n retArr.push(`${origin}_${name}`);\r\n return retArr;\r\n }\r\n }\r\n\r\n // handle more complex types\r\n // argument may have come from a parent\r\n const markupName = `${origin}_${name}`;\r\n\r\n switch (type) {\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n case 'HTMLImageArray':\r\n case 'ArrayTexture(1)':\r\n case 'ArrayTexture(2)':\r\n case 'ArrayTexture(3)':\r\n case 'ArrayTexture(4)':\r\n case 'HTMLImage':\r\n default:\r\n let size;\r\n let isInput;\r\n if (origin === 'constants') {\r\n const constant = this.constants[name];\r\n isInput = this.constantTypes[name] === 'Input';\r\n size = isInput ? constant.size : null;\r\n } else {\r\n isInput = this.isInput(name);\r\n size = isInput ? this.argumentSizes[this.argumentNames.indexOf(name)] : null;\r\n }\r\n retArr.push(`${ markupName }`);\r\n if (zProperty && yProperty) {\r\n if (isInput) {\r\n retArr.push('[(');\r\n this.astGeneric(zProperty, retArr);\r\n retArr.push(`*${ this.dynamicArguments ? '(outputY * outputX)' : size[1] * size[0] })+(`);\r\n this.astGeneric(yProperty, retArr);\r\n retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`);\r\n this.astGeneric(xProperty, retArr);\r\n retArr.push(']');\r\n } else {\r\n retArr.push('[');\r\n this.astGeneric(zProperty, retArr);\r\n retArr.push(']');\r\n retArr.push('[');\r\n this.astGeneric(yProperty, retArr);\r\n retArr.push(']');\r\n retArr.push('[');\r\n this.astGeneric(xProperty, retArr);\r\n retArr.push(']');\r\n }\r\n } else if (yProperty) {\r\n if (isInput) {\r\n retArr.push('[(');\r\n this.astGeneric(yProperty, retArr);\r\n retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`);\r\n this.astGeneric(xProperty, retArr);\r\n retArr.push(']');\r\n } else {\r\n retArr.push('[');\r\n this.astGeneric(yProperty, retArr);\r\n retArr.push(']');\r\n retArr.push('[');\r\n this.astGeneric(xProperty, retArr);\r\n retArr.push(']');\r\n }\r\n } else if (typeof xProperty !== 'undefined') {\r\n retArr.push('[');\r\n this.astGeneric(xProperty, retArr);\r\n retArr.push(']');\r\n }\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *call* expression\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astCallExpression(ast, retArr) {\r\n if (ast.type !== 'CallExpression') {\r\n // Failure, unknown expression\r\n throw this.astErrorOutput('Unknown CallExpression', ast);\r\n }\r\n // Get the full function call, unrolled\r\n let functionName = this.astMemberExpressionUnroll(ast.callee);\r\n\r\n // Register the function into the called registry\r\n if (this.calledFunctions.indexOf(functionName) < 0) {\r\n this.calledFunctions.push(functionName);\r\n }\r\n\r\n const isMathFunction = this.isAstMathFunction(ast);\r\n\r\n // track the function was called\r\n if (this.onFunctionCall) {\r\n this.onFunctionCall(this.name, functionName, ast.arguments);\r\n }\r\n\r\n // Call the function\r\n retArr.push(functionName);\r\n\r\n // Open arguments space\r\n retArr.push('(');\r\n const targetTypes = this.lookupFunctionArgumentTypes(functionName) || [];\r\n // Add the arguments\r\n for (let i = 0; i < ast.arguments.length; ++i) {\r\n const argument = ast.arguments[i];\r\n\r\n // in order to track return type, even though this is CPU\r\n let argumentType = this.getType(argument);\r\n if (!targetTypes[i]) {\r\n this.triggerImplyArgumentType(functionName, i, argumentType, this);\r\n }\r\n\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n this.astGeneric(argument, retArr);\r\n }\r\n // Close arguments space\r\n retArr.push(')');\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Array* Expression\r\n * @param {Object} arrNode - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astArrayExpression(arrNode, retArr) {\r\n const arrLen = arrNode.elements.length;\r\n\r\n retArr.push('new Float32Array([');\r\n for (let i = 0; i < arrLen; ++i) {\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n const subNode = arrNode.elements[i];\r\n this.astGeneric(subNode, retArr)\r\n }\r\n retArr.push('])');\r\n\r\n return retArr;\r\n }\r\n\r\n astDebuggerStatement(arrNode, retArr) {\r\n retArr.push('debugger;');\r\n return retArr;\r\n }\r\n}\r\n","import { utils } from '../../utils'\r\n\r\nfunction constantsToString(constants, types) {\r\n const results = [];\r\n for (const name in types) {\r\n if (!types.hasOwnProperty(name)) continue;\r\n const type = types[name];\r\n const constant = constants[name];\r\n switch (type) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n case 'Boolean':\r\n results.push(`${name}:${constant}`);\r\n break;\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n results.push(`${name}:new ${constant.constructor.name}(${JSON.stringify(Array.from(constant))})`);\r\n break;\r\n }\r\n }\r\n return `{ ${ results.join() } }`;\r\n}\r\n\r\nexport function cpuKernelString(cpuKernel, name) {\r\n const header = [];\r\n const thisProperties = [];\r\n const beforeReturn = [];\r\n\r\n const useFunctionKeyword = !/^function/.test(cpuKernel.color.toString());\r\n\r\n header.push(\r\n ' const { context, canvas, constants: incomingConstants } = settings;',\r\n ` const output = new Int32Array(${JSON.stringify(Array.from(cpuKernel.output))});`,\r\n ` const _constantTypes = ${JSON.stringify(cpuKernel.constantTypes)};`,\r\n ` const _constants = ${constantsToString(cpuKernel.constants, cpuKernel.constantTypes)};`,\r\n );\r\n\r\n thisProperties.push(\r\n ' constants: _constants,',\r\n ' context,',\r\n ' output,',\r\n ' thread: {x: 0, y: 0, z: 0},',\r\n );\r\n\r\n if (cpuKernel.graphical) {\r\n header.push(` const _imageData = context.createImageData(${cpuKernel.output[0]}, ${cpuKernel.output[1]});`);\r\n header.push(` const _colorData = new Uint8ClampedArray(${cpuKernel.output[0]} * ${cpuKernel.output[1]} * 4);`);\r\n\r\n const colorFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.color.toString(), {\r\n thisLookup: (propertyName) => {\r\n switch (propertyName) {\r\n case '_colorData':\r\n return '_colorData';\r\n case '_imageData':\r\n return '_imageData';\r\n case 'output':\r\n return 'output';\r\n case 'thread':\r\n return 'this.thread';\r\n }\r\n return JSON.stringify(cpuKernel[propertyName]);\r\n },\r\n findDependency: (object, name) => {\r\n return null;\r\n }\r\n });\r\n\r\n const getPixelsFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.getPixels.toString(), {\r\n thisLookup: (propertyName) => {\r\n switch (propertyName) {\r\n case '_colorData':\r\n return '_colorData';\r\n case '_imageData':\r\n return '_imageData';\r\n case 'output':\r\n return 'output';\r\n case 'thread':\r\n return 'this.thread';\r\n }\r\n return JSON.stringify(cpuKernel[propertyName]);\r\n },\r\n findDependency: () => {\r\n return null;\r\n }\r\n });\r\n\r\n thisProperties.push(\r\n ' _imageData,',\r\n ' _colorData,',\r\n ` color: ${colorFn},`,\r\n );\r\n\r\n beforeReturn.push(\r\n ` kernel.getPixels = ${getPixelsFn};`\r\n );\r\n }\r\n\r\n const constantTypes = [];\r\n const constantKeys = Object.keys(cpuKernel.constantTypes);\r\n for (let i = 0; i < constantKeys.length; i++) {\r\n constantTypes.push(cpuKernel.constantTypes[constantKeys]);\r\n }\r\n if (cpuKernel.argumentTypes.indexOf('HTMLImageArray') !== -1 || constantTypes.indexOf('HTMLImageArray') !== -1) {\r\n const flattenedImageTo3DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._imageTo3DArray.toString(), {\r\n doNotDefine: ['canvas'],\r\n findDependency: (object, name) => {\r\n if (object === 'this') {\r\n return (useFunctionKeyword ? 'function ' : '') + cpuKernel[name].toString();\r\n }\r\n return null;\r\n },\r\n thisLookup: (propertyName) => {\r\n switch (propertyName) {\r\n case 'canvas':\r\n return;\r\n case 'context':\r\n return 'context';\r\n }\r\n }\r\n });\r\n beforeReturn.push(flattenedImageTo3DArray);\r\n thisProperties.push(` _mediaTo2DArray,`);\r\n thisProperties.push(` _imageTo3DArray,`);\r\n } else if (cpuKernel.argumentTypes.indexOf('HTMLImage') !== -1 || constantTypes.indexOf('HTMLImage') !== -1) {\r\n const flattenedImageTo2DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._mediaTo2DArray.toString(), {\r\n findDependency: (object, name) => {\r\n return null;\r\n },\r\n thisLookup: (propertyName) => {\r\n switch (propertyName) {\r\n case 'canvas':\r\n return 'settings.canvas';\r\n case 'context':\r\n return 'settings.context';\r\n }\r\n throw new Error('unhandled thisLookup');\r\n }\r\n });\r\n beforeReturn.push(flattenedImageTo2DArray);\r\n thisProperties.push(` _mediaTo2DArray,`);\r\n }\r\n\r\n return `function(settings) {\r\n${ header.join('\\n') }\r\n for (const p in _constantTypes) {\r\n if (!_constantTypes.hasOwnProperty(p)) continue;\r\n const type = _constantTypes[p];\r\n switch (type) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n case 'Boolean':\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n if (incomingConstants.hasOwnProperty(p)) {\r\n console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned');\r\n }\r\n continue;\r\n }\r\n if (!incomingConstants.hasOwnProperty(p)) {\r\n throw new Error('constant ' + p + ' not found');\r\n }\r\n _constants[p] = incomingConstants[p];\r\n }\r\n const kernel = (function() {\r\n${cpuKernel._kernelString}\r\n })\r\n .apply({ ${thisProperties.join('\\n')} });\r\n ${ beforeReturn.join('\\n') }\r\n return kernel;\r\n}`;\r\n}\r\n","import { Kernel } from '../kernel';\r\nimport { FunctionBuilder } from '../function-builder';\r\nimport { CPUFunctionNode } from './function-node';\r\nimport { utils } from '../../utils';\r\nimport { cpuKernelString } from './kernel-string';\r\n\r\n/**\r\n * @desc Kernel Implementation for CPU.\r\n *

Instantiates properties to the CPU Kernel.

\r\n */\r\nexport class CPUKernel extends Kernel {\r\n static getFeatures() {\r\n return this.features;\r\n }\r\n static get features() {\r\n return Object.freeze({\r\n kernelMap: true,\r\n isIntegerDivisionAccurate: true\r\n });\r\n }\r\n static get isSupported() {\r\n return true;\r\n }\r\n static isContextMatch(context) {\r\n return false;\r\n }\r\n /**\r\n * @desc The current mode in which gpu.js is executing.\r\n */\r\n static get mode() {\r\n return 'cpu';\r\n }\r\n\r\n static nativeFunctionArguments() {\r\n return null;\r\n }\r\n\r\n static nativeFunctionReturnType() {\r\n return null;\r\n }\r\n\r\n static combineKernels(combinedKernel) {\r\n return combinedKernel;\r\n }\r\n\r\n constructor(source, settings) {\r\n super(source, settings);\r\n this.mergeSettings(source.settings || settings);\r\n\r\n this._imageData = null;\r\n this._colorData = null;\r\n this._kernelString = null;\r\n this.thread = {\r\n x: 0,\r\n y: 0,\r\n z: 0\r\n };\r\n this.translatedSources = null;\r\n }\r\n\r\n initCanvas() {\r\n if (typeof document !== 'undefined') {\r\n return document.createElement('canvas');\r\n } else if (typeof OffscreenCanvas !== 'undefined') {\r\n return new OffscreenCanvas(0, 0);\r\n }\r\n }\r\n\r\n initContext() {\r\n if (!this.canvas) return null;\r\n return this.canvas.getContext('2d');\r\n }\r\n\r\n initPlugins(settings) {\r\n return [];\r\n }\r\n\r\n /**\r\n * @desc Validate settings related to Kernel, such as dimensions size, and auto output support.\r\n * @param {IArguments} args\r\n */\r\n validateSettings(args) {\r\n if (!this.output || this.output.length === 0) {\r\n if (args.length !== 1) {\r\n throw new Error('Auto output only supported for kernels with only one input');\r\n }\r\n\r\n const argType = utils.getVariableType(args[0], this.strictIntegers);\r\n if (argType === 'Array') {\r\n this.output = utils.getDimensions(argType);\r\n } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') {\r\n this.output = args[0].output;\r\n } else {\r\n throw new Error('Auto output not supported for input type: ' + argType);\r\n }\r\n }\r\n\r\n if (this.graphical) {\r\n if (this.output.length !== 2) {\r\n throw new Error('Output must have 2 dimensions on graphical mode');\r\n }\r\n }\r\n\r\n this.checkOutput();\r\n }\r\n\r\n translateSource() {\r\n this.leadingReturnStatement = this.output.length > 1 ? 'resultX[x] = ' : 'result[x] = ';\r\n if (this.subKernels) {\r\n const followingReturnStatement = []\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const {\r\n name\r\n } = this.subKernels[i];\r\n followingReturnStatement.push(this.output.length > 1 ? `resultX_${ name }[x] = subKernelResult_${ name };\\n` : `result_${ name }[x] = subKernelResult_${ name };\\n`);\r\n }\r\n this.followingReturnStatement = followingReturnStatement.join('');\r\n }\r\n const functionBuilder = FunctionBuilder.fromKernel(this, CPUFunctionNode);\r\n this.translatedSources = functionBuilder.getPrototypes('kernel');\r\n if (!this.graphical && !this.returnType) {\r\n this.returnType = functionBuilder.getKernelResultType();\r\n }\r\n }\r\n\r\n /**\r\n * @desc Builds the Kernel, by generating the kernel\r\n * string using thread dimensions, and arguments\r\n * supplied to the kernel.\r\n *\r\n *

If the graphical flag is enabled, canvas is used.

\r\n */\r\n build() {\r\n this.setupConstants();\r\n this.setupArguments(arguments);\r\n this.validateSettings(arguments);\r\n this.translateSource();\r\n\r\n if (this.graphical) {\r\n const {\r\n canvas,\r\n output\r\n } = this;\r\n if (!canvas) {\r\n throw new Error('no canvas available for using graphical output');\r\n }\r\n const width = output[0];\r\n const height = output[1] || 1;\r\n canvas.width = width;\r\n canvas.height = height;\r\n this._imageData = this.context.createImageData(width, height);\r\n this._colorData = new Uint8ClampedArray(width * height * 4);\r\n }\r\n\r\n const kernelString = this.getKernelString();\r\n this.kernelString = kernelString;\r\n\r\n if (this.debug) {\r\n console.log('Function output:');\r\n console.log(kernelString);\r\n }\r\n\r\n try {\r\n this.run = new Function([], kernelString).bind(this)();\r\n } catch (e) {\r\n console.error('An error occurred compiling the javascript: ', e);\r\n }\r\n }\r\n\r\n color(r, g, b, a) {\r\n if (typeof a === 'undefined') {\r\n a = 1;\r\n }\r\n\r\n r = Math.floor(r * 255);\r\n g = Math.floor(g * 255);\r\n b = Math.floor(b * 255);\r\n a = Math.floor(a * 255);\r\n\r\n const width = this.output[0];\r\n const height = this.output[1];\r\n\r\n const x = this.thread.x;\r\n const y = height - this.thread.y - 1;\r\n\r\n const index = x + y * width;\r\n\r\n this._colorData[index * 4 + 0] = r;\r\n this._colorData[index * 4 + 1] = g;\r\n this._colorData[index * 4 + 2] = b;\r\n this._colorData[index * 4 + 3] = a;\r\n }\r\n\r\n /**\r\n * @desc Generates kernel string for this kernel program.\r\n *\r\n *

If sub-kernels are supplied, they are also factored in.\r\n * This string can be saved by calling the `toString` method\r\n * and then can be reused later.

\r\n *\r\n * @returns {String} result\r\n *\r\n */\r\n getKernelString() {\r\n if (this._kernelString !== null) return this._kernelString;\r\n\r\n let kernelThreadString = null;\r\n let {\r\n translatedSources\r\n } = this;\r\n if (translatedSources.length > 1) {\r\n translatedSources = translatedSources.filter(fn => {\r\n if (/^function/.test(fn)) return fn;\r\n kernelThreadString = fn;\r\n return false;\r\n })\r\n } else {\r\n kernelThreadString = translatedSources.shift();\r\n }\r\n return this._kernelString = ` const LOOP_MAX = ${ this._getLoopMaxString() };\r\n ${ this.injectedNative || '' }\r\n const _this = this;\r\n ${ this._processConstants() }\r\n return (${ this.argumentNames.map(argumentName => 'user_' + argumentName).join(', ') }) => {\r\n ${ this._processArguments() }\r\n ${ this.graphical ? this._graphicalKernelBody(kernelThreadString) : this._resultKernelBody(kernelThreadString) }\r\n ${ translatedSources.length > 0 ? translatedSources.join('\\n') : '' }\r\n };`;\r\n }\r\n\r\n /**\r\n * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused.\r\n */\r\n toString() {\r\n return cpuKernelString(this);\r\n }\r\n\r\n /**\r\n * @desc Get the maximum loop size String.\r\n * @returns {String} result\r\n */\r\n _getLoopMaxString() {\r\n return (\r\n this.loopMaxIterations ?\r\n ` ${ parseInt(this.loopMaxIterations) };` :\r\n ' 1000;'\r\n );\r\n }\r\n\r\n _processConstants() {\r\n if (!this.constants) return '';\r\n\r\n const result = [];\r\n for (let p in this.constants) {\r\n const type = this.constantTypes[p];\r\n switch (type) {\r\n case 'HTMLImage':\r\n case 'HTMLVideo':\r\n result.push(` const constants_${p} = this._mediaTo2DArray(this.constants.${p});\\n`);\r\n break;\r\n case 'HTMLImageArray':\r\n result.push(` const constants_${p} = this._imageTo3DArray(this.constants.${p});\\n`);\r\n break;\r\n case 'Input':\r\n result.push(` const constants_${p} = this.constants.${p}.value;\\n`);\r\n break;\r\n default:\r\n result.push(` const constants_${p} = this.constants.${p};\\n`);\r\n }\r\n }\r\n return result.join('');\r\n }\r\n\r\n _processArguments() {\r\n const result = [];\r\n for (let i = 0; i < this.argumentTypes.length; i++) {\r\n const variableName = `user_${this.argumentNames[i]}`;\r\n switch (this.argumentTypes[i]) {\r\n case 'HTMLImage':\r\n case 'HTMLVideo':\r\n result.push(` ${variableName} = this._mediaTo2DArray(${variableName});\\n`);\r\n break;\r\n case 'HTMLImageArray':\r\n result.push(` ${variableName} = this._imageTo3DArray(${variableName});\\n`);\r\n break;\r\n case 'Input':\r\n result.push(` ${variableName} = ${variableName}.value;\\n`);\r\n break;\r\n case 'ArrayTexture(1)':\r\n case 'ArrayTexture(2)':\r\n case 'ArrayTexture(3)':\r\n case 'ArrayTexture(4)':\r\n case 'NumberTexture':\r\n case 'MemoryOptimizedNumberTexture':\r\n result.push(`\r\n if (${variableName}.toArray) {\r\n if (!_this.textureCache) {\r\n _this.textureCache = [];\r\n _this.arrayCache = [];\r\n }\r\n const textureIndex = _this.textureCache.indexOf(${variableName});\r\n if (textureIndex !== -1) {\r\n ${variableName} = _this.arrayCache[textureIndex];\r\n } else {\r\n _this.textureCache.push(${variableName});\r\n ${variableName} = ${variableName}.toArray();\r\n _this.arrayCache.push(${variableName});\r\n }\r\n }`);\r\n break;\r\n }\r\n }\r\n return result.join('');\r\n }\r\n\r\n _mediaTo2DArray(media) {\r\n const canvas = this.canvas;\r\n const width = media.width > 0 ? media.width : media.videoWidth;\r\n const height = media.height > 0 ? media.height : media.videoHeight;\r\n if (canvas.width < width) {\r\n canvas.width = width;\r\n }\r\n if (canvas.height < height) {\r\n canvas.height = height;\r\n }\r\n const ctx = this.context;\r\n ctx.drawImage(media, 0, 0, width, height);\r\n const pixelsData = ctx.getImageData(0, 0, width, height).data;\r\n const imageArray = new Array(height);\r\n let index = 0;\r\n for (let y = height - 1; y >= 0; y--) {\r\n const row = imageArray[y] = new Array(width);\r\n for (let x = 0; x < width; x++) {\r\n const pixel = new Float32Array(4);\r\n pixel[0] = pixelsData[index++] / 255; // r\r\n pixel[1] = pixelsData[index++] / 255; // g\r\n pixel[2] = pixelsData[index++] / 255; // b\r\n pixel[3] = pixelsData[index++] / 255; // a\r\n row[x] = pixel;\r\n }\r\n }\r\n return imageArray;\r\n }\r\n\r\n getPixels(flip) {\r\n const [width, height] = this.output;\r\n // cpu is not flipped by default\r\n return flip ? utils.flipPixels(this._imageData.data, width, height) : this._imageData.data.slice(0);\r\n }\r\n\r\n _imageTo3DArray(images) {\r\n const imagesArray = new Array(images.length);\r\n for (let i = 0; i < images.length; i++) {\r\n imagesArray[i] = this._mediaTo2DArray(images[i]);\r\n }\r\n return imagesArray;\r\n }\r\n\r\n _resultKernelBody(kernelString) {\r\n switch (this.output.length) {\r\n case 1:\r\n return this._resultKernel1DLoop(kernelString) + this._kernelOutput();\r\n case 2:\r\n return this._resultKernel2DLoop(kernelString) + this._kernelOutput();\r\n case 3:\r\n return this._resultKernel3DLoop(kernelString) + this._kernelOutput();\r\n default:\r\n throw new Error('unsupported size kernel');\r\n }\r\n }\r\n\r\n _graphicalKernelBody(kernelThreadString) {\r\n switch (this.output.length) {\r\n case 2:\r\n return this._graphicalKernel2DLoop(kernelThreadString) + this._graphicalOutput();\r\n default:\r\n throw new Error('unsupported size kernel');\r\n }\r\n }\r\n\r\n _graphicalOutput() {\r\n return `\r\n this._imageData.data.set(this._colorData);\r\n this.context.putImageData(this._imageData, 0, 0);\r\n return;`\r\n }\r\n\r\n _getKernelResultTypeConstructorString() {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n return 'Float32Array';\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n return 'Array';\r\n default:\r\n if (this.graphical) {\r\n return 'Float32Array';\r\n }\r\n throw new Error(`unhandled returnType ${ this.returnType }`);\r\n }\r\n }\r\n\r\n _resultKernel1DLoop(kernelString) {\r\n const {\r\n output\r\n } = this;\r\n const constructorString = this._getKernelResultTypeConstructorString();\r\n return ` const outputX = _this.output[0];\r\n const result = new ${constructorString}(outputX);\r\n ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new ${constructorString}(outputX);\\n`).join(' ') }\r\n ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\\n`).join(' ') }\r\n for (let x = 0; x < outputX; x++) {\r\n this.thread.x = x;\r\n this.thread.y = 0;\r\n this.thread.z = 0;\r\n ${ kernelString }\r\n }`;\r\n }\r\n\r\n _resultKernel2DLoop(kernelString) {\r\n const {\r\n output\r\n } = this;\r\n const constructorString = this._getKernelResultTypeConstructorString();\r\n return ` const outputX = _this.output[0];\r\n const outputY = _this.output[1];\r\n const result = new Array(outputY);\r\n ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\\n`).join(' ') }\r\n ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\\n`).join(' ') }\r\n for (let y = 0; y < outputY; y++) {\r\n this.thread.z = 0;\r\n this.thread.y = y;\r\n const resultX = result[y] = new ${constructorString}(outputX);\r\n ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\\n`).join('') }\r\n for (let x = 0; x < outputX; x++) {\r\n this.thread.x = x;\r\n ${ kernelString }\r\n }\r\n }`;\r\n }\r\n\r\n _graphicalKernel2DLoop(kernelString) {\r\n const {\r\n output\r\n } = this;\r\n const constructorString = this._getKernelResultTypeConstructorString();\r\n return ` const outputX = _this.output[0];\r\n const outputY = _this.output[1];\r\n ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\\n`).join(' ') }\r\n ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\\n`).join(' ') }\r\n for (let y = 0; y < outputY; y++) {\r\n this.thread.z = 0;\r\n this.thread.y = y;\r\n ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\\n`).join('') }\r\n for (let x = 0; x < outputX; x++) {\r\n this.thread.x = x;\r\n ${ kernelString }\r\n }\r\n }`;\r\n }\r\n\r\n _resultKernel3DLoop(kernelString) {\r\n const {\r\n output\r\n } = this;\r\n const constructorString = this._getKernelResultTypeConstructorString();\r\n return ` const outputX = _this.output[0];\r\n const outputY = _this.output[1];\r\n const outputZ = _this.output[2];\r\n const result = new Array(outputZ);\r\n ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputZ);\\n`).join(' ') }\r\n ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\\n`).join(' ') }\r\n for (let z = 0; z < outputZ; z++) {\r\n this.thread.z = z;\r\n const resultY = result[z] = new Array(outputY);\r\n ${ this._mapSubKernels(subKernel => `const resultY_${ subKernel.name } = result_${subKernel.name}[z] = new Array(outputY);\\n`).join(' ') }\r\n for (let y = 0; y < outputY; y++) {\r\n this.thread.y = y;\r\n const resultX = resultY[y] = new ${constructorString}(outputX);\r\n ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = resultY_${subKernel.name}[y] = new ${constructorString}(outputX);\\n`).join(' ') }\r\n for (let x = 0; x < outputX; x++) {\r\n this.thread.x = x;\r\n ${ kernelString }\r\n }\r\n }\r\n }`;\r\n }\r\n\r\n _kernelOutput() {\r\n if (!this.subKernels) {\r\n return '\\n return result;';\r\n }\r\n return `\\n return {\r\n result: result,\r\n ${ this.subKernels.map(subKernel => `${ subKernel.property }: result_${ subKernel.name }`).join(',\\n ') }\r\n };`;\r\n }\r\n\r\n _mapSubKernels(fn) {\r\n return this.subKernels === null ? [''] :\r\n this.subKernels.map(fn);\r\n }\r\n\r\n\r\n\r\n destroy(removeCanvasReference) {\r\n if (removeCanvasReference) {\r\n delete this.canvas;\r\n }\r\n }\r\n\r\n static destroyContext(context) {}\r\n\r\n toJSON() {\r\n const json = super.toJSON();\r\n json.functionNodes = FunctionBuilder.fromKernel(this, CPUFunctionNode).toJSON();\r\n return json;\r\n }\r\n\r\n setOutput(output) {\r\n super.setOutput(output);\r\n const [width, height] = this.output;\r\n if (this.graphical) {\r\n this._imageData = this.context.createImageData(width, height);\r\n this._colorData = new Uint8ClampedArray(width * height * 4);\r\n }\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { Texture } from '../../../texture';\r\n\r\nexport class GLTextureFloat extends Texture {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(1)';\r\n }\r\n renderRawOutput() {\r\n const { context: gl } = this;\r\n const framebuffer = gl.createFramebuffer();\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\r\n gl.framebufferTexture2D(\r\n gl.FRAMEBUFFER,\r\n gl.COLOR_ATTACHMENT0,\r\n gl.TEXTURE_2D,\r\n this.texture,\r\n 0\r\n );\r\n const result = new Float32Array(this.size[0] * this.size[1] * 4);\r\n gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.FLOAT, result);\r\n return result;\r\n }\r\n renderValues() {\r\n return this.renderRawOutput();\r\n }\r\n toArray() {\r\n return utils.erectFloat(this.renderValues(), this.output[0]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray2Float extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(2)';\r\n }\r\n toArray() {\r\n return utils.erectArray2(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray2Float2D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(2)';\r\n }\r\n toArray() {\r\n return utils.erect2DArray2(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray2Float3D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(2)';\r\n }\r\n toArray() {\r\n return utils.erect3DArray2(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray3Float extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(3)';\r\n }\r\n toArray() {\r\n return utils.erectArray3(this.renderValues(), this.output[0]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray3Float2D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(3)';\r\n }\r\n toArray() {\r\n return utils.erect2DArray3(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray3Float3D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(3)';\r\n }\r\n toArray() {\r\n return utils.erect3DArray3(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray4Float extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(4)';\r\n }\r\n toArray() {\r\n return utils.erectArray4(this.renderValues(), this.output[0]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray4Float2D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(4)';\r\n }\r\n toArray() {\r\n return utils.erect2DArray4(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray4Float3D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(4)';\r\n }\r\n toArray() {\r\n return utils.erect3DArray4(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureFloat2D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(1)';\r\n }\r\n toArray() {\r\n return utils.erect2DFloat(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureFloat3D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(1)';\r\n }\r\n toArray() {\r\n return utils.erect3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureMemoryOptimized extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'MemoryOptimizedNumberTexture';\r\n }\r\n toArray() {\r\n return utils.erectMemoryOptimizedFloat(this.renderValues(), this.output[0]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureMemoryOptimized2D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'MemoryOptimizedNumberTexture';\r\n }\r\n toArray() {\r\n return utils.erectMemoryOptimized2DFloat(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureMemoryOptimized3D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'MemoryOptimizedNumberTexture';\r\n }\r\n toArray() {\r\n return utils.erectMemoryOptimized3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { Texture } from '../../../texture';\r\n\r\nexport class GLTextureUnsigned extends Texture {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'NumberTexture';\r\n }\r\n renderRawOutput() {\r\n const { context: gl } = this;\r\n const framebuffer = gl.createFramebuffer();\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\r\n gl.framebufferTexture2D(\r\n gl.FRAMEBUFFER,\r\n gl.COLOR_ATTACHMENT0,\r\n gl.TEXTURE_2D,\r\n this.texture,\r\n 0\r\n );\r\n const result = new Uint8Array(this.size[0] * this.size[1] * 4);\r\n gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.UNSIGNED_BYTE, result);\r\n return result;\r\n }\r\n renderValues() {\r\n return new Float32Array(this.renderRawOutput().buffer);\r\n }\r\n toArray() {\r\n return utils.erectPackedFloat(this.renderValues(), this.output[0]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureUnsigned } from './unsigned';\r\n\r\nexport class GLTextureUnsigned2D extends GLTextureUnsigned {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'NumberTexture';\r\n }\r\n toArray() {\r\n return utils.erect2DPackedFloat(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureUnsigned } from './unsigned';\r\n\r\nexport class GLTextureUnsigned3D extends GLTextureUnsigned {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'NumberTexture';\r\n }\r\n toArray() {\r\n return utils.erect3DPackedFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { GLTextureUnsigned } from './unsigned';\r\n\r\nexport class GLTextureGraphical extends GLTextureUnsigned {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(4)';\r\n }\r\n toArray() {\r\n return this.renderValues();\r\n }\r\n}\r\n","import { Kernel } from '../kernel';\r\nimport { utils } from '../../utils';\r\nimport { GLTextureArray2Float } from './texture/array-2-float';\r\nimport { GLTextureArray2Float2D } from './texture/array-2-float-2d';\r\nimport { GLTextureArray2Float3D } from './texture/array-2-float-3d';\r\nimport { GLTextureArray3Float } from './texture/array-3-float';\r\nimport { GLTextureArray3Float2D } from './texture/array-3-float-2d';\r\nimport { GLTextureArray3Float3D } from './texture/array-3-float-3d';\r\nimport { GLTextureArray4Float } from './texture/array-4-float';\r\nimport { GLTextureArray4Float2D } from './texture/array-4-float-2d';\r\nimport { GLTextureArray4Float3D } from './texture/array-4-float-3d';\r\nimport { GLTextureFloat } from './texture/float';\r\nimport { GLTextureFloat2D } from './texture/float-2d';\r\nimport { GLTextureFloat3D } from './texture/float-3d';\r\nimport { GLTextureMemoryOptimized } from './texture/memory-optimized';\r\nimport { GLTextureMemoryOptimized2D } from './texture/memory-optimized-2d';\r\nimport { GLTextureMemoryOptimized3D } from './texture/memory-optimized-3d';\r\nimport { GLTextureUnsigned } from './texture/unsigned';\r\nimport { GLTextureUnsigned2D } from './texture/unsigned-2d';\r\nimport { GLTextureUnsigned3D } from './texture/unsigned-3d';\r\nimport { GLTextureGraphical } from './texture/graphical';\r\n\r\n/**\r\n * @abstract\r\n * @extends Kernel\r\n */\r\nexport class GLKernel extends Kernel {\r\n static get mode() {\r\n return 'gpu';\r\n }\r\n\r\n static getIsFloatRead() {\r\n const kernelString = `function kernelFunction() {\r\n return 1;\r\n }`;\r\n const kernel = new this(kernelString, {\r\n context: this.testContext,\r\n canvas: this.testCanvas,\r\n validate: false,\r\n output: [1],\r\n precision: 'single',\r\n returnType: 'Number',\r\n tactic: 'speed',\r\n });\r\n kernel.build();\r\n kernel.run();\r\n const result = kernel.renderOutput();\r\n kernel.destroy(true);\r\n return result[0] === 1;\r\n }\r\n\r\n static getIsIntegerDivisionAccurate() {\r\n function kernelFunction(v1, v2) {\r\n return v1[this.thread.x] / v2[this.thread.x];\r\n }\r\n const kernel = new this(kernelFunction.toString(), {\r\n context: this.testContext,\r\n canvas: this.testCanvas,\r\n validate: false,\r\n output: [2],\r\n returnType: 'Number',\r\n precision: 'unsigned',\r\n tactic: 'speed',\r\n });\r\n const args = [\r\n [6, 6030401],\r\n [3, 3991]\r\n ];\r\n kernel.build.apply(kernel, args);\r\n kernel.run.apply(kernel, args);\r\n const result = kernel.renderOutput();\r\n kernel.destroy(true);\r\n // have we not got whole numbers for 6/3 or 6030401/3991\r\n // add more here if others see this problem\r\n return result[0] === 2 && result[1] === 1511;\r\n }\r\n\r\n /**\r\n * @abstract\r\n */\r\n static get testCanvas() {\r\n throw new Error(`\"testCanvas\" not defined on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @abstract\r\n */\r\n static get testContext() {\r\n throw new Error(`\"testContext\" not defined on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @type {IKernelFeatures}\r\n */\r\n static get features() {\r\n throw new Error(`\"features\" not defined on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @abstract\r\n */\r\n static setupFeatureChecks() {\r\n throw new Error(`\"setupFeatureChecks\" not defined on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @desc Fix division by factor of 3 FP accuracy bug\r\n * @param {Boolean} fix - should fix\r\n */\r\n setFixIntegerDivisionAccuracy(fix) {\r\n this.fixIntegerDivisionAccuracy = fix;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Toggle output mode\r\n * @param {String} flag - 'single' or 'unsigned'\r\n */\r\n setPrecision(flag) {\r\n this.precision = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Toggle texture output mode\r\n * @param {Boolean} flag - true to enable floatTextures\r\n * @deprecated\r\n */\r\n setFloatTextures(flag) {\r\n utils.warnDeprecated('method', 'setFloatTextures', 'setOptimizeFloatMemory');\r\n this.floatTextures = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * A highly readable very forgiving micro-parser for a glsl function that gets argument types\r\n * @param {String} source\r\n * @returns {{argumentTypes: String[], argumentNames: String[]}}\r\n */\r\n static nativeFunctionArguments(source) {\r\n const argumentTypes = [];\r\n const argumentNames = [];\r\n const states = [];\r\n const isStartingVariableName = /^[a-zA-Z_]/;\r\n const isVariableChar = /[a-zA-Z_0-9]/;\r\n let i = 0;\r\n let argumentName = null;\r\n let argumentType = null;\r\n while (i < source.length) {\r\n const char = source[i];\r\n const nextChar = source[i + 1];\r\n const state = states.length > 0 ? states[states.length - 1] : null;\r\n\r\n // begin MULTI_LINE_COMMENT handling\r\n if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '*') {\r\n states.push('MULTI_LINE_COMMENT');\r\n i += 2;\r\n continue;\r\n } else if (state === 'MULTI_LINE_COMMENT' && char === '*' && nextChar === '/') {\r\n states.pop();\r\n i += 2;\r\n continue;\r\n }\r\n // end MULTI_LINE_COMMENT handling\r\n\r\n // begin COMMENT handling\r\n else if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '/') {\r\n states.push('COMMENT');\r\n i += 2;\r\n continue;\r\n } else if (state === 'COMMENT' && char === '\\n') {\r\n states.pop();\r\n i++;\r\n continue;\r\n }\r\n // end COMMENT handling\r\n\r\n // being FUNCTION_ARGUMENTS handling\r\n else if (state === null && char === '(') {\r\n states.push('FUNCTION_ARGUMENTS');\r\n i++;\r\n continue;\r\n } else if (state === 'FUNCTION_ARGUMENTS') {\r\n if (char === ')') {\r\n states.pop();\r\n break;\r\n }\r\n if (char === 'f' && nextChar === 'l' && source[i + 2] === 'o' && source[i + 3] === 'a' && source[i + 4] === 't' && source[i + 5] === ' ') {\r\n states.push('DECLARE_VARIABLE');\r\n argumentType = 'float';\r\n argumentName = '';\r\n i += 6;\r\n continue;\r\n } else if (char === 'i' && nextChar === 'n' && source[i + 2] === 't' && source[i + 3] === ' ') {\r\n states.push('DECLARE_VARIABLE');\r\n argumentType = 'int';\r\n argumentName = '';\r\n i += 4;\r\n continue;\r\n } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '2' && source[i + 4] === ' ') {\r\n states.push('DECLARE_VARIABLE');\r\n argumentType = 'vec2';\r\n argumentName = '';\r\n i += 5;\r\n continue;\r\n } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '3' && source[i + 4] === ' ') {\r\n states.push('DECLARE_VARIABLE');\r\n argumentType = 'vec3';\r\n argumentName = '';\r\n i += 5;\r\n continue;\r\n } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '4' && source[i + 4] === ' ') {\r\n states.push('DECLARE_VARIABLE');\r\n argumentType = 'vec4';\r\n argumentName = '';\r\n i += 5;\r\n continue;\r\n }\r\n }\r\n // end FUNCTION_ARGUMENTS handling\r\n\r\n // begin DECLARE_VARIABLE handling\r\n else if (state === 'DECLARE_VARIABLE') {\r\n if (argumentName === '') {\r\n if (char === ' ') {\r\n i++;\r\n continue;\r\n }\r\n if (!isStartingVariableName.test(char)) {\r\n throw new Error('variable name is not expected string');\r\n }\r\n }\r\n argumentName += char;\r\n if (!isVariableChar.test(nextChar)) {\r\n states.pop();\r\n argumentNames.push(argumentName);\r\n argumentTypes.push(typeMap[argumentType]);\r\n }\r\n }\r\n // end DECLARE_VARIABLE handling\r\n\r\n // Progress to next character\r\n i++;\r\n }\r\n if (states.length > 0) {\r\n throw new Error('GLSL function was not parsable');\r\n }\r\n return {\r\n argumentNames,\r\n argumentTypes,\r\n };\r\n }\r\n\r\n static nativeFunctionReturnType(source) {\r\n return typeMap[source.match(/int|float|vec[2-4]/)[0]];\r\n }\r\n\r\n static combineKernels(combinedKernel, lastKernel) {\r\n combinedKernel.apply(null, arguments);\r\n const {\r\n texSize,\r\n context,\r\n threadDim\r\n } = lastKernel.texSize;\r\n let result;\r\n if (lastKernel.precision === 'single') {\r\n const w = texSize[0];\r\n const h = Math.ceil(texSize[1] / 4);\r\n result = new Float32Array(w * h * 4 * 4);\r\n context.readPixels(0, 0, w, h * 4, context.RGBA, context.FLOAT, result);\r\n } else {\r\n const bytes = new Uint8Array(texSize[0] * texSize[1] * 4);\r\n context.readPixels(0, 0, texSize[0], texSize[1], context.RGBA, context.UNSIGNED_BYTE, bytes);\r\n result = new Float32Array(bytes.buffer);\r\n }\r\n\r\n result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]);\r\n\r\n if (lastKernel.output.length === 1) {\r\n return result;\r\n } else if (lastKernel.output.length === 2) {\r\n return utils.splitArray(result, lastKernel.output[0]);\r\n } else if (lastKernel.output.length === 3) {\r\n const cube = utils.splitArray(result, lastKernel.output[0] * lastKernel.output[1]);\r\n return cube.map(function(x) {\r\n return utils.splitArray(x, lastKernel.output[0]);\r\n });\r\n }\r\n }\r\n\r\n constructor(source, settings) {\r\n super(source, settings);\r\n this.transferValues = null;\r\n this.formatValues = null;\r\n this.TextureConstructor = null;\r\n this.renderOutput = null;\r\n this.renderRawOutput = null;\r\n this.texSize = null;\r\n this.translatedSource = null;\r\n this.renderStrategy = null;\r\n this.compiledFragmentShader = null;\r\n this.compiledVertexShader = null;\r\n }\r\n\r\n checkTextureSize() {\r\n const { features } = this.constructor;\r\n if (this.texSize[0] > features.maxTextureSize || this.texSize[1] > features.maxTextureSize) {\r\n throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${features.maxTextureSize},${features.maxTextureSize}]`);\r\n }\r\n }\r\n\r\n translateSource() {\r\n throw new Error(`\"translateSource\" not defined on ${this.constructor.name}`);\r\n }\r\n\r\n /**\r\n * Picks a render strategy for the now finally parsed kernel\r\n * @param args\r\n * @return {null|KernelOutput}\r\n */\r\n pickRenderStrategy(args) {\r\n if (this.graphical) {\r\n this.renderRawOutput = this.readPackedPixelsToUint8Array;\r\n this.transferValues = (pixels) => pixels;\r\n this.TextureConstructor = GLTextureGraphical;\r\n return null;\r\n }\r\n if (this.precision === 'unsigned') {\r\n this.renderRawOutput = this.readPackedPixelsToUint8Array;\r\n this.transferValues = this.readPackedPixelsToFloat32Array;\r\n if (this.pipeline) {\r\n this.renderOutput = this.renderTexture;\r\n if (this.subKernels !== null) {\r\n this.renderKernels = this.renderKernelsToTextures;\r\n }\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureUnsigned3D;\r\n this.renderStrategy = renderStrategy.PackedPixelTo3DFloat;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureUnsigned2D;\r\n this.renderStrategy = renderStrategy.PackedPixelTo2DFloat;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureUnsigned;\r\n this.renderStrategy = renderStrategy.PackedPixelToFloat;\r\n return null;\r\n }\r\n break;\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n return this.requestFallback(args);\r\n }\r\n } else {\r\n if (this.subKernels !== null) {\r\n this.renderKernels = this.renderKernelsToArrays;\r\n }\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n this.renderOutput = this.renderValues;\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureUnsigned3D;\r\n this.renderStrategy = renderStrategy.PackedPixelTo3DFloat;\r\n this.formatValues = utils.erect3DPackedFloat;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureUnsigned2D;\r\n this.renderStrategy = renderStrategy.PackedPixelTo2DFloat;\r\n this.formatValues = utils.erect2DPackedFloat;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureUnsigned;\r\n this.renderStrategy = renderStrategy.PackedPixelToFloat;\r\n this.formatValues = utils.erectPackedFloat;\r\n return null;\r\n }\r\n\r\n break;\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n return this.requestFallback(args);\r\n }\r\n }\r\n } else if (this.precision === 'single') {\r\n this.renderRawOutput = this.readFloatPixelsToFloat32Array;\r\n this.transferValues = this.readFloatPixelsToFloat32Array;\r\n if (this.pipeline) {\r\n this.renderStrategy = renderStrategy.FloatTexture;\r\n this.renderOutput = this.renderTexture;\r\n if (this.subKernels !== null) {\r\n this.renderKernels = this.renderKernelsToTextures;\r\n }\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n if (this.optimizeFloatMemory) {\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureMemoryOptimized3D;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureMemoryOptimized2D;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureMemoryOptimized;\r\n return null;\r\n }\r\n } else {\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureFloat3D;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureFloat2D;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureFloat;\r\n return null;\r\n }\r\n }\r\n break;\r\n case 'Array(2)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float3D;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float2D;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray2Float;\r\n return null;\r\n }\r\n break;\r\n case 'Array(3)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float3D;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float2D;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray3Float;\r\n return null;\r\n }\r\n break;\r\n case 'Array(4)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float3D;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float2D;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray4Float;\r\n return null;\r\n }\r\n }\r\n }\r\n this.renderOutput = this.renderValues;\r\n if (this.subKernels !== null) {\r\n this.renderKernels = this.renderKernelsToArrays;\r\n }\r\n if (this.optimizeFloatMemory) {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureMemoryOptimized3D;\r\n this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized3DFloat;\r\n this.formatValues = utils.erectMemoryOptimized3DFloat;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureMemoryOptimized2D;\r\n this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized2DFloat;\r\n this.formatValues = utils.erectMemoryOptimized2DFloat;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureMemoryOptimized;\r\n this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimizedFloat;\r\n this.formatValues = utils.erectMemoryOptimizedFloat;\r\n return null;\r\n }\r\n break;\r\n case 'Array(2)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray2;\r\n this.formatValues = utils.erect3DArray2;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray2;\r\n this.formatValues = utils.erect2DArray2;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray2Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray2;\r\n this.formatValues = utils.erectArray2;\r\n return null;\r\n }\r\n break;\r\n case 'Array(3)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray3;\r\n this.formatValues = utils.erect3DArray3;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray3;\r\n this.formatValues = utils.erect2DArray3;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray3Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray3;\r\n this.formatValues = utils.erectArray3;\r\n return null;\r\n }\r\n break;\r\n case 'Array(4)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray4;\r\n this.formatValues = utils.erect3DArray4;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray4;\r\n this.formatValues = utils.erect2DArray4;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray4Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray4;\r\n this.formatValues = utils.erectArray4;\r\n return null;\r\n }\r\n }\r\n } else {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureFloat3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DFloat;\r\n this.formatValues = utils.erect3DFloat;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureFloat2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DFloat;\r\n this.formatValues = utils.erect2DFloat;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureFloat;\r\n this.renderStrategy = renderStrategy.FloatPixelToFloat;\r\n this.formatValues = utils.erectFloat;\r\n return null;\r\n }\r\n break;\r\n case 'Array(2)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray2;\r\n this.formatValues = utils.erect3DArray2;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray2;\r\n this.formatValues = utils.erect2DArray2;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray2Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray2;\r\n this.formatValues = utils.erectArray2;\r\n return null;\r\n }\r\n break;\r\n case 'Array(3)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray3;\r\n this.formatValues = utils.erect3DArray3;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray3;\r\n this.formatValues = utils.erect2DArray3;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray3Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray3;\r\n this.formatValues = utils.erectArray3;\r\n return null;\r\n }\r\n break;\r\n case 'Array(4)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray4;\r\n this.formatValues = utils.erect3DArray4;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray4;\r\n this.formatValues = utils.erect2DArray4;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray4Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray4;\r\n this.formatValues = utils.erectArray4;\r\n return null;\r\n }\r\n }\r\n }\r\n } else {\r\n throw new Error(`unhandled precision of \"${this.precision}\"`);\r\n }\r\n\r\n throw new Error(`unhandled return type \"${this.returnType}\"`);\r\n }\r\n\r\n /**\r\n * @abstract\r\n * @returns String\r\n */\r\n getKernelString() {\r\n throw new Error(`abstract method call`);\r\n }\r\n\r\n getMainResultTexture() {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Integer':\r\n case 'Number':\r\n return this.getMainResultNumberTexture();\r\n case 'Array(2)':\r\n return this.getMainResultArray2Texture();\r\n case 'Array(3)':\r\n return this.getMainResultArray3Texture();\r\n case 'Array(4)':\r\n return this.getMainResultArray4Texture();\r\n default:\r\n throw new Error(`unhandled returnType type ${ this.returnType }`);\r\n }\r\n }\r\n\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultKernelNumberTexture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultSubKernelNumberTexture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultKernelArray2Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultSubKernelArray2Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultKernelArray3Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultSubKernelArray3Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultKernelArray4Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultSubKernelArray4Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultGraphical() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultMemoryOptimizedFloats() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultPackedPixels() {\r\n throw new Error(`abstract method call`);\r\n }\r\n\r\n getMainResultString() {\r\n if (this.graphical) {\r\n return this.getMainResultGraphical();\r\n } else if (this.precision === 'single') {\r\n if (this.optimizeFloatMemory) {\r\n return this.getMainResultMemoryOptimizedFloats();\r\n }\r\n return this.getMainResultTexture();\r\n } else {\r\n return this.getMainResultPackedPixels();\r\n }\r\n }\r\n\r\n getMainResultNumberTexture() {\r\n return utils.linesToString(this.getMainResultKernelNumberTexture()) +\r\n utils.linesToString(this.getMainResultSubKernelNumberTexture());\r\n }\r\n\r\n getMainResultArray2Texture() {\r\n return utils.linesToString(this.getMainResultKernelArray2Texture()) +\r\n utils.linesToString(this.getMainResultSubKernelArray2Texture());\r\n }\r\n\r\n getMainResultArray3Texture() {\r\n return utils.linesToString(this.getMainResultKernelArray3Texture()) +\r\n utils.linesToString(this.getMainResultSubKernelArray3Texture());\r\n }\r\n\r\n getMainResultArray4Texture() {\r\n return utils.linesToString(this.getMainResultKernelArray4Texture()) +\r\n utils.linesToString(this.getMainResultSubKernelArray4Texture());\r\n }\r\n\r\n /**\r\n *\r\n * @return {string}\r\n */\r\n getFloatTacticDeclaration() {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'precision lowp float;\\n';\r\n case 'performance':\r\n return 'precision highp float;\\n';\r\n case 'balanced':\r\n default:\r\n return 'precision mediump float;\\n';\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @return {string}\r\n */\r\n getIntTacticDeclaration() {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'precision lowp int;\\n';\r\n case 'performance':\r\n return 'precision highp int;\\n';\r\n case 'balanced':\r\n default:\r\n return 'precision mediump int;\\n';\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @return {string}\r\n */\r\n getSampler2DTacticDeclaration() {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'precision lowp sampler2D;\\n';\r\n case 'performance':\r\n return 'precision highp sampler2D;\\n';\r\n case 'balanced':\r\n default:\r\n return 'precision mediump sampler2D;\\n';\r\n }\r\n }\r\n\r\n getSampler2DArrayTacticDeclaration() {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'precision lowp sampler2DArray;\\n';\r\n case 'performance':\r\n return 'precision highp sampler2DArray;\\n';\r\n case 'balanced':\r\n default:\r\n return 'precision mediump sampler2DArray;\\n';\r\n }\r\n }\r\n\r\n renderTexture() {\r\n return new this.TextureConstructor({\r\n texture: this.outputTexture,\r\n size: this.texSize,\r\n dimensions: this.threadDim,\r\n output: this.output,\r\n context: this.context,\r\n });\r\n }\r\n readPackedPixelsToUint8Array() {\r\n if (this.precision !== 'unsigned') throw new Error('Requires this.precision to be \"unsigned\"');\r\n const {\r\n texSize,\r\n context: gl\r\n } = this;\r\n const result = new Uint8Array(texSize[0] * texSize[1] * 4);\r\n gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, result);\r\n return result;\r\n }\r\n\r\n readPackedPixelsToFloat32Array() {\r\n return new Float32Array(this.readPackedPixelsToUint8Array().buffer);\r\n }\r\n\r\n readFloatPixelsToFloat32Array() {\r\n if (this.precision !== 'single') throw new Error('Requires this.precision to be \"single\"');\r\n const {\r\n texSize,\r\n context: gl\r\n } = this;\r\n const w = texSize[0];\r\n const h = texSize[1];\r\n const result = new Float32Array(w * h * 4);\r\n gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result);\r\n return result;\r\n }\r\n\r\n readMemoryOptimizedFloatPixelsToFloat32Array() {\r\n if (this.precision !== 'single') throw new Error('Requires this.precision to be \"single\"');\r\n const {\r\n texSize,\r\n context: gl\r\n } = this;\r\n const w = texSize[0];\r\n const h = texSize[1];\r\n const result = new Float32Array(w * h * 4);\r\n gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result);\r\n return result;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Boolean} [flip]\r\n * @return {Uint8Array}\r\n */\r\n getPixels(flip) {\r\n const {\r\n context: gl,\r\n output\r\n } = this;\r\n const [width, height] = output;\r\n const pixels = new Uint8Array(width * height * 4);\r\n gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);\r\n // flipped by default, so invert\r\n return new Uint8ClampedArray((flip ? pixels : utils.flipPixels(pixels, width, height)).buffer);\r\n }\r\n\r\n renderKernelsToArrays() {\r\n const result = {\r\n result: this.renderOutput(),\r\n };\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n result[this.subKernels[i].property] = new this.TextureConstructor({\r\n texture: this.subKernelOutputTextures[i],\r\n size: this.texSize,\r\n dimensions: this.threadDim,\r\n output: this.output,\r\n context: this.context,\r\n }).toArray();\r\n }\r\n return result;\r\n }\r\n\r\n renderKernelsToTextures() {\r\n const result = {\r\n result: this.renderOutput(),\r\n };\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n result[this.subKernels[i].property] = new this.TextureConstructor({\r\n texture: this.subKernelOutputTextures[i],\r\n size: this.texSize,\r\n dimensions: this.threadDim,\r\n output: this.output,\r\n context: this.context,\r\n });\r\n }\r\n return result;\r\n }\r\n\r\n setOutput(output) {\r\n super.setOutput(output);\r\n if (this.program) {\r\n this.threadDim = [this.output[0], this.output[1] || 1, this.output[2] || 1];\r\n this.texSize = utils.getKernelTextureSize({\r\n optimizeFloatMemory: this.optimizeFloatMemory,\r\n precision: this.precision,\r\n }, this.output);\r\n const { context: gl } = this;\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n this.updateMaxTexSize();\r\n this.framebuffer.width = this.texSize[0];\r\n this.framebuffer.height = this.texSize[1];\r\n this.context.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);\r\n this.canvas.width = this.maxTexSize[0];\r\n this.canvas.height = this.maxTexSize[1];\r\n this._setupOutputTexture();\r\n if (this.subKernels && this.subKernels.length > 0) {\r\n this._setupSubOutputTextures();\r\n }\r\n }\r\n return this;\r\n }\r\n renderValues() {\r\n return this.formatValues(\r\n this.transferValues(),\r\n this.output[0],\r\n this.output[1],\r\n this.output[2]\r\n );\r\n }\r\n}\r\n\r\nexport const renderStrategy = Object.freeze({\r\n PackedPixelToUint8Array: Symbol('PackedPixelToUint8Array'),\r\n PackedPixelToFloat: Symbol('PackedPixelToFloat'),\r\n PackedPixelTo2DFloat: Symbol('PackedPixelTo2DFloat'),\r\n PackedPixelTo3DFloat: Symbol('PackedPixelTo3DFloat'),\r\n PackedTexture: Symbol('PackedTexture'),\r\n FloatPixelToFloat32Array: Symbol('FloatPixelToFloat32Array'),\r\n FloatPixelToFloat: Symbol('FloatPixelToFloat'),\r\n FloatPixelTo2DFloat: Symbol('FloatPixelTo2DFloat'),\r\n FloatPixelTo3DFloat: Symbol('FloatPixelTo3DFloat'),\r\n FloatPixelToArray2: Symbol('FloatPixelToArray2'),\r\n FloatPixelTo2DArray2: Symbol('FloatPixelTo2DArray2'),\r\n FloatPixelTo3DArray2: Symbol('FloatPixelTo3DArray2'),\r\n FloatPixelToArray3: Symbol('FloatPixelToArray3'),\r\n FloatPixelTo2DArray3: Symbol('FloatPixelTo2DArray3'),\r\n FloatPixelTo3DArray3: Symbol('FloatPixelTo3DArray3'),\r\n FloatPixelToArray4: Symbol('FloatPixelToArray4'),\r\n FloatPixelTo2DArray4: Symbol('FloatPixelTo2DArray4'),\r\n FloatPixelTo3DArray4: Symbol('FloatPixelTo3DArray4'),\r\n FloatTexture: Symbol('FloatTexture'),\r\n MemoryOptimizedFloatPixelToMemoryOptimizedFloat: Symbol('MemoryOptimizedFloatPixelToFloat'),\r\n MemoryOptimizedFloatPixelToMemoryOptimized2DFloat: Symbol('MemoryOptimizedFloatPixelTo2DFloat'),\r\n MemoryOptimizedFloatPixelToMemoryOptimized3DFloat: Symbol('MemoryOptimizedFloatPixelTo3DFloat'),\r\n});\r\n\r\nconst typeMap = {\r\n int: 'Integer',\r\n float: 'Number',\r\n vec2: 'Array(2)',\r\n vec3: 'Array(3)',\r\n vec4: 'Array(4)',\r\n};\r\n","import { utils } from '../../utils';\r\nimport { FunctionNode } from '../function-node';\r\n// Closure capture for the ast function, prevent collision with existing AST functions\r\n// The prefixes to use\r\nconst jsMathPrefix = 'Math.';\r\nconst localPrefix = 'this.';\r\n\r\n/**\r\n * @desc [INTERNAL] Takes in a function node, and does all the AST voodoo required to toString its respective WebGL code\r\n * @extends FunctionNode\r\n * @returns the converted WebGL function string\r\n */\r\nexport class WebGLFunctionNode extends FunctionNode {\r\n constructor(source, settings) {\r\n super(source, settings);\r\n if (settings && settings.hasOwnProperty('fixIntegerDivisionAccuracy')) {\r\n this.fixIntegerDivisionAccuracy = settings.fixIntegerDivisionAccuracy;\r\n }\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for to its *named function*\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astFunction(ast, retArr) {\r\n // Setup function return type and name\r\n if (this.isRootKernel) {\r\n retArr.push('void');\r\n } else {\r\n // looking up return type, this is a little expensive, and can be avoided if returnType is set\r\n let lastReturn = null;\r\n if (!this.returnType) {\r\n const lastReturn = this.findLastReturn();\r\n if (lastReturn) {\r\n this.returnType = this.getType(ast.body);\r\n if (this.returnType === 'LiteralInteger') {\r\n this.returnType = 'Number';\r\n }\r\n }\r\n }\r\n\r\n const { returnType } = this;\r\n if (!returnType) {\r\n retArr.push('void');\r\n } else {\r\n const type = typeMap[returnType];\r\n if (!type) {\r\n throw new Error(`unknown type ${returnType}`);\r\n }\r\n retArr.push(type);\r\n }\r\n }\r\n retArr.push(' ');\r\n retArr.push(this.name);\r\n retArr.push('(');\r\n\r\n if (!this.isRootKernel) {\r\n // Arguments handling\r\n for (let i = 0; i < this.argumentNames.length; ++i) {\r\n const argumentName = this.argumentNames[i];\r\n\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n let argumentType = this.argumentTypes[this.argumentNames.indexOf(argumentName)];\r\n // The type is too loose ended, here we descide to solidify a type, lets go with float\r\n if (!argumentType) {\r\n throw this.astErrorOutput(`Unknown argument ${argumentName} type`, ast);\r\n }\r\n if (argumentType === 'LiteralInteger') {\r\n this.argumentTypes[i] = argumentType = 'Number';\r\n }\r\n const type = typeMap[argumentType];\r\n if (!type) {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n retArr.push(type);\r\n retArr.push(' ');\r\n retArr.push('user_');\r\n retArr.push(argumentName);\r\n }\r\n }\r\n\r\n // Function opening\r\n retArr.push(') {\\n');\r\n\r\n // Body statement iteration\r\n for (let i = 0; i < ast.body.body.length; ++i) {\r\n this.astGeneric(ast.body.body[i], retArr);\r\n retArr.push('\\n');\r\n }\r\n\r\n // Function closing\r\n retArr.push('}\\n');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for to *return* statement\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astReturnStatement(ast, retArr) {\r\n if (!ast.argument) throw this.astErrorOutput('Unexpected return statement', ast);\r\n this.pushState('skip-literal-correction');\r\n const type = this.getType(ast.argument);\r\n this.popState('skip-literal-correction');\r\n\r\n const result = [];\r\n\r\n if (!this.returnType) {\r\n if (type === 'LiteralInteger' || type === 'Integer') {\r\n this.returnType = 'Number';\r\n } else {\r\n this.returnType = type;\r\n }\r\n }\r\n\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Number':\r\n case 'Float':\r\n switch (type) {\r\n case 'Integer':\r\n result.push('float(');\r\n this.astGeneric(ast.argument, result);\r\n result.push(')');\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(ast.argument, result);\r\n\r\n // Running astGeneric forces the LiteralInteger to pick a type, and here, if we are returning a float, yet\r\n // the LiteralInteger has picked to be an integer because of constraints on it we cast it to float.\r\n if (this.getType(ast) === 'Integer') {\r\n result.unshift('float(');\r\n result.push(')');\r\n }\r\n break;\r\n default:\r\n this.astGeneric(ast.argument, result);\r\n }\r\n break;\r\n case 'Integer':\r\n switch (type) {\r\n case 'Float':\r\n case 'Number':\r\n this.castValueToInteger(ast.argument, result);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(ast.argument, result);\r\n break;\r\n default:\r\n this.astGeneric(ast.argument, result);\r\n }\r\n break;\r\n case 'Array(4)':\r\n case 'Array(3)':\r\n case 'Array(2)':\r\n case 'Input':\r\n this.astGeneric(ast.argument, result);\r\n break;\r\n default:\r\n throw this.astErrorOutput(`unhandled return type ${this.returnType}`, ast);\r\n }\r\n\r\n if (this.isRootKernel) {\r\n retArr.push(`kernelResult = ${ result.join('') };`);\r\n retArr.push('return;');\r\n } else if (this.isSubKernel) {\r\n retArr.push(`subKernelResult_${ this.name } = ${ result.join('') };`);\r\n retArr.push(`return subKernelResult_${ this.name };`);\r\n } else {\r\n retArr.push(`return ${ result.join('') };`);\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *literal value*\r\n *\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n *\r\n * @returns {Array} the append retArr\r\n */\r\n astLiteral(ast, retArr) {\r\n // Reject non numeric literals\r\n if (isNaN(ast.value)) {\r\n throw this.astErrorOutput(\r\n 'Non-numeric literal not supported : ' + ast.value,\r\n ast\r\n );\r\n }\r\n\r\n const key = `${ast.start},${ast.end}`;\r\n if (Number.isInteger(ast.value)) {\r\n if (this.isState('in-for-loop-init') || this.isState('casting-to-integer') || this.isState('building-integer')) {\r\n this.literalTypes[key] = 'Integer';\r\n retArr.push(`${ast.value}`);\r\n } else if (this.isState('casting-to-float') || this.isState('building-float')) {\r\n this.literalTypes[key] = 'Number';\r\n retArr.push(`${ast.value}.0`);\r\n } else {\r\n this.literalTypes[key] = 'Number';\r\n retArr.push(`${ast.value}.0`);\r\n }\r\n } else if (this.isState('casting-to-integer') || this.isState('building-integer')) {\r\n this.literalTypes[key] = 'Integer';\r\n retArr.push(Math.round(ast.value));\r\n } else {\r\n this.literalTypes[key] = 'Number';\r\n retArr.push(`${ast.value}`);\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *binary* expression\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astBinaryExpression(ast, retArr) {\r\n if (this.checkAndUpconvertOperator(ast, retArr)) {\r\n return retArr;\r\n }\r\n\r\n if (this.fixIntegerDivisionAccuracy && ast.operator === '/') {\r\n retArr.push('div_with_int_check(');\r\n this.pushState('building-float');\r\n switch (this.getType(ast.left)) {\r\n case 'Integer':\r\n this.castValueToFloat(ast.left, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(ast.left, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.left, retArr);\r\n }\r\n retArr.push(', ');\r\n switch (this.getType(ast.right)) {\r\n case 'Integer':\r\n this.castValueToFloat(ast.right, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(ast.right, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.right, retArr);\r\n }\r\n this.popState('building-float');\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n retArr.push('(');\r\n const leftType = this.getType(ast.left) || 'Number';\r\n const rightType = this.getType(ast.right) || 'Number';\r\n if (!leftType || !rightType) {\r\n throw this.astErrorOutput(`Unhandled binary expression`, ast);\r\n }\r\n const key = leftType + ' & ' + rightType;\r\n switch (key) {\r\n case 'Integer & Integer':\r\n this.pushState('building-integer');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-integer');\r\n break;\r\n case 'Number & Float':\r\n case 'Float & Number':\r\n case 'Float & Float':\r\n case 'Number & Number':\r\n this.pushState('building-float');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-float');\r\n break;\r\n case 'LiteralInteger & LiteralInteger':\r\n if (this.isState('casting-to-integer') || this.isState('building-integer')) {\r\n this.pushState('building-integer');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-integer');\r\n } else {\r\n this.pushState('building-float');\r\n this.castLiteralToFloat(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castLiteralToFloat(ast.right, retArr);\r\n this.popState('building-float');\r\n }\r\n break;\r\n\r\n case 'Integer & Float':\r\n case 'Integer & Number':\r\n if (ast.operator === '>' || ast.operator === '<' && ast.right.type === 'Literal') {\r\n // if right value is actually a float, don't loose that information, cast left to right rather than the usual right to left\r\n if (!Number.isInteger(ast.right.value)) {\r\n this.pushState('building-float');\r\n this.castValueToFloat(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-float');\r\n break;\r\n }\r\n }\r\n this.pushState('building-integer');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.pushState('casting-to-integer');\r\n if (ast.right.type === 'Literal') {\r\n const literalResult = [];\r\n this.astGeneric(ast.right, literalResult);\r\n const literalType = this.getType(ast.right);\r\n if (literalType === 'Integer') {\r\n retArr.push(literalResult.join(''));\r\n } else {\r\n throw this.astErrorOutput(`Unhandled binary expression with literal`, ast);\r\n }\r\n } else {\r\n retArr.push('int(');\r\n this.astGeneric(ast.right, retArr);\r\n retArr.push(')');\r\n }\r\n this.popState('casting-to-integer');\r\n this.popState('building-integer');\r\n break;\r\n case 'Integer & LiteralInteger':\r\n this.pushState('building-integer');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castLiteralToInteger(ast.right, retArr);\r\n this.popState('building-integer');\r\n break;\r\n\r\n case 'Number & Integer':\r\n this.pushState('building-float');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castValueToFloat(ast.right, retArr);\r\n this.popState('building-float');\r\n break;\r\n case 'Float & LiteralInteger':\r\n case 'Number & LiteralInteger':\r\n if (this.isState('in-for-loop-test')) {\r\n this.pushState('building-integer');\r\n retArr.push('int(');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(')');\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castLiteralToInteger(ast.right, retArr);\r\n this.popState('building-integer');\r\n } else {\r\n this.pushState('building-float');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castLiteralToFloat(ast.right, retArr);\r\n this.popState('building-float');\r\n }\r\n break;\r\n case 'LiteralInteger & Float':\r\n case 'LiteralInteger & Number':\r\n if (this.isState('in-for-loop-test') || this.isState('in-for-loop-init') || this.isState('casting-to-integer')) {\r\n this.pushState('building-integer');\r\n this.castLiteralToInteger(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castValueToInteger(ast.right, retArr);\r\n this.popState('building-integer');\r\n } else {\r\n this.pushState('building-float');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.pushState('casting-to-float');\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('casting-to-float');\r\n this.popState('building-float');\r\n }\r\n break;\r\n case 'LiteralInteger & Integer':\r\n this.pushState('building-integer');\r\n this.castLiteralToInteger(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-integer');\r\n break;\r\n\r\n case 'Boolean & Boolean':\r\n this.pushState('building-boolean');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-boolean');\r\n break;\r\n\r\n case 'Float & Integer':\r\n this.pushState('building-float');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castValueToFloat(ast.right, retArr);\r\n this.popState('building-float');\r\n break;\r\n\r\n default:\r\n throw this.astErrorOutput(`Unhandled binary expression between ${key}`, ast);\r\n }\r\n retArr.push(')');\r\n\r\n return retArr;\r\n }\r\n\r\n checkAndUpconvertOperator(ast, retArr) {\r\n const bitwiseResult = this.checkAndUpconvertBitwiseOperators(ast, retArr);\r\n if (bitwiseResult) {\r\n return bitwiseResult;\r\n }\r\n const upconvertableOperators = {\r\n '%': 'mod',\r\n '**': 'pow',\r\n };\r\n const foundOperator = upconvertableOperators[ast.operator];\r\n if (!foundOperator) return null;\r\n retArr.push(foundOperator);\r\n retArr.push('(');\r\n switch (this.getType(ast.left)) {\r\n case 'Integer':\r\n this.castValueToFloat(ast.left, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(ast.left, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.left, retArr);\r\n }\r\n retArr.push(',');\r\n switch (this.getType(ast.right)) {\r\n case 'Integer':\r\n this.castValueToFloat(ast.right, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(ast.right, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.right, retArr);\r\n }\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n checkAndUpconvertBitwiseOperators(ast, retArr) {\r\n const upconvertableOperators = {\r\n '&': 'bitwiseAnd',\r\n '|': 'bitwiseOr',\r\n '^': 'bitwiseXOR',\r\n '<<': 'bitwiseZeroFillLeftShift',\r\n '>>': 'bitwiseSignedRightShift',\r\n '>>>': 'bitwiseZeroFillRightShift',\r\n };\r\n const foundOperator = upconvertableOperators[ast.operator];\r\n if (!foundOperator) return null;\r\n retArr.push(foundOperator);\r\n retArr.push('(');\r\n const leftType = this.getType(ast.left);\r\n switch (leftType) {\r\n case 'Number':\r\n case 'Float':\r\n this.castValueToInteger(ast.left, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(ast.left, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.left, retArr);\r\n }\r\n retArr.push(',');\r\n const rightType = this.getType(ast.right);\r\n switch (rightType) {\r\n case 'Number':\r\n case 'Float':\r\n this.castValueToInteger(ast.right, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(ast.right, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.right, retArr);\r\n }\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n checkAndUpconvertBitwiseUnary(ast, retArr) {\r\n const upconvertableOperators = {\r\n '~': 'bitwiseNot',\r\n };\r\n const foundOperator = upconvertableOperators[ast.operator];\r\n if (!foundOperator) return null;\r\n retArr.push(foundOperator);\r\n retArr.push('(');\r\n switch (this.getType(ast.argument)) {\r\n case 'Number':\r\n case 'Float':\r\n this.castValueToInteger(ast.argument, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(ast.argument, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.argument, retArr);\r\n }\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Object} ast\r\n * @param {Array} retArr\r\n * @return {String[]}\r\n */\r\n castLiteralToInteger(ast, retArr) {\r\n this.pushState('casting-to-integer');\r\n this.astGeneric(ast, retArr);\r\n this.popState('casting-to-integer');\r\n return retArr;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Object} ast\r\n * @param {Array} retArr\r\n * @return {String[]}\r\n */\r\n castLiteralToFloat(ast, retArr) {\r\n this.pushState('casting-to-float');\r\n this.astGeneric(ast, retArr);\r\n this.popState('casting-to-float');\r\n return retArr;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Object} ast\r\n * @param {Array} retArr\r\n * @return {String[]}\r\n */\r\n castValueToInteger(ast, retArr) {\r\n this.pushState('casting-to-integer');\r\n retArr.push('int(');\r\n this.astGeneric(ast, retArr);\r\n retArr.push(')');\r\n this.popState('casting-to-integer');\r\n return retArr;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Object} ast\r\n * @param {Array} retArr\r\n * @return {String[]}\r\n */\r\n castValueToFloat(ast, retArr) {\r\n this.pushState('casting-to-float');\r\n retArr.push('float(');\r\n this.astGeneric(ast, retArr);\r\n retArr.push(')');\r\n this.popState('casting-to-float');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *identifier* expression\r\n * @param {Object} idtNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astIdentifierExpression(idtNode, retArr) {\r\n if (idtNode.type !== 'Identifier') {\r\n throw this.astErrorOutput('IdentifierExpression - not an Identifier', idtNode);\r\n }\r\n\r\n const type = this.getType(idtNode);\r\n\r\n if (idtNode.name === 'Infinity') {\r\n // https://stackoverflow.com/a/47543127/1324039\r\n retArr.push('3.402823466e+38');\r\n } else if (type === 'Boolean') {\r\n if (this.argumentNames.indexOf(idtNode.name) > -1) {\r\n retArr.push(`bool(user_${idtNode.name})`);\r\n } else {\r\n retArr.push(`user_${idtNode.name}`);\r\n }\r\n } else {\r\n retArr.push(`user_${idtNode.name}`);\r\n }\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *for-loop* expression\r\n * @param {Object} forNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed webgl string\r\n */\r\n astForStatement(forNode, retArr) {\r\n if (forNode.type !== 'ForStatement') {\r\n throw this.astErrorOutput('Invalid for statement', forNode);\r\n }\r\n\r\n const initArr = [];\r\n const testArr = [];\r\n const updateArr = [];\r\n const bodyArr = [];\r\n let isSafe = null;\r\n\r\n if (forNode.init) {\r\n this.pushState('in-for-loop-init');\r\n this.astGeneric(forNode.init, initArr);\r\n const { declarations } = forNode.init;\r\n for (let i = 0; i < declarations.length; i++) {\r\n if (declarations[i].init && declarations[i].init.type !== 'Literal') {\r\n isSafe = false;\r\n }\r\n }\r\n if (isSafe) {\r\n for (let i = 0; i < initArr.length; i++) {\r\n if (initArr[i].includes && initArr[i].includes(',')) {\r\n isSafe = false;\r\n }\r\n }\r\n }\r\n this.popState('in-for-loop-init');\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.test) {\r\n this.pushState('in-for-loop-test');\r\n this.astGeneric(forNode.test, testArr);\r\n this.popState('in-for-loop-test');\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.update) {\r\n this.astGeneric(forNode.update, updateArr);\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.body) {\r\n this.pushState('loop-body');\r\n this.astGeneric(forNode.body, bodyArr);\r\n this.popState('loop-body');\r\n }\r\n\r\n // have all parts, now make them safe\r\n if (isSafe === null) {\r\n isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test);\r\n }\r\n\r\n if (isSafe) {\r\n retArr.push(`for (${initArr.join('')};${testArr.join('')};${updateArr.join('')}){\\n`);\r\n retArr.push(bodyArr.join(''));\r\n retArr.push('}\\n');\r\n } else {\r\n const iVariableName = this.getInternalVariableName('safeI');\r\n if (initArr.length > 0) {\r\n retArr.push(initArr.join(''), ';\\n');\r\n }\r\n retArr.push(`for (int ${iVariableName}=0;${iVariableName} 0) {\r\n retArr.push(`if (!${testArr.join('')}) break;\\n`);\r\n }\r\n retArr.push(bodyArr.join(''));\r\n retArr.push(`\\n${updateArr.join('')};`);\r\n retArr.push('}\\n');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *while* loop\r\n * @param {Object} whileNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed webgl string\r\n */\r\n astWhileStatement(whileNode, retArr) {\r\n if (whileNode.type !== 'WhileStatement') {\r\n throw this.astErrorOutput('Invalid while statement', whileNode);\r\n }\r\n\r\n const iVariableName = this.getInternalVariableName('safeI');\r\n retArr.push(`for (int ${iVariableName}=0;${iVariableName} i + 1) {\r\n movingDefaultToEnd = true;\r\n this.astGeneric(cases[i].consequent, defaultResult);\r\n continue;\r\n } else {\r\n retArr.push(' else {\\n');\r\n }\r\n } else {\r\n // all others\r\n if (i === 0 || !pastFirstIf) {\r\n pastFirstIf = true;\r\n retArr.push(`if (${varName} == `);\r\n } else {\r\n if (fallingThrough) {\r\n retArr.push(`${varName} == `);\r\n fallingThrough = false;\r\n } else {\r\n retArr.push(` else if (${varName} == `);\r\n }\r\n }\r\n if (type === 'Integer') {\r\n const testType = this.getType(cases[i].test);\r\n switch (testType) {\r\n case 'Number':\r\n case 'Float':\r\n this.castValueToInteger(cases[i].test, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(cases[i].test, retArr);\r\n break;\r\n }\r\n } else if (type === 'Float') {\r\n const testType = this.getType(cases[i].test);\r\n switch (testType) {\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(cases[i].test, retArr);\r\n break;\r\n case 'Integer':\r\n this.castValueToFloat(cases[i].test, retArr);\r\n break;\r\n }\r\n } else {\r\n throw new Error('unhanlded');\r\n }\r\n if (!cases[i].consequent || cases[i].consequent.length === 0) {\r\n fallingThrough = true;\r\n retArr.push(' || ');\r\n continue;\r\n }\r\n retArr.push(`) {\\n`);\r\n }\r\n this.astGeneric(cases[i].consequent, retArr);\r\n retArr.push('\\n}');\r\n }\r\n if (movingDefaultToEnd) {\r\n retArr.push(' else {');\r\n retArr.push(defaultResult.join(''));\r\n retArr.push('}');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *This* expression\r\n * @param {Object} tNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astThisExpression(tNode, retArr) {\r\n retArr.push('this');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Member* Expression\r\n * @param {Object} mNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astMemberExpression(mNode, retArr) {\r\n const {\r\n property,\r\n name,\r\n signature,\r\n origin,\r\n type,\r\n xProperty,\r\n yProperty,\r\n zProperty\r\n } = this.getMemberExpressionDetails(mNode);\r\n switch (signature) {\r\n case 'value.thread.value':\r\n case 'this.thread.value':\r\n if (name !== 'x' && name !== 'y' && name !== 'z') {\r\n throw this.astErrorOutput('Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`', mNode);\r\n }\r\n retArr.push(`threadId.${name}`);\r\n return retArr;\r\n case 'this.output.value':\r\n if (this.dynamicOutput) {\r\n switch (name) {\r\n case 'x':\r\n if (this.isState('casting-to-float')) {\r\n retArr.push('float(uOutputDim.x)');\r\n } else {\r\n retArr.push('uOutputDim.x');\r\n }\r\n break;\r\n case 'y':\r\n if (this.isState('casting-to-float')) {\r\n retArr.push('float(uOutputDim.y)');\r\n } else {\r\n retArr.push('uOutputDim.y');\r\n }\r\n break;\r\n case 'z':\r\n if (this.isState('casting-to-float')) {\r\n retArr.push('float(uOutputDim.z)');\r\n } else {\r\n retArr.push('uOutputDim.z');\r\n }\r\n break;\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n }\r\n } else {\r\n switch (name) {\r\n case 'x':\r\n if (this.isState('casting-to-integer')) {\r\n retArr.push(this.output[0]);\r\n } else {\r\n retArr.push(this.output[0], '.0');\r\n }\r\n break;\r\n case 'y':\r\n if (this.isState('casting-to-integer')) {\r\n retArr.push(this.output[1]);\r\n } else {\r\n retArr.push(this.output[1], '.0');\r\n }\r\n break;\r\n case 'z':\r\n if (this.isState('casting-to-integer')) {\r\n retArr.push(this.output[2]);\r\n } else {\r\n retArr.push(this.output[2], '.0');\r\n }\r\n break;\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n }\r\n }\r\n return retArr;\r\n case 'value':\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n case 'value[]':\r\n case 'value[][]':\r\n case 'value[][][]':\r\n case 'value[][][][]':\r\n case 'value.value':\r\n if (origin === 'Math') {\r\n retArr.push(Math[name]);\r\n return retArr;\r\n }\r\n switch (property) {\r\n case 'r':\r\n retArr.push(`user_${ name }.r`);\r\n return retArr;\r\n case 'g':\r\n retArr.push(`user_${ name }.g`);\r\n return retArr;\r\n case 'b':\r\n retArr.push(`user_${ name }.b`);\r\n return retArr;\r\n case 'a':\r\n retArr.push(`user_${ name }.a`);\r\n return retArr;\r\n }\r\n break;\r\n case 'this.constants.value':\r\n if (typeof xProperty === 'undefined') {\r\n switch (type) {\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n retArr.push(`constants_${ name }`);\r\n return retArr;\r\n }\r\n }\r\n case 'this.constants.value[]':\r\n case 'this.constants.value[][]':\r\n case 'this.constants.value[][][]':\r\n case 'this.constants.value[][][][]':\r\n break;\r\n case 'fn()[]':\r\n this.astCallExpression(mNode.object, retArr);\r\n retArr.push('[');\r\n retArr.push(this.memberExpressionPropertyMarkup(property));\r\n retArr.push(']');\r\n return retArr;\r\n case '[][]':\r\n this.astArrayExpression(mNode.object, retArr);\r\n retArr.push('[');\r\n retArr.push(this.memberExpressionPropertyMarkup(property));\r\n retArr.push(']');\r\n return retArr;\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n }\r\n\r\n if (mNode.computed === false) {\r\n // handle simple types\r\n switch (type) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n case 'Boolean':\r\n retArr.push(`${origin}_${name}`);\r\n return retArr;\r\n }\r\n }\r\n\r\n // handle more complex types\r\n // argument may have come from a parent\r\n const markupName = `${origin}_${name}`;\r\n\r\n switch (type) {\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n // Get from local vec4\r\n this.astGeneric(mNode.object, retArr);\r\n retArr.push('[');\r\n retArr.push(this.memberExpressionPropertyMarkup(xProperty));\r\n retArr.push(']');\r\n break;\r\n case 'HTMLImageArray':\r\n retArr.push(`getImage3D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'ArrayTexture(1)':\r\n retArr.push(`getFloatFromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'Array1D(2)':\r\n case 'Array2D(2)':\r\n case 'Array3D(2)':\r\n retArr.push(`getMemoryOptimizedVec2(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'ArrayTexture(2)':\r\n retArr.push(`getVec2FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'Array1D(3)':\r\n case 'Array2D(3)':\r\n case 'Array3D(3)':\r\n retArr.push(`getMemoryOptimizedVec3(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'ArrayTexture(3)':\r\n retArr.push(`getVec3FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'Array1D(4)':\r\n case 'Array2D(4)':\r\n case 'Array3D(4)':\r\n retArr.push(`getMemoryOptimizedVec4(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'ArrayTexture(4)':\r\n case 'HTMLImage':\r\n case 'HTMLVideo':\r\n retArr.push(`getVec4FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'NumberTexture':\r\n case 'Array':\r\n case 'Array2D':\r\n case 'Array3D':\r\n case 'Array4D':\r\n case 'Input':\r\n case 'Number':\r\n case 'Float':\r\n case 'Integer':\r\n if (this.precision === 'single') {\r\n // bitRatio is always 4 here, javascript doesn't yet have 8 or 16 bit support\r\n // TODO: make 8 or 16 bit work anyway!\r\n retArr.push(`getMemoryOptimized32(${markupName}, ${markupName}Size, ${markupName}Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n } else {\r\n const bitRatio = (origin === 'user' ?\r\n this.lookupFunctionArgumentBitRatio(this.name, name) :\r\n this.constantBitRatios[name]\r\n );\r\n switch (bitRatio) {\r\n case 1:\r\n retArr.push(`get8(${markupName}, ${markupName}Size, ${markupName}Dim, `);\r\n break;\r\n case 2:\r\n retArr.push(`get16(${markupName}, ${markupName}Size, ${markupName}Dim, `);\r\n break;\r\n case 4:\r\n case 0:\r\n retArr.push(`get32(${markupName}, ${markupName}Size, ${markupName}Dim, `);\r\n break;\r\n default:\r\n throw new Error(`unhandled bit ratio of ${bitRatio}`);\r\n }\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n }\r\n break;\r\n case 'MemoryOptimizedNumberTexture':\r\n retArr.push(`getMemoryOptimized32(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n default:\r\n throw new Error(`unhandled member expression \"${ type }\"`);\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *call* expression\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astCallExpression(ast, retArr) {\r\n if (!ast.callee) {\r\n throw this.astErrorOutput('Unknown CallExpression', ast);\r\n }\r\n\r\n let functionName = null;\r\n const isMathFunction = this.isAstMathFunction(ast);\r\n\r\n // Its a math operator or this.something(), remove the prefix\r\n if (isMathFunction || (ast.callee.object && ast.callee.object.type === 'ThisExpression')) {\r\n functionName = ast.callee.property.name;\r\n }\r\n // Issue #212, BABEL!\r\n else if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[0].type === 'Literal' && !isNaN(ast.callee.expressions[0].raw)) {\r\n functionName = ast.callee.expressions[1].property.name;\r\n } else {\r\n functionName = ast.callee.name;\r\n }\r\n\r\n if (!functionName) {\r\n throw this.astErrorOutput(`Unhandled function, couldn't find name`, ast);\r\n }\r\n\r\n // if this if grows to more than one, lets use a switch\r\n if (functionName === 'atan2') {\r\n functionName = 'atan';\r\n }\r\n\r\n // Register the function into the called registry\r\n if (this.calledFunctions.indexOf(functionName) < 0) {\r\n this.calledFunctions.push(functionName);\r\n }\r\n\r\n if (functionName === 'random' && this.plugins && this.plugins.length > 0) {\r\n for (let i = 0; i < this.plugins.length; i++) {\r\n const plugin = this.plugins[i];\r\n if (plugin.functionMatch === 'Math.random()' && plugin.functionReplace) {\r\n retArr.push(plugin.functionReplace);\r\n return retArr;\r\n }\r\n }\r\n }\r\n\r\n // track the function was called\r\n if (this.onFunctionCall) {\r\n this.onFunctionCall(this.name, functionName, ast.arguments);\r\n }\r\n\r\n // Call the function\r\n retArr.push(functionName);\r\n\r\n // Open arguments space\r\n retArr.push('(');\r\n\r\n // Add the arguments\r\n if (isMathFunction) {\r\n for (let i = 0; i < ast.arguments.length; ++i) {\r\n const argument = ast.arguments[i];\r\n const argumentType = this.getType(argument);\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n\r\n switch (argumentType) {\r\n case 'Integer':\r\n this.castValueToFloat(argument, retArr);\r\n break;\r\n default:\r\n this.astGeneric(argument, retArr);\r\n break;\r\n }\r\n }\r\n } else {\r\n const targetTypes = this.lookupFunctionArgumentTypes(functionName) || [];\r\n for (let i = 0; i < ast.arguments.length; ++i) {\r\n const argument = ast.arguments[i];\r\n let targetType = targetTypes[i];\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n const argumentType = this.getType(argument);\r\n if (!targetType) {\r\n this.triggerImplyArgumentType(functionName, i, argumentType, this);\r\n targetType = argumentType;\r\n }\r\n switch (argumentType) {\r\n case 'Number':\r\n case 'Float':\r\n if (targetType === 'Integer') {\r\n retArr.push('int(');\r\n this.astGeneric(argument, retArr);\r\n retArr.push(')');\r\n continue;\r\n } else if (targetType === 'Number' || targetType === 'Float') {\r\n this.astGeneric(argument, retArr);\r\n continue;\r\n } else if (targetType === 'LiteralInteger') {\r\n this.castLiteralToFloat(argument, retArr);\r\n continue;\r\n }\r\n break;\r\n case 'Integer':\r\n if (targetType === 'Number' || targetType === 'Float') {\r\n retArr.push('float(');\r\n this.astGeneric(argument, retArr);\r\n retArr.push(')');\r\n continue;\r\n } else if (targetType === 'Integer') {\r\n this.astGeneric(argument, retArr);\r\n continue;\r\n }\r\n break;\r\n case 'LiteralInteger':\r\n if (targetType === 'Integer') {\r\n this.castLiteralToInteger(argument, retArr);\r\n continue;\r\n } else if (targetType === 'Number' || targetType === 'Float') {\r\n this.castLiteralToFloat(argument, retArr);\r\n continue;\r\n } else if (targetType === 'LiteralInteger') {\r\n this.astGeneric(argument, retArr);\r\n continue;\r\n }\r\n break;\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n if (targetType === argumentType) {\r\n if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast);\r\n this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i);\r\n retArr.push(`user_${argument.name}`);\r\n continue;\r\n }\r\n break;\r\n case 'HTMLImage':\r\n case 'HTMLImageArray':\r\n case 'HTMLVideo':\r\n case 'ArrayTexture(1)':\r\n case 'ArrayTexture(2)':\r\n case 'ArrayTexture(3)':\r\n case 'ArrayTexture(4)':\r\n case 'Array':\r\n case 'Input':\r\n if (targetType === argumentType) {\r\n if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast);\r\n this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i);\r\n retArr.push(`user_${argument.name},user_${argument.name}Size,user_${argument.name}Dim`);\r\n continue;\r\n }\r\n break;\r\n }\r\n throw this.astErrorOutput(`Unhandled argument combination of ${ argumentType } and ${ targetType } for argument named \"${ argument.name }\"`, ast);\r\n }\r\n }\r\n // Close arguments space\r\n retArr.push(')');\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Array* Expression\r\n * @param {Object} arrNode - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astArrayExpression(arrNode, retArr) {\r\n const arrLen = arrNode.elements.length;\r\n\r\n retArr.push('vec' + arrLen + '(');\r\n for (let i = 0; i < arrLen; ++i) {\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n const subNode = arrNode.elements[i];\r\n this.astGeneric(subNode, retArr)\r\n }\r\n retArr.push(')');\r\n\r\n return retArr;\r\n }\r\n\r\n memberExpressionXYZ(x, y, z, retArr) {\r\n if (z) {\r\n retArr.push(this.memberExpressionPropertyMarkup(z), ', ');\r\n } else {\r\n retArr.push('0, ');\r\n }\r\n if (y) {\r\n retArr.push(this.memberExpressionPropertyMarkup(y), ', ');\r\n } else {\r\n retArr.push('0, ');\r\n }\r\n retArr.push(this.memberExpressionPropertyMarkup(x));\r\n return retArr;\r\n }\r\n\r\n memberExpressionPropertyMarkup(property) {\r\n if (!property) {\r\n throw new Error('Property not set');\r\n }\r\n const type = this.getType(property);\r\n const result = [];\r\n switch (type) {\r\n case 'Number':\r\n case 'Float':\r\n this.castValueToInteger(property, result);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(property, result);\r\n break;\r\n default:\r\n this.astGeneric(property, result);\r\n }\r\n return result.join('');\r\n }\r\n}\r\n\r\nconst typeMap = {\r\n 'Array': 'sampler2D',\r\n 'Array(2)': 'vec2',\r\n 'Array(3)': 'vec3',\r\n 'Array(4)': 'vec4',\r\n 'Array2D': 'sampler2D',\r\n 'Array3D': 'sampler2D',\r\n 'Boolean': 'bool',\r\n 'Float': 'float',\r\n 'Input': 'sampler2D',\r\n 'Integer': 'int',\r\n 'Number': 'float',\r\n 'LiteralInteger': 'float',\r\n 'NumberTexture': 'sampler2D',\r\n 'MemoryOptimizedNumberTexture': 'sampler2D',\r\n 'ArrayTexture(1)': 'sampler2D',\r\n 'ArrayTexture(2)': 'sampler2D',\r\n 'ArrayTexture(3)': 'sampler2D',\r\n 'ArrayTexture(4)': 'sampler2D',\r\n 'HTMLVideo': 'sampler2D',\r\n 'HTMLImage': 'sampler2D',\r\n 'HTMLImageArray': 'sampler2DArray',\r\n};\r\n\r\nconst operatorMap = {\r\n '===': '==',\r\n '!==': '!='\r\n};\r\n","const source = `\r\n\r\nuniform highp float triangle_noise_seed;\r\nhighp float triangle_noise_shift = 0.000001;\r\n\r\n//https://www.shadertoy.com/view/4t2SDh\r\n//note: uniformly distributed, normalized rand, [0;1[\r\nfloat nrand( vec2 n )\r\n{\r\n return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453);\r\n}\r\n//note: remaps v to [0;1] in interval [a;b]\r\nfloat remap( float a, float b, float v )\r\n{\r\n return clamp( (v-a) / (b-a), 0.0, 1.0 );\r\n}\r\n\r\nfloat n4rand( vec2 n )\r\n{\r\n float t = fract( triangle_noise_seed + triangle_noise_shift );\r\n float nrnd0 = nrand( n + 0.07*t );\r\n float nrnd1 = nrand( n + 0.11*t );\r\n float nrnd2 = nrand( n + 0.13*t );\r\n float nrnd3 = nrand( n + 0.17*t );\r\n float result = (nrnd0+nrnd1+nrnd2+nrnd3) / 4.0;\r\n triangle_noise_shift = result + 0.000001;\r\n return result;\r\n}`;\r\n\r\nconst name = 'triangle-noise-noise';\r\n\r\nconst functionMatch = 'Math.random()';\r\n\r\nconst functionReplace = 'n4rand(vTexCoord)';\r\n\r\nconst functionReturnType = 'Number';\r\n\r\nconst onBeforeRun = (kernel) => {\r\n kernel.setUniform1f('triangle_noise_seed', Math.random());\r\n};\r\n\r\n/**\r\n * @type IPlugin\r\n */\r\nexport default {\r\n name,\r\n onBeforeRun,\r\n functionMatch,\r\n functionReplace,\r\n functionReturnType,\r\n source\r\n};\r\n","// language=GLSL\r\nexport const fragmentShader = `__HEADER__;\r\n__FLOAT_TACTIC_DECLARATION__;\r\n__INT_TACTIC_DECLARATION__;\r\n__SAMPLER_2D_TACTIC_DECLARATION__;\r\n\r\nconst int LOOP_MAX = __LOOP_MAX__;\r\n\r\n__PLUGINS__;\r\n__CONSTANTS__;\r\n\r\nvarying vec2 vTexCoord;\r\n\r\nvec4 round(vec4 x) {\r\n return floor(x + 0.5);\r\n}\r\n\r\nfloat round(float x) {\r\n return floor(x + 0.5);\r\n}\r\n\r\nconst int BIT_COUNT = 32;\r\nint modi(int x, int y) {\r\n return x - y * (x / y);\r\n}\r\n\r\nint bitwiseOr(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 || b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseXOR(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 || b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseAnd(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 && b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseNot(int a) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (modi(a, 2) == 0) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n n = n * 2;\r\n }\r\n return result;\r\n}\r\nint bitwiseZeroFillLeftShift(int n, int shift) {\r\n int maxBytes = BIT_COUNT;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (maxBytes >= n) {\r\n break;\r\n }\r\n maxBytes *= 2;\r\n }\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= shift) {\r\n break;\r\n }\r\n n *= 2;\r\n }\r\n\r\n int result = 0;\r\n int byteVal = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= maxBytes) break;\r\n if (modi(n, 2) > 0) { result += byteVal; }\r\n n = int(n / 2);\r\n byteVal *= 2;\r\n }\r\n return result;\r\n}\r\n\r\nint bitwiseSignedRightShift(int num, int shifts) {\r\n return int(floor(float(num) / pow(2.0, float(shifts))));\r\n}\r\n\r\nint bitwiseZeroFillRightShift(int n, int shift) {\r\n int maxBytes = BIT_COUNT;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (maxBytes >= n) {\r\n break;\r\n }\r\n maxBytes *= 2;\r\n }\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= shift) {\r\n break;\r\n }\r\n n /= 2;\r\n }\r\n int result = 0;\r\n int byteVal = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= maxBytes) break;\r\n if (modi(n, 2) > 0) { result += byteVal; }\r\n n = int(n / 2);\r\n byteVal *= 2;\r\n }\r\n return result;\r\n}\r\n\r\nvec2 integerMod(vec2 x, float y) {\r\n vec2 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nvec3 integerMod(vec3 x, float y) {\r\n vec3 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nvec4 integerMod(vec4 x, vec4 y) {\r\n vec4 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nfloat integerMod(float x, float y) {\r\n float res = floor(mod(x, y));\r\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\r\n}\r\n\r\nint integerMod(int x, int y) {\r\n return x - (y * int(x / y));\r\n}\r\n\r\n__DIVIDE_WITH_INTEGER_CHECK__;\r\n\r\n// Here be dragons!\r\n// DO NOT OPTIMIZE THIS CODE\r\n// YOU WILL BREAK SOMETHING ON SOMEBODY\\'S MACHINE\r\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\r\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\r\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\r\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\r\nfloat decode32(vec4 texel) {\r\n __DECODE32_ENDIANNESS__;\r\n texel *= 255.0;\r\n vec2 gte128;\r\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\r\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\r\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\r\n float res = exp2(round(exponent));\r\n texel.b = texel.b - 128.0 * gte128.x;\r\n res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;\r\n res *= gte128.y * -2.0 + 1.0;\r\n return res;\r\n}\r\n\r\nfloat decode16(vec4 texel, int index) {\r\n int channel = integerMod(index, 2);\r\n if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0;\r\n if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0;\r\n return 0.0;\r\n}\r\n\r\nfloat decode8(vec4 texel, int index) {\r\n int channel = integerMod(index, 4);\r\n if (channel == 0) return texel.r * 255.0;\r\n if (channel == 1) return texel.g * 255.0;\r\n if (channel == 2) return texel.b * 255.0;\r\n if (channel == 3) return texel.a * 255.0;\r\n return 0.0;\r\n}\r\n\r\nvec4 legacyEncode32(float f) {\r\n float F = abs(f);\r\n float sign = f < 0.0 ? 1.0 : 0.0;\r\n float exponent = floor(log2(F));\r\n float mantissa = (exp2(-exponent) * F);\r\n // exponent += floor(log2(mantissa));\r\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\r\n texel.rg = integerMod(texel.rg, 256.0);\r\n texel.b = integerMod(texel.b, 128.0);\r\n texel.a = exponent*0.5 + 63.5;\r\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\r\n texel = floor(texel);\r\n texel *= 0.003921569; // 1/255\r\n __ENCODE32_ENDIANNESS__;\r\n return texel;\r\n}\r\n\r\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\r\nvec4 encode32(float value) {\r\n if (value == 0.0) return vec4(0, 0, 0, 0);\r\n\r\n float exponent;\r\n float mantissa;\r\n vec4 result;\r\n float sgn;\r\n\r\n sgn = step(0.0, -value);\r\n value = abs(value);\r\n\r\n exponent = floor(log2(value));\r\n\r\n mantissa = value*pow(2.0, -exponent)-1.0;\r\n exponent = exponent+127.0;\r\n result = vec4(0,0,0,0);\r\n\r\n result.a = floor(exponent/2.0);\r\n exponent = exponent - result.a*2.0;\r\n result.a = result.a + 128.0*sgn;\r\n\r\n result.b = floor(mantissa * 128.0);\r\n mantissa = mantissa - result.b / 128.0;\r\n result.b = result.b + exponent*128.0;\r\n\r\n result.g = floor(mantissa*32768.0);\r\n mantissa = mantissa - result.g/32768.0;\r\n\r\n result.r = floor(mantissa*8388608.0);\r\n return result/255.0;\r\n}\r\n// Dragons end here\r\n\r\nint index;\r\nivec3 threadId;\r\n\r\nivec3 indexTo3D(int idx, ivec3 texDim) {\r\n int z = int(idx / (texDim.x * texDim.y));\r\n idx -= z * int(texDim.x * texDim.y);\r\n int y = int(idx / texDim.x);\r\n int x = int(integerMod(idx, texDim.x));\r\n return ivec3(x, y, z);\r\n}\r\n\r\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize));\r\n return decode32(texel);\r\n}\r\n\r\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x * 2;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y));\r\n return decode16(texel, index);\r\n}\r\n\r\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x * 4;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y));\r\n return decode8(texel, index);\r\n}\r\n\r\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int channel = integerMod(index, 4);\r\n index = index / 4;\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize));\r\n if (channel == 0) return texel.r;\r\n if (channel == 1) return texel.g;\r\n if (channel == 2) return texel.b;\r\n if (channel == 3) return texel.a;\r\n return 0.0;\r\n}\r\n\r\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n return texture2D(tex, st / vec2(texSize));\r\n}\r\n\r\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return result[0];\r\n}\r\n\r\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return vec2(result[0], result[1]);\r\n}\r\n\r\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + (texDim.x * (y + (texDim.y * z)));\r\n int channel = integerMod(index, 2);\r\n index = index / 2;\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize));\r\n if (channel == 0) return vec2(texel.r, texel.g);\r\n if (channel == 1) return vec2(texel.b, texel.a);\r\n return vec2(0.0, 0.0);\r\n}\r\n\r\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return vec3(result[0], result[1], result[2]);\r\n}\r\n\r\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\r\n int vectorIndex = fieldIndex / 4;\r\n int vectorOffset = fieldIndex - vectorIndex * 4;\r\n int readY = vectorIndex / texSize.x;\r\n int readX = vectorIndex - readY * texSize.x;\r\n vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\r\n\r\n if (vectorOffset == 0) {\r\n return tex1.xyz;\r\n } else if (vectorOffset == 1) {\r\n return tex1.yzw;\r\n } else {\r\n readX++;\r\n if (readX >= texSize.x) {\r\n readX = 0;\r\n readY++;\r\n }\r\n vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize));\r\n if (vectorOffset == 2) {\r\n return vec3(tex1.z, tex1.w, tex2.x);\r\n } else {\r\n return vec3(tex1.w, tex2.x, tex2.y);\r\n }\r\n }\r\n}\r\n\r\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n return getImage2D(tex, texSize, texDim, z, y, x);\r\n}\r\n\r\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int channel = integerMod(index, 2);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize));\r\n return vec4(texel.r, texel.g, texel.b, texel.a);\r\n}\r\n\r\nvec4 actualColor;\r\nvoid color(float r, float g, float b, float a) {\r\n actualColor = vec4(r,g,b,a);\r\n}\r\n\r\nvoid color(float r, float g, float b) {\r\n color(r,g,b,1.0);\r\n}\r\n\r\nvoid color(sampler2D image) {\r\n actualColor = texture2D(image, vTexCoord);\r\n}\r\n\r\n__INJECTED_NATIVE__;\r\n__MAIN_CONSTANTS__;\r\n__MAIN_ARGUMENTS__;\r\n__KERNEL__;\r\n\r\nvoid main(void) {\r\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\r\n __MAIN_RESULT__;\r\n}`;\r\n","// language=GLSL\r\nexport const vertexShader = `__FLOAT_TACTIC_DECLARATION__;\r\n__INT_TACTIC_DECLARATION__;\r\n__SAMPLER_2D_TACTIC_DECLARATION__;\r\n\r\nattribute vec2 aPos;\r\nattribute vec2 aTexCoord;\r\n\r\nvarying vec2 vTexCoord;\r\nuniform vec2 ratio;\r\n\r\nvoid main(void) {\r\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\r\n vTexCoord = aTexCoord;\r\n}`;\r\n","/**\n *\n * @param {WebGLRenderingContext} gl\n * @param {IGLWiretapOptions} [options]\n * @returns {GLWiretapProxy}\n */\nfunction glWiretap(gl, options = {}) {\n const {\n contextName = 'gl',\n throwGetError,\n useTrackablePrimitives,\n readPixelsFile,\n recording = [],\n variables = {},\n onReadPixels,\n onUnrecognizedArgumentLookup,\n } = options;\n const proxy = new Proxy(gl, { get: listen });\n const contextVariables = [];\n const entityNames = {};\n let imageCount = 0;\n let indent = '';\n let readPixelsVariableName;\n return proxy;\n function listen(obj, property) {\n switch (property) {\n case 'addComment': return addComment;\n case 'checkThrowError': return checkThrowError;\n case 'getReadPixelsVariableName': return readPixelsVariableName;\n case 'insertVariable': return insertVariable;\n case 'reset': return reset;\n case 'setIndent': return setIndent;\n case 'toString': return toString;\n case 'getContextVariableName': return getContextVariableName;\n }\n if (typeof gl[property] === 'function') {\n return function() { // need arguments from this, fyi\n switch (property) {\n case 'getError':\n if (throwGetError) {\n recording.push(`${indent}if (${contextName}.getError() !== ${contextName}.NONE) throw new Error('error');`);\n } else {\n recording.push(`${indent}${contextName}.getError();`); // flush out errors\n }\n return gl.getError();\n case 'getExtension': {\n const variableName = `${contextName}Variables${contextVariables.length}`;\n recording.push(`${indent}const ${variableName} = ${contextName}.getExtension('${arguments[0]}');`);\n const extension = gl.getExtension(arguments[0]);\n if (extension && typeof extension === 'object') {\n const tappedExtension = glExtensionWiretap(extension, {\n getEntity,\n useTrackablePrimitives,\n recording,\n contextName: variableName,\n contextVariables,\n variables,\n indent,\n onUnrecognizedArgumentLookup,\n });\n contextVariables.push(tappedExtension);\n return tappedExtension;\n } else {\n contextVariables.push(null);\n }\n return extension;\n }\n case 'readPixels':\n const i = contextVariables.indexOf(arguments[6]);\n let targetVariableName;\n if (i === -1) {\n const variableName = getVariableName(arguments[6]);\n if (variableName) {\n targetVariableName = variableName;\n recording.push(`${indent}${variableName}`);\n } else {\n targetVariableName = `${contextName}Variable${contextVariables.length}`;\n contextVariables.push(arguments[6]);\n recording.push(`${indent}const ${targetVariableName} = new ${arguments[6].constructor.name}(${arguments[6].length});`);\n }\n } else {\n targetVariableName = `${contextName}Variable${i}`;\n }\n readPixelsVariableName = targetVariableName;\n const argumentAsStrings = [\n arguments[0],\n arguments[1],\n arguments[2],\n arguments[3],\n getEntity(arguments[4]),\n getEntity(arguments[5]),\n targetVariableName\n ];\n recording.push(`${indent}${contextName}.readPixels(${argumentAsStrings.join(', ')});`);\n if (readPixelsFile) {\n writePPM(arguments[2], arguments[3]);\n }\n if (onReadPixels) {\n onReadPixels(targetVariableName, argumentAsStrings);\n }\n return gl.readPixels.apply(gl, arguments);\n case 'drawBuffers':\n recording.push(`${indent}${contextName}.drawBuffers([${argumentsToString(arguments[0], { contextName, contextVariables, getEntity, addVariable, variables, onUnrecognizedArgumentLookup } )}]);`);\n return gl.drawBuffers(arguments[0]);\n }\n let result = gl[property].apply(gl, arguments);\n switch (typeof result) {\n case 'undefined':\n recording.push(`${indent}${methodCallToString(property, arguments)};`);\n return;\n case 'number':\n case 'boolean':\n if (useTrackablePrimitives && contextVariables.indexOf(trackablePrimitive(result)) === -1) {\n recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);\n contextVariables.push(result = trackablePrimitive(result));\n break;\n }\n default:\n if (result === null) {\n recording.push(`${methodCallToString(property, arguments)};`);\n } else {\n recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);\n }\n\n contextVariables.push(result);\n }\n return result;\n }\n }\n entityNames[gl[property]] = property;\n return gl[property];\n }\n function toString() {\n return recording.join('\\n');\n }\n function reset() {\n while (recording.length > 0) {\n recording.pop();\n }\n }\n function insertVariable(name, value) {\n variables[name] = value;\n }\n function getEntity(value) {\n const name = entityNames[value];\n if (name) {\n return contextName + '.' + name;\n }\n return value;\n }\n function setIndent(spaces) {\n indent = ' '.repeat(spaces);\n }\n function addVariable(value, source) {\n const variableName = `${contextName}Variable${contextVariables.length}`;\n recording.push(`${indent}const ${variableName} = ${source};`);\n contextVariables.push(value);\n return variableName;\n }\n function writePPM(width, height) {\n const sourceVariable = `${contextName}Variable${contextVariables.length}`;\n const imageVariable = `imageDatum${imageCount}`;\n recording.push(`${indent}let ${imageVariable} = [\"P3\\\\n# ${readPixelsFile}.ppm\\\\n\", ${width}, ' ', ${height}, \"\\\\n255\\\\n\"].join(\"\");`);\n recording.push(`${indent}for (let i = 0; i < ${imageVariable}.length; i += 4) {`);\n recording.push(`${indent} ${imageVariable} += ${sourceVariable}[i] + ' ' + ${sourceVariable}[i + 1] + ' ' + ${sourceVariable}[i + 2] + ' ';`);\n recording.push(`${indent}}`);\n recording.push(`${indent}if (typeof require !== \"undefined\") {`);\n recording.push(`${indent} require('fs').writeFileSync('./${readPixelsFile}.ppm', ${imageVariable});`);\n recording.push(`${indent}}`);\n imageCount++;\n }\n function addComment(value) {\n recording.push(`${indent}// ${value}`);\n }\n function checkThrowError() {\n recording.push(`${indent}(() => {\n${indent}const error = ${contextName}.getError();\n${indent}if (error !== ${contextName}.NONE) {\n${indent} const names = Object.getOwnPropertyNames(gl);\n${indent} for (let i = 0; i < names.length; i++) {\n${indent} const name = names[i];\n${indent} if (${contextName}[name] === error) {\n${indent} throw new Error('${contextName} threw ' + name);\n${indent} }\n${indent} }\n${indent}}\n${indent}})();`);\n }\n function methodCallToString(method, args) {\n return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`;\n }\n\n function getVariableName(value) {\n if (variables) {\n for (const name in variables) {\n if (variables[name] === value) {\n return name;\n }\n }\n }\n return null;\n }\n\n function getContextVariableName(value) {\n const i = contextVariables.indexOf(value);\n if (i !== -1) {\n return `${contextName}Variable${i}`;\n }\n return null;\n }\n}\n\n/**\n *\n * @param extension\n * @param {IGLExtensionWiretapOptions} options\n * @returns {*}\n */\nfunction glExtensionWiretap(extension, options) {\n const proxy = new Proxy(extension, { get: listen });\n const extensionEntityNames = {};\n const {\n contextName,\n contextVariables,\n getEntity,\n useTrackablePrimitives,\n recording,\n variables,\n indent,\n onUnrecognizedArgumentLookup,\n } = options;\n return proxy;\n function listen(obj, property) {\n if (typeof obj[property] === 'function') {\n return function() {\n switch (property) {\n case 'drawBuffersWEBGL':\n recording.push(`${indent}${contextName}.drawBuffersWEBGL([${argumentsToString(arguments[0], { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })}]);`);\n return extension.drawBuffersWEBGL(arguments[0]);\n }\n let result = extension[property].apply(extension, arguments);\n switch (typeof result) {\n case 'undefined':\n recording.push(`${indent}${methodCallToString(property, arguments)};`);\n return;\n case 'number':\n case 'boolean':\n if (useTrackablePrimitives && contextVariables.indexOf(trackablePrimitive(result)) === -1) {\n recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);\n contextVariables.push(result = trackablePrimitive(result));\n } else {\n recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);\n contextVariables.push(result);\n }\n break;\n default:\n if (result === null) {\n recording.push(`${methodCallToString(property, arguments)};`);\n } else {\n recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);\n }\n contextVariables.push(result);\n }\n return result;\n };\n }\n extensionEntityNames[extension[property]] = property;\n return extension[property];\n }\n\n function getExtensionEntity(value) {\n if (extensionEntityNames.hasOwnProperty(value)) {\n return `${contextName}.${extensionEntityNames[value]}`;\n }\n return getEntity(value);\n }\n\n function methodCallToString(method, args) {\n return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`;\n }\n\n function addVariable(value, source) {\n const variableName = `${contextName}Variable${contextVariables.length}`;\n contextVariables.push(value);\n recording.push(`${indent}const ${variableName} = ${source};`);\n return variableName;\n }\n}\n\nfunction argumentsToString(args, options) {\n const { variables, onUnrecognizedArgumentLookup } = options;\n return (Array.from(args).map((arg) => {\n const variableName = getVariableName(arg);\n if (variableName) {\n return variableName;\n }\n return argumentToString(arg, options);\n }).join(', '));\n\n function getVariableName(value) {\n if (variables) {\n for (const name in variables) {\n if (!variables.hasOwnProperty(name)) continue;\n if (variables[name] === value) {\n return name;\n }\n }\n }\n if (onUnrecognizedArgumentLookup) {\n return onUnrecognizedArgumentLookup(value);\n }\n return null;\n }\n}\n\nfunction argumentToString(arg, options) {\n const { contextName, contextVariables, getEntity, addVariable, onUnrecognizedArgumentLookup } = options;\n if (typeof arg === 'undefined') {\n return 'undefined';\n }\n if (arg === null) {\n return 'null';\n }\n const i = contextVariables.indexOf(arg);\n if (i > -1) {\n return `${contextName}Variable${i}`;\n }\n switch (arg.constructor.name) {\n case 'String':\n const hasLines = /\\n/.test(arg);\n const hasSingleQuotes = /'/.test(arg);\n const hasDoubleQuotes = /\"/.test(arg);\n if (hasLines) {\n return '`' + arg + '`';\n } else if (hasSingleQuotes && !hasDoubleQuotes) {\n return '\"' + arg + '\"';\n } else if (!hasSingleQuotes && hasDoubleQuotes) {\n return \"'\" + arg + \"'\";\n } else {\n return '\\'' + arg + '\\'';\n }\n case 'Number': return getEntity(arg);\n case 'Boolean': return getEntity(arg);\n case 'Array':\n return addVariable(arg, `new ${arg.constructor.name}([${Array.from(arg).join(',')}])`);\n case 'Float32Array':\n case 'Uint8Array':\n case 'Uint16Array':\n case 'Int32Array':\n return addVariable(arg, `new ${arg.constructor.name}(${JSON.stringify(Array.from(arg))})`);\n default:\n if (onUnrecognizedArgumentLookup) {\n const instantiationString = onUnrecognizedArgumentLookup(arg);\n if (instantiationString) {\n return instantiationString;\n }\n }\n throw new Error(`unrecognized argument type ${arg.constructor.name}`);\n }\n}\n\nfunction trackablePrimitive(value) {\n // wrapped in object, so track-able\n return new value.constructor(value);\n}\n\nif (typeof module !== 'undefined') {\n module.exports = { glWiretap, glExtensionWiretap };\n}\n\nif (typeof window !== 'undefined') {\n glWiretap.glExtensionWiretap = glExtensionWiretap;\n window.glWiretap = glWiretap;\n}\n","import { glWiretap } from 'gl-wiretap';\r\nimport { utils } from '../../utils';\r\n\r\nfunction toStringWithoutUtils(fn) {\r\n return fn.toString()\r\n .replace('=>', '')\r\n .replace(/^function /, '')\r\n .replace(/utils[.]/g, '/*utils.*/');\r\n}\r\n\r\n/**\r\n *\r\n * @param {Kernel} Kernel\r\n * @param {KernelVariable[]} args\r\n * @param {Kernel} originKernel\r\n * @param {string} [setupContextString]\r\n * @param {string} [destroyContextString]\r\n * @returns {string}\r\n */\r\nexport function glKernelString(Kernel, args, originKernel, setupContextString, destroyContextString) {\r\n args = args ? Array.from(args).map(arg => {\r\n switch (typeof arg) {\r\n case 'boolean':\r\n return new Boolean(arg);\r\n case 'number':\r\n return new Number(arg);\r\n default:\r\n return arg;\r\n }\r\n }) : null;\r\n const uploadedValues = [];\r\n const postResult = [];\r\n const context = glWiretap(originKernel.context, {\r\n useTrackablePrimitives: true,\r\n onReadPixels: (targetName) => {\r\n if (kernel.subKernels) {\r\n if (!subKernelsResultVariableSetup) {\r\n postResult.push(` const result = { result: ${getRenderString(targetName, kernel)} };`);\r\n subKernelsResultVariableSetup = true;\r\n } else {\r\n const property = kernel.subKernels[subKernelsResultIndex++].property;\r\n postResult.push(` result${isNaN(property) ? '.' + property : `[${property}]`} = ${getRenderString(targetName, kernel)};`);\r\n }\r\n if (subKernelsResultIndex === kernel.subKernels.length) {\r\n postResult.push(' return result;');\r\n }\r\n return;\r\n }\r\n if (targetName) {\r\n postResult.push(` return ${getRenderString(targetName, kernel)};`);\r\n } else {\r\n postResult.push(` return null;`);\r\n }\r\n },\r\n onUnrecognizedArgumentLookup: (argument) => {\r\n const argumentName = findKernelValue(argument, kernel.kernelArguments, [], context, uploadedValues);\r\n if (argumentName) {\r\n return argumentName;\r\n }\r\n const constantName = findKernelValue(argument, kernel.kernelConstants, constants ? Object.keys(constants).map(key => constants[key]) : [], context, uploadedValues);\r\n if (constantName) {\r\n return constantName;\r\n }\r\n return null;\r\n }\r\n });\r\n let subKernelsResultVariableSetup = false;\r\n let subKernelsResultIndex = 0;\r\n const {\r\n source,\r\n canvas,\r\n output,\r\n pipeline,\r\n graphical,\r\n loopMaxIterations,\r\n constants,\r\n optimizeFloatMemory,\r\n precision,\r\n fixIntegerDivisionAccuracy,\r\n functions,\r\n nativeFunctions,\r\n subKernels,\r\n immutable,\r\n argumentTypes,\r\n constantTypes,\r\n kernelArguments,\r\n kernelConstants,\r\n } = originKernel;\r\n const kernel = new Kernel(source, {\r\n canvas,\r\n context,\r\n checkContext: false,\r\n output,\r\n pipeline,\r\n graphical,\r\n loopMaxIterations,\r\n constants,\r\n optimizeFloatMemory,\r\n precision,\r\n fixIntegerDivisionAccuracy,\r\n functions,\r\n nativeFunctions,\r\n subKernels,\r\n immutable,\r\n argumentTypes,\r\n constantTypes,\r\n });\r\n let result = [];\r\n context.setIndent(2);\r\n kernel.build.apply(kernel, args);\r\n result.push(context.toString());\r\n context.reset();\r\n\r\n kernel.kernelArguments.forEach((kernelArgument, i) => {\r\n switch (kernelArgument.type) {\r\n // primitives\r\n case 'Integer':\r\n case 'Boolean':\r\n case 'Number':\r\n case 'Float':\r\n // non-primitives\r\n case 'Array':\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n case 'HTMLImage':\r\n case 'HTMLVideo':\r\n context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue);\r\n break;\r\n case 'HTMLImageArray':\r\n for (let imageIndex = 0; imageIndex < args[i].length; imageIndex++) {\r\n const arg = args[i];\r\n context.insertVariable(`uploadValue_${kernelArgument.name}[${imageIndex}]`, arg[imageIndex]);\r\n }\r\n break;\r\n case 'Input':\r\n context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue);\r\n break;\r\n case 'MemoryOptimizedNumberTexture':\r\n case 'NumberTexture':\r\n case 'Array1D(2)':\r\n case 'Array1D(3)':\r\n case 'Array1D(4)':\r\n case 'Array2D(2)':\r\n case 'Array2D(3)':\r\n case 'Array2D(4)':\r\n case 'Array3D(2)':\r\n case 'Array3D(3)':\r\n case 'Array3D(4)':\r\n case 'ArrayTexture(1)':\r\n case 'ArrayTexture(2)':\r\n case 'ArrayTexture(3)':\r\n case 'ArrayTexture(4)':\r\n context.insertVariable(`uploadValue_${kernelArgument.name}`, args[i].texture);\r\n break;\r\n default:\r\n throw new Error(`unhandled kernelArgumentType insertion for glWiretap of type ${kernelArgument.type}`);\r\n }\r\n });\r\n result.push('/** start of injected functions **/');\r\n result.push(`function ${toStringWithoutUtils(utils.flattenTo)}`);\r\n result.push(`function ${toStringWithoutUtils(utils.flatten2dArrayTo)}`);\r\n result.push(`function ${toStringWithoutUtils(utils.flatten3dArrayTo)}`);\r\n result.push(`function ${toStringWithoutUtils(utils.flatten4dArrayTo)}`);\r\n result.push(`function ${toStringWithoutUtils(utils.isArray)}`);\r\n if (kernel.renderOutput !== kernel.renderTexture && kernel.formatValues) {\r\n result.push(\r\n ` const renderOutput = function ${toStringWithoutUtils(kernel.formatValues)};`\r\n );\r\n }\r\n result.push('/** end of injected functions **/');\r\n result.push(` const innerKernel = function (${kernel.kernelArguments.map(kernelArgument => kernelArgument.varName).join(', ')}) {`);\r\n context.setIndent(4);\r\n kernel.run.apply(kernel, args);\r\n if (kernel.renderKernels) {\r\n kernel.renderKernels();\r\n } else if (kernel.renderOutput) {\r\n kernel.renderOutput();\r\n }\r\n result.push(' /** start setup uploads for kernel values **/');\r\n kernel.kernelArguments.forEach(kernelArgument => {\r\n result.push(' ' + kernelArgument.getStringValueHandler().split('\\n').join('\\n '));\r\n });\r\n result.push(' /** end setup uploads for kernel values **/');\r\n result.push(context.toString());\r\n if (kernel.renderOutput === kernel.renderTexture) {\r\n context.reset();\r\n const results = kernel.renderKernels();\r\n const textureName = context.getContextVariableName(kernel.outputTexture);\r\n result.push(` return {\r\n result: {\r\n texture: ${ textureName },\r\n type: '${ results.result.type }',\r\n toArray: ${ getToArrayString(results.result, textureName) }\r\n },`);\r\n const { subKernels, subKernelOutputTextures } = kernel;\r\n for (let i = 0; i < subKernels.length; i++) {\r\n const texture = subKernelOutputTextures[i];\r\n const subKernel = subKernels[i];\r\n const subKernelResult = results[subKernel.property];\r\n const subKernelTextureName = context.getContextVariableName(texture);\r\n result.push(`\r\n ${subKernel.property}: {\r\n texture: ${ subKernelTextureName },\r\n type: '${ subKernelResult.type }',\r\n toArray: ${ getToArrayString(subKernelResult, subKernelTextureName) }\r\n },`);\r\n }\r\n result.push(` };`);\r\n }\r\n result.push(` ${destroyContextString ? '\\n' + destroyContextString + ' ': ''}`);\r\n result.push(postResult.join('\\n'));\r\n result.push(' };');\r\n if (kernel.graphical) {\r\n result.push(getGetPixelsString(kernel));\r\n result.push(` innerKernel.getPixels = getPixels;`);\r\n }\r\n result.push(' return innerKernel;');\r\n\r\n let constantsUpload = [];\r\n kernelConstants.forEach((kernelConstant) => {\r\n constantsUpload.push(`${ kernelConstant.getStringValueHandler()}`);\r\n });\r\n return `function kernel(settings) {\r\n const { context, constants } = settings;\r\n ${constantsUpload.join('')}\r\n ${setupContextString ? setupContextString : ''}\r\n${result.join('\\n')}\r\n}`;\r\n}\r\n\r\nfunction getRenderString(targetName, kernel) {\r\n const readBackValue = kernel.precision === 'single' ? targetName : `new Float32Array(${targetName}.buffer)`;\r\n if (kernel.output[2]) {\r\n return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]}, ${kernel.output[2]})`;\r\n }\r\n if (kernel.output[1]) {\r\n return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]})`;\r\n }\r\n\r\n return `renderOutput(${readBackValue}, ${kernel.output[0]})`;\r\n}\r\n\r\nfunction getGetPixelsString(kernel) {\r\n const getPixels = kernel.getPixels.toString();\r\n const useFunctionKeyword = !/^function/.test(getPixels);\r\n return utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ getPixels }`, {\r\n findDependency: (object, name) => {\r\n if (object === 'utils') {\r\n return `const ${name} = ${utils[name].toString()};`;\r\n }\r\n return null;\r\n },\r\n thisLookup: (property) => {\r\n if (property === 'context') {\r\n return null;\r\n }\r\n if (kernel.hasOwnProperty(property)) {\r\n return JSON.stringify(kernel[property]);\r\n }\r\n throw new Error(`unhandled thisLookup ${ property }`);\r\n }\r\n });\r\n}\r\n\r\nfunction getToArrayString(kernelResult, textureName) {\r\n const toArray = kernelResult.toArray.toString();\r\n const useFunctionKeyword = !/^function/.test(toArray);\r\n const flattenedFunctions = utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ toArray }`, {\r\n findDependency: (object, name) => {\r\n if (object === 'utils') {\r\n return `const ${name} = ${utils[name].toString()};`;\r\n } else if (object === 'this') {\r\n return `${useFunctionKeyword ? 'function ' : ''}${kernelResult[name].toString()}`;\r\n } else {\r\n throw new Error('unhandled fromObject');\r\n }\r\n },\r\n thisLookup: (property) => {\r\n if (property === 'texture') {\r\n return textureName;\r\n }\r\n if (kernelResult.hasOwnProperty(property)) {\r\n return JSON.stringify(kernelResult[property]);\r\n }\r\n throw new Error(`unhandled thisLookup ${ property }`);\r\n }\r\n });\r\n return `() => {\r\n ${flattenedFunctions}\r\n return toArray();\r\n }`;\r\n}\r\n\r\n/**\r\n *\r\n * @param {KernelVariable} argument\r\n * @param {KernelValue[]} kernelValues\r\n * @param {KernelVariable[]} values\r\n * @param context\r\n * @param {KernelVariable[]} uploadedValues\r\n * @return {string|null}\r\n */\r\nfunction findKernelValue(argument, kernelValues, values, context, uploadedValues) {\r\n if (argument === null) return null;\r\n switch (typeof argument) {\r\n case 'boolean':\r\n case 'number':\r\n return null;\r\n }\r\n if (\r\n typeof HTMLImageElement !== 'undefined' &&\r\n argument instanceof HTMLImageElement\r\n ) {\r\n for (let i = 0; i < kernelValues.length; i++) {\r\n const kernelValue = kernelValues[i];\r\n if (kernelValue.type !== 'HTMLImageArray') continue;\r\n if (kernelValue.uploadValue !== argument) continue;\r\n // TODO: if we send two of the same image, the parser could get confused, and short circuit to the first, handle that here\r\n const variableIndex = values[i].indexOf(argument);\r\n if (variableIndex === -1) continue;\r\n const variableName = `uploadValue_${kernelValue.name}[${variableIndex}]`;\r\n context.insertVariable(variableName, argument);\r\n return variableName;\r\n }\r\n return null;\r\n }\r\n\r\n for (let i = 0; i < kernelValues.length; i++) {\r\n const kernelValue = kernelValues[i];\r\n if (argument !== kernelValue.uploadValue) continue;\r\n const variable = `uploadValue_${kernelValue.name}`;\r\n context.insertVariable(variable, kernelValue);\r\n return variable;\r\n }\r\n return null;\r\n}\r\n","/**\r\n * @class KernelValue\r\n */\r\nexport class KernelValue {\r\n /**\r\n *\r\n * @param {KernelVariable} value\r\n * @param {IKernelValueSettings} settings\r\n */\r\n constructor(value, settings) {\r\n const {\r\n name,\r\n kernel,\r\n context,\r\n checkContext,\r\n onRequestContextHandle,\r\n onUpdateValueMismatch,\r\n origin,\r\n strictIntegers,\r\n type,\r\n tactic,\r\n } = settings;\r\n if (!name) {\r\n throw new Error('name not set');\r\n }\r\n if (!type) {\r\n throw new Error('type not set');\r\n }\r\n if (!origin) {\r\n throw new Error('origin not set');\r\n }\r\n if (!tactic) {\r\n throw new Error('tactic not set');\r\n }\r\n if (origin !== 'user' && origin !== 'constants') {\r\n throw new Error(`origin must be \"user\" or \"constants\" value is \"${ origin }\"`);\r\n }\r\n if (!onRequestContextHandle) {\r\n throw new Error('onRequestContextHandle is not set');\r\n }\r\n this.name = name;\r\n this.origin = origin;\r\n this.tactic = tactic;\r\n this.id = `${this.origin}_${name}`;\r\n this.varName = origin === 'constants' ? `constants.${name}` : name;\r\n this.kernel = kernel;\r\n this.strictIntegers = strictIntegers;\r\n // handle textures\r\n this.type = value.type || type;\r\n this.size = value.size || null;\r\n this.index = null;\r\n this.context = context;\r\n this.checkContext = checkContext !== null && checkContext !== undefined ? checkContext : true;\r\n this.contextHandle = null;\r\n this.onRequestContextHandle = onRequestContextHandle;\r\n this.onUpdateValueMismatch = onUpdateValueMismatch;\r\n this.forceUploadEachRun = null;\r\n }\r\n\r\n getSource() {\r\n throw new Error(`\"getSource\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n updateValue(value) {\r\n throw new Error(`\"updateValue\" not defined on ${ this.constructor.name }`);\r\n }\r\n}\r\n","import { Input } from '../../../input';\r\nimport { KernelValue } from '../../kernel-value';\r\nimport { utils } from '../../../utils';\r\n\r\nexport class WebGLKernelValue extends KernelValue {\r\n /**\r\n * @param {KernelVariable} value\r\n * @param {IWebGLKernelValueSettings} settings\r\n */\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.dimensionsId = null;\r\n this.sizeId = null;\r\n this.initialValueConstructor = value.constructor;\r\n this.onRequestTexture = settings.onRequestTexture;\r\n this.onRequestIndex = settings.onRequestIndex;\r\n this.uploadValue = null;\r\n this.textureSize = null;\r\n this.bitRatio = null;\r\n }\r\n\r\n /**\r\n *\r\n * @param {number} width\r\n * @param {number} height\r\n */\r\n checkSize(width, height) {\r\n if (!this.kernel.validate) return;\r\n const { maxTextureSize } = this.kernel.constructor.features;\r\n if (width > maxTextureSize || height > maxTextureSize) {\r\n if (width > height) {\r\n throw new Error(`Argument width of ${width} larger than maximum size of ${maxTextureSize} for your GPU`);\r\n } else {\r\n throw new Error(`Argument height of ${height} larger than maximum size of ${maxTextureSize} for your GPU`);\r\n }\r\n }\r\n }\r\n\r\n requestTexture() {\r\n this.texture = this.onRequestTexture();\r\n this.setupTexture();\r\n }\r\n\r\n setupTexture() {\r\n this.contextHandle = this.onRequestContextHandle();\r\n this.index = this.onRequestIndex();\r\n this.dimensionsId = this.id + 'Dim';\r\n this.sizeId = this.id + 'Size';\r\n }\r\n\r\n getTransferArrayType(value) {\r\n if (Array.isArray(value[0])) {\r\n return this.getTransferArrayType(value[0]);\r\n }\r\n switch (value.constructor) {\r\n case Array:\r\n case Int32Array:\r\n case Int16Array:\r\n case Int8Array:\r\n return Float32Array;\r\n case Uint8ClampedArray:\r\n case Uint8Array:\r\n case Uint16Array:\r\n case Uint32Array:\r\n case Float32Array:\r\n case Float64Array:\r\n return value.constructor;\r\n }\r\n console.warn('Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros');\r\n return value.constructor;\r\n }\r\n /**\r\n * @desc Adds kernel parameters to the Value Texture,\r\n * binding it to the context, etc.\r\n *\r\n * @param {Array|Float32Array|Uint16Array} value - The actual Value supplied to the kernel\r\n * @param {Number} length - the expected total length of the output array\r\n * @param {Object} [Type]\r\n * @returns {Float32Array|Uint16Array|Uint8Array} flattened array to transfer\r\n */\r\n formatArrayTransfer(value, length, Type) {\r\n if (utils.isArray(value[0]) || this.optimizeFloatMemory) {\r\n // not already flat\r\n const valuesFlat = new Float32Array(length);\r\n utils.flattenTo(value, valuesFlat);\r\n return valuesFlat;\r\n } else {\r\n switch (value.constructor) {\r\n case Uint8ClampedArray:\r\n case Uint8Array:\r\n case Int8Array:\r\n case Uint16Array:\r\n case Int16Array:\r\n case Float32Array:\r\n case Int32Array: {\r\n const valuesFlat = new(Type || value.constructor)(length);\r\n utils.flattenTo(value, valuesFlat);\r\n return valuesFlat;\r\n }\r\n default: {\r\n const valuesFlat = new Float32Array(length);\r\n utils.flattenTo(value, valuesFlat);\r\n return valuesFlat;\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * bit storage ratio of source to target 'buffer', i.e. if 8bit array -> 32bit tex = 4\r\n * @param value\r\n * @returns {number}\r\n */\r\n getBitRatio(value) {\r\n if (Array.isArray(value[0])) {\r\n return this.getBitRatio(value[0]);\r\n } else if (value.constructor === Input) {\r\n return this.getBitRatio(value.value);\r\n }\r\n switch (value.constructor) {\r\n case Uint8ClampedArray:\r\n case Uint8Array:\r\n case Int8Array:\r\n return 1;\r\n case Uint16Array:\r\n case Int16Array:\r\n return 2;\r\n case Float32Array:\r\n case Int32Array:\r\n default:\r\n return 4;\r\n }\r\n }\r\n\r\n /**\r\n * Used for when we want a string output of our kernel, so we can still input values to the kernel\r\n */\r\n getStringValueHandler() {\r\n throw new Error(`\"getStringValueHandler\" not implemented on ${this.constructor.name}`);\r\n }\r\n\r\n getVariablePrecisionString() {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'lowp';\r\n case 'performance':\r\n return 'highp';\r\n case 'balanced':\r\n default:\r\n return 'mediump';\r\n }\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueBoolean extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n return `const bool ${this.id} = ${value};\\n`;\r\n }\r\n return `uniform bool ${this.id};\\n`;\r\n }\r\n\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform1i(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueFloat extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n if (Number.isInteger(value)) {\r\n return `const float ${this.id} = ${value}.0;\\n`;\r\n }\r\n return `const float ${this.id} = ${value};\\n`;\r\n }\r\n return `uniform float ${this.id};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform1f(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueInteger extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n return `const int ${this.id} = ${ parseInt(value) };\\n`;\r\n }\r\n return `uniform int ${this.id};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform1i(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueHTMLImage extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n const { width, height } = value;\r\n this.checkSize(width, height);\r\n this.dimensions = [width, height, 1];\r\n this.requestTexture();\r\n this.textureSize = [width, height];\r\n this.uploadValue = value;\r\n }\r\n\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(inputImage) {\r\n if (inputImage.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue = inputImage);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueHTMLImage } from './html-image';\r\n\r\nexport class WebGLKernelValueDynamicHTMLImage extends WebGLKernelValueHTMLImage {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n const { width, height } = value;\r\n this.checkSize(width, height);\r\n this.dimensions = [width, height, 1];\r\n this.textureSize = [width, height];\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { WebGLKernelValueHTMLImage } from './html-image';\r\n\r\nexport class WebGLKernelValueHTMLVideo extends WebGLKernelValueHTMLImage {}\r\n","import { WebGLKernelValueDynamicHTMLImage } from './dynamic-html-image';\r\n\r\nexport class WebGLKernelValueDynamicHTMLVideo extends WebGLKernelValueDynamicHTMLImage {}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleInput extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = 4;\r\n let [w, h, d] = value.size;\r\n this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,\r\n `flattenTo(${this.varName}.value, uploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(input) {\r\n if (input.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(input.value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueUnsignedInput extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = this.getBitRatio(value);\r\n const [w, h, d] = value.size;\r\n this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);\r\n this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio);\r\n this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio));\r\n this.TranserArrayType = this.getTransferArrayType(value.value);\r\n this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength);\r\n this.uploadValue = new Uint8Array(this.preUploadValue.buffer);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,\r\n `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,\r\n `flattenTo(${this.varName}.value, preUploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(input) {\r\n if (input.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(input.value, this.preUploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueUnsignedInput } from './unsigned-input';\r\n\r\nexport class WebGLKernelValueDynamicUnsignedInput extends WebGLKernelValueUnsignedInput {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n let [w, h, d] = value.size;\r\n this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);\r\n this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio);\r\n this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio));\r\n const Type = this.getTransferArrayType(value.value);\r\n this.preUploadValue = new Type(this.uploadArrayLength);\r\n this.uploadValue = new Uint8Array(this.preUploadValue.buffer);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueMemoryOptimizedNumberTexture extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n const [width, height] = value.size;\r\n this.checkSize(width, height);\r\n this.setupTexture();\r\n this.dimensions = value.dimensions;\r\n this.textureSize = value.size;\r\n this.uploadValue = value.texture;\r\n this.forceUploadEachRun = true;\r\n }\r\n\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName}.texture;\\n`;\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(inputTexture) {\r\n if (inputTexture.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n if (this.checkContext && inputTexture.context !== this.context) {\r\n throw new Error(`Value ${this.name} (${this.type }) must be from same context`);\r\n }\r\n const { context: gl } = this;\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueMemoryOptimizedNumberTexture } from './memory-optimized-number-texture';\r\n\r\nexport class WebGLKernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(inputTexture) {\r\n this.checkSize(inputTexture.size[0], inputTexture.size[1]);\r\n this.dimensions = inputTexture.dimensions;\r\n this.textureSize = inputTexture.size;\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(inputTexture);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueNumberTexture extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n const [width, height] = value.size;\r\n this.checkSize(width, height);\r\n this.setupTexture();\r\n const { size: textureSize, dimensions } = value;\r\n this.bitRatio = this.getBitRatio(value);\r\n this.dimensions = dimensions;\r\n this.textureSize = textureSize;\r\n this.uploadValue = value.texture;\r\n this.forceUploadEachRun = true;\r\n }\r\n\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName}.texture;\\n`;\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(inputTexture) {\r\n if (inputTexture.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n if (this.checkContext && inputTexture.context !== this.context) {\r\n throw new Error(`Value ${this.name} (${this.type}) must be from same context`);\r\n }\r\n const { context: gl } = this;\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueNumberTexture } from './number-texture';\r\n\r\nexport class WebGLKernelValueDynamicNumberTexture extends WebGLKernelValueNumberTexture {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.dimensions = value.dimensions;\r\n this.checkSize(value.size[0], value.size[1]);\r\n this.textureSize = value.size;\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = 4;\r\n this.dimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,\r\n `flattenTo(${this.varName}, uploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray1DI extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = 4;\r\n this.setShape(value);\r\n }\r\n\r\n setShape(value) {\r\n const valueDimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio);\r\n this.dimensions = new Int32Array([valueDimensions[1], 1, 1]);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,\r\n `flattenTo(${this.varName}, uploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flatten2dArrayTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray1DI } from './single-array1d-i';\r\n\r\nexport class WebGLKernelValueDynamicSingleArray1DI extends WebGLKernelValueSingleArray1DI {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray2DI extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = 4;\r\n this.setShape(value);\r\n }\r\n\r\n setShape(value) {\r\n const valueDimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio);\r\n this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], 1]);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,\r\n `flattenTo(${this.varName}, uploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flatten3dArrayTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray2DI } from './single-array2d-i';\r\n\r\nexport class WebGLKernelValueDynamicSingleArray2DI extends WebGLKernelValueSingleArray2DI {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray3DI extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = 4;\r\n this.setShape(value);\r\n }\r\n\r\n setShape(value) {\r\n const valueDimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio);\r\n this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], valueDimensions[3]]);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,\r\n `flattenTo(${this.varName}, uploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flatten4dArrayTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray3DI } from './single-array3d-i';\r\n\r\nexport class WebGLKernelValueDynamicSingleArray3DI extends WebGLKernelValueSingleArray3DI {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray2 extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n return `const vec2 ${this.id} = vec2(${value[0]},${value[1]});\\n`;\r\n }\r\n return `uniform vec2 ${this.id};\\n`;\r\n }\r\n\r\n getStringValueHandler() {\r\n // resetting isn't supported for Array(2)\r\n if (this.origin === 'constants') return '';\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform2fv(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray3 extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n return `const vec3 ${this.id} = vec3(${value[0]},${value[1]},${value[2]});\\n`;\r\n }\r\n return `uniform vec3 ${this.id};\\n`;\r\n }\r\n\r\n getStringValueHandler() {\r\n // resetting isn't supported for Array(3)\r\n if (this.origin === 'constants') return '';\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform3fv(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray4 extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n return `const vec4 ${this.id} = vec4(${value[0]},${value[1]},${value[2]},${value[3]});\\n`;\r\n }\r\n return `uniform vec4 ${this.id};\\n`;\r\n }\r\n\r\n getStringValueHandler() {\r\n // resetting isn't supported for Array(4)\r\n if (this.origin === 'constants') return '';\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform4fv(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueUnsignedArray extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = this.getBitRatio(value);\r\n this.dimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio);\r\n this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio));\r\n this.TranserArrayType = this.getTransferArrayType(value);\r\n this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength);\r\n this.uploadValue = new Uint8Array(this.preUploadValue.buffer);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,\r\n `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,\r\n `flattenTo(${this.varName}, preUploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.preUploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueUnsignedArray } from './unsigned-array';\r\n\r\nexport class WebGLKernelValueDynamicUnsignedArray extends WebGLKernelValueUnsignedArray {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.dimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio);\r\n this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio));\r\n const Type = this.getTransferArrayType(value);\r\n this.preUploadValue = new Type(this.uploadArrayLength);\r\n this.uploadValue = new Uint8Array(this.preUploadValue.buffer);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { WebGLKernelValueBoolean } from './kernel-value/boolean';\r\nimport { WebGLKernelValueFloat } from './kernel-value/float';\r\nimport { WebGLKernelValueInteger } from './kernel-value/integer';\r\n\r\nimport { WebGLKernelValueHTMLImage } from './kernel-value/html-image';\r\nimport { WebGLKernelValueDynamicHTMLImage } from './kernel-value/dynamic-html-image';\r\n\r\nimport { WebGLKernelValueHTMLVideo } from './kernel-value/html-video';\r\nimport { WebGLKernelValueDynamicHTMLVideo } from './kernel-value/dynamic-html-video';\r\n\r\nimport { WebGLKernelValueSingleInput } from './kernel-value/single-input';\r\nimport { WebGLKernelValueDynamicSingleInput } from './kernel-value/dynamic-single-input';\r\n\r\nimport { WebGLKernelValueUnsignedInput } from './kernel-value/unsigned-input';\r\nimport { WebGLKernelValueDynamicUnsignedInput } from './kernel-value/dynamic-unsigned-input';\r\n\r\nimport { WebGLKernelValueMemoryOptimizedNumberTexture } from './kernel-value/memory-optimized-number-texture';\r\nimport { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } from './kernel-value/dynamic-memory-optimized-number-texture';\r\n\r\nimport { WebGLKernelValueNumberTexture } from './kernel-value/number-texture';\r\nimport { WebGLKernelValueDynamicNumberTexture } from './kernel-value/dynamic-number-texture';\r\n\r\nimport { WebGLKernelValueSingleArray } from './kernel-value/single-array';\r\nimport { WebGLKernelValueDynamicSingleArray } from './kernel-value/dynamic-single-array';\r\n\r\nimport { WebGLKernelValueSingleArray1DI } from './kernel-value/single-array1d-i';\r\nimport { WebGLKernelValueDynamicSingleArray1DI } from './kernel-value/dynamic-single-array1d-i';\r\n\r\nimport { WebGLKernelValueSingleArray2DI } from './kernel-value/single-array2d-i';\r\nimport { WebGLKernelValueDynamicSingleArray2DI } from './kernel-value/dynamic-single-array2d-i';\r\n\r\nimport { WebGLKernelValueSingleArray3DI } from './kernel-value/single-array3d-i';\r\nimport { WebGLKernelValueDynamicSingleArray3DI } from './kernel-value/dynamic-single-array3d-i';\r\n\r\nimport { WebGLKernelValueSingleArray2 } from './kernel-value/single-array2';\r\nimport { WebGLKernelValueSingleArray3 } from './kernel-value/single-array3';\r\nimport { WebGLKernelValueSingleArray4 } from './kernel-value/single-array4';\r\n\r\nimport { WebGLKernelValueUnsignedArray } from './kernel-value/unsigned-array';\r\nimport { WebGLKernelValueDynamicUnsignedArray } from './kernel-value/dynamic-unsigned-array';\r\n\r\nexport const kernelValueMaps = {\r\n unsigned: {\r\n dynamic: {\r\n 'Boolean': WebGLKernelValueBoolean,\r\n 'Integer': WebGLKernelValueInteger,\r\n 'Float': WebGLKernelValueFloat,\r\n 'Array': WebGLKernelValueDynamicUnsignedArray,\r\n 'Array(2)': false,\r\n 'Array(3)': false,\r\n 'Array(4)': false,\r\n 'Array1D(2)': false,\r\n 'Array1D(3)': false,\r\n 'Array1D(4)': false,\r\n 'Array2D(2)': false,\r\n 'Array2D(3)': false,\r\n 'Array2D(4)': false,\r\n 'Array3D(2)': false,\r\n 'Array3D(3)': false,\r\n 'Array3D(4)': false,\r\n 'Input': WebGLKernelValueDynamicUnsignedInput,\r\n 'NumberTexture': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGLKernelValueDynamicHTMLImage,\r\n 'HTMLImageArray': false,\r\n 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo,\r\n },\r\n static: {\r\n 'Boolean': WebGLKernelValueBoolean,\r\n 'Float': WebGLKernelValueFloat,\r\n 'Integer': WebGLKernelValueInteger,\r\n 'Array': WebGLKernelValueUnsignedArray,\r\n 'Array(2)': false,\r\n 'Array(3)': false,\r\n 'Array(4)': false,\r\n 'Array1D(2)': false,\r\n 'Array1D(3)': false,\r\n 'Array1D(4)': false,\r\n 'Array2D(2)': false,\r\n 'Array2D(3)': false,\r\n 'Array2D(4)': false,\r\n 'Array3D(2)': false,\r\n 'Array3D(3)': false,\r\n 'Array3D(4)': false,\r\n 'Input': WebGLKernelValueUnsignedInput,\r\n 'NumberTexture': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(1)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(2)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(3)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(4)': WebGLKernelValueNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGLKernelValueHTMLImage,\r\n 'HTMLImageArray': false,\r\n 'HTMLVideo': WebGLKernelValueHTMLVideo,\r\n }\r\n },\r\n single: {\r\n dynamic: {\r\n 'Boolean': WebGLKernelValueBoolean,\r\n 'Integer': WebGLKernelValueInteger,\r\n 'Float': WebGLKernelValueFloat,\r\n 'Array': WebGLKernelValueDynamicSingleArray,\r\n 'Array(2)': WebGLKernelValueSingleArray2,\r\n 'Array(3)': WebGLKernelValueSingleArray3,\r\n 'Array(4)': WebGLKernelValueSingleArray4,\r\n 'Array1D(2)': WebGLKernelValueDynamicSingleArray1DI,\r\n 'Array1D(3)': WebGLKernelValueDynamicSingleArray1DI,\r\n 'Array1D(4)': WebGLKernelValueDynamicSingleArray1DI,\r\n 'Array2D(2)': WebGLKernelValueDynamicSingleArray2DI,\r\n 'Array2D(3)': WebGLKernelValueDynamicSingleArray2DI,\r\n 'Array2D(4)': WebGLKernelValueDynamicSingleArray2DI,\r\n 'Array3D(2)': WebGLKernelValueDynamicSingleArray3DI,\r\n 'Array3D(3)': WebGLKernelValueDynamicSingleArray3DI,\r\n 'Array3D(4)': WebGLKernelValueDynamicSingleArray3DI,\r\n 'Input': WebGLKernelValueDynamicSingleInput,\r\n 'NumberTexture': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGLKernelValueDynamicHTMLImage,\r\n 'HTMLImageArray': false,\r\n 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo,\r\n },\r\n static: {\r\n 'Boolean': WebGLKernelValueBoolean,\r\n 'Float': WebGLKernelValueFloat,\r\n 'Integer': WebGLKernelValueInteger,\r\n 'Array': WebGLKernelValueSingleArray,\r\n 'Array(2)': WebGLKernelValueSingleArray2,\r\n 'Array(3)': WebGLKernelValueSingleArray3,\r\n 'Array(4)': WebGLKernelValueSingleArray4,\r\n 'Array1D(2)': WebGLKernelValueSingleArray1DI,\r\n 'Array1D(3)': WebGLKernelValueSingleArray1DI,\r\n 'Array1D(4)': WebGLKernelValueSingleArray1DI,\r\n 'Array2D(2)': WebGLKernelValueSingleArray2DI,\r\n 'Array2D(3)': WebGLKernelValueSingleArray2DI,\r\n 'Array2D(4)': WebGLKernelValueSingleArray2DI,\r\n 'Array3D(2)': WebGLKernelValueSingleArray3DI,\r\n 'Array3D(3)': WebGLKernelValueSingleArray3DI,\r\n 'Array3D(4)': WebGLKernelValueSingleArray3DI,\r\n 'Input': WebGLKernelValueSingleInput,\r\n 'NumberTexture': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(1)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(2)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(3)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(4)': WebGLKernelValueNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGLKernelValueHTMLImage,\r\n 'HTMLImageArray': false,\r\n 'HTMLVideo': WebGLKernelValueHTMLVideo,\r\n }\r\n },\r\n};\r\n\r\nexport function lookupKernelValueType(type, dynamic, precision, value) {\r\n if (!type) {\r\n throw new Error('type missing');\r\n }\r\n if (!dynamic) {\r\n throw new Error('dynamic missing');\r\n }\r\n if (!precision) {\r\n throw new Error('precision missing');\r\n }\r\n if (value.type) {\r\n type = value.type;\r\n }\r\n const types = kernelValueMaps[precision][dynamic];\r\n if (types[type] === false) {\r\n return null;\r\n } else if (types[type] === undefined) {\r\n throw new Error(`Could not find a KernelValue for ${ type }`);\r\n }\r\n return types[type];\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray } from './single-array';\r\n\r\nexport class WebGLKernelValueDynamicSingleArray extends WebGLKernelValueSingleArray {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.dimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleInput } from './single-input';\r\n\r\nexport class WebGLKernelValueDynamicSingleInput extends WebGLKernelValueSingleInput {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n let [w, h, d] = value.size;\r\n this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { GLKernel } from '../gl/kernel';\r\nimport { FunctionBuilder } from '../function-builder';\r\nimport { WebGLFunctionNode } from './function-node';\r\nimport { utils } from '../../utils';\r\nimport triangleNoise from '../../plugins/triangle-noise';\r\nimport { fragmentShader } from './fragment-shader';\r\nimport { vertexShader } from './vertex-shader';\r\nimport { glKernelString } from '../gl/kernel-string';\r\nimport { lookupKernelValueType } from './kernel-value-maps';\r\n\r\nlet isSupported = null;\r\nlet testCanvas = null;\r\nlet testContext = null;\r\nlet testExtensions = null;\r\nlet features = null;\r\n\r\nconst plugins = [triangleNoise];\r\nconst canvases = [];\r\nconst maxTexSizes = {};\r\n\r\n/**\r\n * @desc Kernel Implementation for WebGL.\r\n *\r\n * This builds the shaders and runs them on the GPU, then outputs the result\r\n * back as float (enabled by default) and Texture.\r\n *\r\n * @prop {Object} textureCache - webGl Texture cache\r\n * @prop {Object} programUniformLocationCache - Location of program variables in memory\r\n * @prop {Object} framebuffer - Webgl frameBuffer\r\n * @prop {Object} buffer - WebGL buffer\r\n * @prop {Object} program - The webGl Program\r\n * @prop {Object} functionBuilder - Function Builder instance bound to this Kernel\r\n * @prop {Boolean} pipeline - Set output type to FAST mode (GPU to GPU via Textures), instead of float\r\n * @prop {String} endianness - Endian information like Little-endian, Big-endian.\r\n * @prop {Array} argumentTypes - Types of parameters sent to the Kernel\r\n * @prop {String} compiledFragmentShader - Compiled fragment shader string\r\n * @prop {String} compiledVertexShader - Compiled Vertical shader string\r\n * @extends GLKernel\r\n */\r\nexport class WebGLKernel extends GLKernel {\r\n static get isSupported() {\r\n if (isSupported !== null) {\r\n return isSupported;\r\n }\r\n this.setupFeatureChecks();\r\n isSupported = this.isContextMatch(testContext);\r\n return isSupported;\r\n }\r\n\r\n static setupFeatureChecks() {\r\n if (typeof document !== 'undefined') {\r\n testCanvas = document.createElement('canvas');\r\n } else if (typeof OffscreenCanvas !== 'undefined') {\r\n testCanvas = new OffscreenCanvas(0, 0);\r\n }\r\n if (!testCanvas) return;\r\n testContext = testCanvas.getContext('webgl') || testCanvas.getContext('experimental-webgl');\r\n if (!testContext || !testContext.getExtension) return;\r\n testExtensions = {\r\n OES_texture_float: testContext.getExtension('OES_texture_float'),\r\n OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'),\r\n OES_element_index_uint: testContext.getExtension('OES_element_index_uint'),\r\n WEBGL_draw_buffers: testContext.getExtension('WEBGL_draw_buffers'),\r\n };\r\n features = this.getFeatures();\r\n }\r\n\r\n static isContextMatch(context) {\r\n if (typeof WebGLRenderingContext !== 'undefined') {\r\n return context instanceof WebGLRenderingContext;\r\n }\r\n return false;\r\n }\r\n\r\n static getFeatures() {\r\n const isDrawBuffers = this.getIsDrawBuffers();\r\n return Object.freeze({\r\n isFloatRead: this.getIsFloatRead(),\r\n isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(),\r\n isTextureFloat: this.getIsTextureFloat(),\r\n isDrawBuffers,\r\n kernelMap: isDrawBuffers,\r\n channelCount: this.getChannelCount(),\r\n });\r\n }\r\n\r\n static getIsTextureFloat() {\r\n return Boolean(testExtensions.OES_texture_float);\r\n }\r\n\r\n static getIsDrawBuffers() {\r\n return Boolean(testExtensions.WEBGL_draw_buffers);\r\n }\r\n\r\n static getChannelCount() {\r\n return testExtensions.WEBGL_draw_buffers ?\r\n testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) :\r\n 1;\r\n }\r\n\r\n static lookupKernelValueType(type, dynamic, precision, value) {\r\n return lookupKernelValueType(type, dynamic, precision, value);\r\n }\r\n\r\n static get testCanvas() {\r\n return testCanvas;\r\n }\r\n\r\n static get testContext() {\r\n return testContext;\r\n }\r\n\r\n static get features() {\r\n return features;\r\n }\r\n\r\n static get fragmentShader() {\r\n return fragmentShader;\r\n }\r\n\r\n static get vertexShader() {\r\n return vertexShader;\r\n }\r\n\r\n /**\r\n *\r\n * @param {String} source\r\n * @param {IKernelSettings} settings\r\n */\r\n constructor(source, settings) {\r\n super(source, settings);\r\n this.program = null;\r\n this.pipeline = settings.pipeline;\r\n this.endianness = utils.systemEndianness();\r\n this.extensions = {};\r\n this.subKernelOutputTextures = null;\r\n this.kernelArguments = null;\r\n this.argumentTextureCount = 0;\r\n this.constantTextureCount = 0;\r\n this.compiledFragmentShader = null;\r\n this.compiledVertexShader = null;\r\n this.fragShader = null;\r\n this.vertShader = null;\r\n this.drawBuffersMap = null;\r\n this.outputTexture = null;\r\n\r\n /**\r\n *\r\n * @type {Int32Array|null}\r\n */\r\n this.maxTexSize = null;\r\n this.switchingKernels = false;\r\n this.onRequestSwitchKernel = null;\r\n\r\n this.mergeSettings(source.settings || settings);\r\n\r\n /**\r\n * The thread dimensions, x, y and z\r\n * @type {Array|null}\r\n */\r\n this.threadDim = null;\r\n this.framebuffer = null;\r\n this.buffer = null;\r\n this.textureCache = {};\r\n this.programUniformLocationCache = {};\r\n this.uniform1fCache = {};\r\n this.uniform1iCache = {};\r\n this.uniform2fCache = {};\r\n this.uniform2fvCache = {};\r\n this.uniform2ivCache = {};\r\n this.uniform3fvCache = {};\r\n this.uniform3ivCache = {};\r\n this.uniform4fvCache = {};\r\n this.uniform4ivCache = {};\r\n }\r\n\r\n initCanvas() {\r\n if (typeof document !== 'undefined') {\r\n const canvas = document.createElement('canvas');\r\n // Default width and height, to fix webgl issue in safari\r\n canvas.width = 2;\r\n canvas.height = 2;\r\n return canvas;\r\n } else if (typeof OffscreenCanvas !== 'undefined') {\r\n return new OffscreenCanvas(0, 0);\r\n }\r\n }\r\n\r\n initContext() {\r\n const settings = {\r\n alpha: false,\r\n depth: false,\r\n antialias: false\r\n };\r\n return this.canvas.getContext('webgl', settings) || this.canvas.getContext('experimental-webgl', settings);\r\n }\r\n\r\n initPlugins(settings) {\r\n // default plugins\r\n const pluginsToUse = [];\r\n const { source } = this;\r\n if (typeof source === 'string') {\r\n for (let i = 0; i < plugins.length; i++) {\r\n const plugin = plugins[i];\r\n if (source.match(plugin.functionMatch)) {\r\n pluginsToUse.push(plugin);\r\n }\r\n }\r\n } else if (typeof source === 'object') {\r\n // `source` is from object, json\r\n if (settings.pluginNames) { //TODO: in context of JSON support, pluginNames may not exist here\r\n for (let i = 0; i < plugins.length; i++) {\r\n const plugin = plugins[i];\r\n const usePlugin = settings.pluginNames.some(pluginName => pluginName === plugin.name);\r\n if (usePlugin) {\r\n pluginsToUse.push(plugin);\r\n }\r\n }\r\n }\r\n }\r\n return pluginsToUse;\r\n }\r\n\r\n initExtensions() {\r\n this.extensions = {\r\n OES_texture_float: this.context.getExtension('OES_texture_float'),\r\n OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'),\r\n OES_element_index_uint: this.context.getExtension('OES_element_index_uint'),\r\n WEBGL_draw_buffers: this.context.getExtension('WEBGL_draw_buffers'),\r\n WEBGL_color_buffer_float: this.context.getExtension('WEBGL_color_buffer_float'),\r\n };\r\n }\r\n\r\n /**\r\n * @desc Validate settings related to Kernel, such as dimensions size, and auto output support.\r\n * @param {IArguments} args\r\n */\r\n validateSettings(args) {\r\n if (!this.validate) {\r\n this.texSize = utils.getKernelTextureSize({\r\n optimizeFloatMemory: this.optimizeFloatMemory,\r\n precision: this.precision,\r\n }, this.output);\r\n return;\r\n }\r\n\r\n const { features } = this.constructor;\r\n if (this.optimizeFloatMemory === true && !features.isTextureFloat) {\r\n throw new Error('Float textures are not supported');\r\n } else if (this.precision === 'single' && !features.isFloatRead) {\r\n throw new Error('Single precision not supported');\r\n } else if (!this.graphical && this.precision === null && features.isTextureFloat) {\r\n this.precision = features.isFloatRead ? 'single' : 'unsigned';\r\n }\r\n\r\n if (this.subKernels && this.subKernels.length > 0 && !this.extensions.WEBGL_draw_buffers) {\r\n throw new Error('could not instantiate draw buffers extension');\r\n }\r\n\r\n if (this.fixIntegerDivisionAccuracy === null) {\r\n this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate;\r\n } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) {\r\n this.fixIntegerDivisionAccuracy = false;\r\n }\r\n\r\n this.checkOutput();\r\n\r\n if (!this.output || this.output.length === 0) {\r\n if (args.length !== 1) {\r\n throw new Error('Auto output only supported for kernels with only one input');\r\n }\r\n\r\n const argType = utils.getVariableType(args[0], this.strictIntegers);\r\n if (argType === 'Array') {\r\n this.output = utils.getDimensions(argType);\r\n } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') {\r\n this.output = args[0].output;\r\n } else {\r\n throw new Error('Auto output not supported for input type: ' + argType);\r\n }\r\n }\r\n\r\n if (this.graphical) {\r\n if (this.output.length !== 2) {\r\n throw new Error('Output must have 2 dimensions on graphical mode');\r\n }\r\n\r\n if (this.precision === 'precision') {\r\n this.precision = 'unsigned';\r\n console.warn('Cannot use graphical mode and single precision at the same time');\r\n }\r\n\r\n this.texSize = utils.clone(this.output);\r\n return;\r\n } else if (this.precision === null && features.isTextureFloat) {\r\n this.precision = 'single';\r\n }\r\n\r\n this.texSize = utils.getKernelTextureSize({\r\n optimizeFloatMemory: this.optimizeFloatMemory,\r\n precision: this.precision,\r\n }, this.output);\r\n\r\n this.checkTextureSize();\r\n }\r\n\r\n updateMaxTexSize() {\r\n const { texSize, canvas } = this;\r\n if (this.maxTexSize === null) {\r\n let canvasIndex = canvases.indexOf(canvas);\r\n if (canvasIndex === -1) {\r\n canvasIndex = canvases.length;\r\n canvases.push(canvas);\r\n maxTexSizes[canvasIndex] = [texSize[0], texSize[1]];\r\n }\r\n this.maxTexSize = maxTexSizes[canvasIndex];\r\n }\r\n if (this.maxTexSize[0] < texSize[0]) {\r\n this.maxTexSize[0] = texSize[0];\r\n }\r\n if (this.maxTexSize[1] < texSize[1]) {\r\n this.maxTexSize[1] = texSize[1];\r\n }\r\n }\r\n\r\n // TODO: move channel checks to new place\r\n _oldtranslateSource() {\r\n const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, {\r\n fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy\r\n });\r\n\r\n // need this line to automatically get returnType\r\n const translatedSource = functionBuilder.getPrototypeString('kernel');\r\n\r\n if (!this.returnType) {\r\n this.returnType = functionBuilder.getKernelResultType();\r\n }\r\n\r\n let requiredChannels = 0;\r\n const returnTypes = functionBuilder.getReturnTypes();\r\n for (let i = 0; i < returnTypes.length; i++) {\r\n switch (returnTypes[i]) {\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n requiredChannels++;\r\n break;\r\n case 'Array(2)':\r\n requiredChannels += 2;\r\n break;\r\n case 'Array(3)':\r\n requiredChannels += 3;\r\n break;\r\n case 'Array(4)':\r\n requiredChannels += 4;\r\n break;\r\n }\r\n }\r\n\r\n if (features && requiredChannels > features.channelCount) {\r\n throw new Error('Too many channels!');\r\n }\r\n\r\n return this.translatedSource = translatedSource;\r\n }\r\n\r\n setupArguments(args) {\r\n this.kernelArguments = [];\r\n this.argumentTextureCount = 0;\r\n const needsArgumentTypes = this.argumentTypes === null;\r\n // TODO: remove\r\n if (needsArgumentTypes) {\r\n this.argumentTypes = [];\r\n }\r\n this.argumentSizes = [];\r\n this.argumentBitRatios = [];\r\n // TODO: end remove\r\n\r\n if (args.length < this.argumentNames.length) {\r\n throw new Error('not enough arguments for kernel');\r\n } else if (args.length > this.argumentNames.length) {\r\n throw new Error('too many arguments for kernel');\r\n }\r\n\r\n const { context: gl } = this;\r\n let textureIndexes = 0;\r\n for (let index = 0; index < args.length; index++) {\r\n const value = args[index];\r\n const name = this.argumentNames[index];\r\n let type;\r\n if (needsArgumentTypes) {\r\n type = utils.getVariableType(value, this.strictIntegers);\r\n this.argumentTypes.push(type);\r\n } else {\r\n type = this.argumentTypes[index];\r\n }\r\n const KernelValue = this.constructor.lookupKernelValueType(type, this.dynamicArguments ? 'dynamic' : 'static', this.precision, args[index]);\r\n if (KernelValue === null) {\r\n return this.requestFallback(args);\r\n }\r\n const kernelArgument = new KernelValue(value, {\r\n name,\r\n type,\r\n tactic: this.tactic,\r\n origin: 'user',\r\n context: gl,\r\n checkContext: this.checkContext,\r\n kernel: this,\r\n strictIntegers: this.strictIntegers,\r\n onRequestTexture: () => {\r\n return this.context.createTexture();\r\n },\r\n onRequestIndex: () => {\r\n return textureIndexes++;\r\n },\r\n onUpdateValueMismatch: () => {\r\n this.switchingKernels = true;\r\n },\r\n onRequestContextHandle: () => {\r\n return gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount++;\r\n }\r\n });\r\n this.kernelArguments.push(kernelArgument);\r\n this.argumentSizes.push(kernelArgument.textureSize);\r\n this.argumentBitRatios[index] = kernelArgument.bitRatio;\r\n }\r\n }\r\n\r\n setupConstants(args) {\r\n const { context: gl } = this;\r\n this.kernelConstants = [];\r\n this.forceUploadKernelConstants = [];\r\n let needsConstantTypes = this.constantTypes === null;\r\n if (needsConstantTypes) {\r\n this.constantTypes = {};\r\n }\r\n this.constantBitRatios = {};\r\n let textureIndexes = 0;\r\n for (const name in this.constants) {\r\n const value = this.constants[name];\r\n let type;\r\n if (needsConstantTypes) {\r\n type = utils.getVariableType(value, this.strictIntegers);\r\n this.constantTypes[name] = type;\r\n } else {\r\n type = this.constantTypes[name];\r\n }\r\n const KernelValue = this.constructor.lookupKernelValueType(type, 'static', this.precision, value);\r\n if (KernelValue === null) {\r\n return this.requestFallback(args);\r\n }\r\n const kernelValue = new KernelValue(value, {\r\n name,\r\n type,\r\n tactic: this.tactic,\r\n origin: 'constants',\r\n context: this.context,\r\n checkContext: this.checkContext,\r\n kernel: this,\r\n strictIntegers: this.strictIntegers,\r\n onRequestTexture: () => {\r\n return this.context.createTexture();\r\n },\r\n onRequestIndex: () => {\r\n return textureIndexes++;\r\n },\r\n onRequestContextHandle: () => {\r\n return gl.TEXTURE0 + this.constantTextureCount++;\r\n }\r\n });\r\n this.constantBitRatios[name] = kernelValue.bitRatio;\r\n this.kernelConstants.push(kernelValue);\r\n if (kernelValue.forceUploadEachRun) {\r\n this.forceUploadKernelConstants.push(kernelValue);\r\n }\r\n }\r\n }\r\n\r\n build() {\r\n this.initExtensions();\r\n this.validateSettings(arguments);\r\n this.setupConstants(arguments);\r\n if (this.fallbackRequested) return;\r\n this.setupArguments(arguments);\r\n if (this.fallbackRequested) return;\r\n this.updateMaxTexSize();\r\n this.translateSource();\r\n const failureResult = this.pickRenderStrategy(arguments);\r\n if (failureResult) {\r\n return failureResult;\r\n }\r\n const { texSize, context: gl, canvas } = this;\r\n gl.enable(gl.SCISSOR_TEST);\r\n if (this.pipeline && this.precision === 'single') {\r\n gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);\r\n canvas.width = this.maxTexSize[0];\r\n canvas.height = this.maxTexSize[1];\r\n } else {\r\n gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);\r\n canvas.width = this.maxTexSize[0];\r\n canvas.height = this.maxTexSize[1];\r\n }\r\n const threadDim = this.threadDim = Array.from(this.output);\r\n while (threadDim.length < 3) {\r\n threadDim.push(1);\r\n }\r\n\r\n const compiledVertexShader = this.getVertexShader(arguments);\r\n const vertShader = gl.createShader(gl.VERTEX_SHADER);\r\n gl.shaderSource(vertShader, compiledVertexShader);\r\n gl.compileShader(vertShader);\r\n this.vertShader = vertShader;\r\n\r\n const compiledFragmentShader = this.getFragmentShader(arguments);\r\n const fragShader = gl.createShader(gl.FRAGMENT_SHADER);\r\n gl.shaderSource(fragShader, compiledFragmentShader);\r\n gl.compileShader(fragShader);\r\n this.fragShader = fragShader;\r\n\r\n if (this.debug) {\r\n console.log('GLSL Shader Output:');\r\n console.log(compiledFragmentShader);\r\n }\r\n\r\n if (!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) {\r\n throw new Error('Error compiling vertex shader: ' + gl.getShaderInfoLog(vertShader));\r\n }\r\n if (!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) {\r\n throw new Error('Error compiling fragment shader: ' + gl.getShaderInfoLog(fragShader));\r\n }\r\n\r\n const program = this.program = gl.createProgram();\r\n gl.attachShader(program, vertShader);\r\n gl.attachShader(program, fragShader);\r\n gl.linkProgram(program);\r\n this.framebuffer = gl.createFramebuffer();\r\n this.framebuffer.width = texSize[0];\r\n this.framebuffer.height = texSize[1];\r\n\r\n const vertices = new Float32Array([-1, -1,\r\n 1, -1, -1, 1,\r\n 1, 1\r\n ]);\r\n const texCoords = new Float32Array([\r\n 0, 0,\r\n 1, 0,\r\n 0, 1,\r\n 1, 1\r\n ]);\r\n\r\n const texCoordOffset = vertices.byteLength;\r\n\r\n let buffer = this.buffer;\r\n if (!buffer) {\r\n buffer = this.buffer = gl.createBuffer();\r\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\r\n gl.bufferData(gl.ARRAY_BUFFER, vertices.byteLength + texCoords.byteLength, gl.STATIC_DRAW);\r\n } else {\r\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\r\n }\r\n\r\n gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices);\r\n gl.bufferSubData(gl.ARRAY_BUFFER, texCoordOffset, texCoords);\r\n\r\n const aPosLoc = gl.getAttribLocation(this.program, 'aPos');\r\n gl.enableVertexAttribArray(aPosLoc);\r\n gl.vertexAttribPointer(aPosLoc, 2, gl.FLOAT, false, 0, 0);\r\n const aTexCoordLoc = gl.getAttribLocation(this.program, 'aTexCoord');\r\n gl.enableVertexAttribArray(aTexCoordLoc);\r\n gl.vertexAttribPointer(aTexCoordLoc, 2, gl.FLOAT, false, 0, texCoordOffset);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n\r\n let i = 0;\r\n gl.useProgram(this.program);\r\n for (let p in this.constants) {\r\n this.kernelConstants[i++].updateValue(this.constants[p]);\r\n }\r\n\r\n if (!this.immutable) {\r\n this._setupOutputTexture();\r\n if (\r\n this.subKernels !== null &&\r\n this.subKernels.length > 0\r\n ) {\r\n this._setupSubOutputTextures();\r\n }\r\n }\r\n }\r\n\r\n translateSource() {\r\n const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, {\r\n fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy\r\n });\r\n this.translatedSource = functionBuilder.getPrototypeString('kernel');\r\n if (!this.graphical && !this.returnType) {\r\n this.returnType = functionBuilder.getKernelResultType();\r\n }\r\n\r\n if (this.subKernels && this.subKernels.length > 0) {\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (!subKernel.returnType) {\r\n subKernel.returnType = functionBuilder.getSubKernelResultType(i);\r\n }\r\n }\r\n }\r\n }\r\n\r\n run() {\r\n const { kernelArguments, forceUploadKernelConstants } = this;\r\n const texSize = this.texSize;\r\n const gl = this.context;\r\n\r\n gl.useProgram(this.program);\r\n gl.scissor(0, 0, texSize[0], texSize[1]);\r\n\r\n if (this.dynamicOutput) {\r\n this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim));\r\n this.setUniform2iv('uTexSize', texSize);\r\n }\r\n\r\n this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]);\r\n\r\n this.switchingKernels = false;\r\n for (let i = 0; i < forceUploadKernelConstants.length; i++) {\r\n const constant = forceUploadKernelConstants[i];\r\n constant.updateValue(this.constants[constant.name]);\r\n if (this.switchingKernels) return;\r\n }\r\n for (let i = 0; i < kernelArguments.length; i++) {\r\n kernelArguments[i].updateValue(arguments[i]);\r\n if (this.switchingKernels) return;\r\n }\r\n\r\n if (this.plugins) {\r\n for (let i = 0; i < this.plugins.length; i++) {\r\n const plugin = this.plugins[i];\r\n if (plugin.onBeforeRun) {\r\n plugin.onBeforeRun(this);\r\n }\r\n }\r\n }\r\n\r\n if (this.graphical) {\r\n if (this.pipeline) {\r\n gl.bindRenderbuffer(gl.RENDERBUFFER, null);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n if (!this.outputTexture || this.immutable) {\r\n this._setupOutputTexture();\r\n }\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n return new this.TextureConstructor({\r\n texture: this.outputTexture,\r\n size: texSize,\r\n dimensions: this.threadDim,\r\n output: this.output,\r\n context: this.context,\r\n });\r\n }\r\n gl.bindRenderbuffer(gl.RENDERBUFFER, null);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n return;\r\n }\r\n\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n if (this.immutable) {\r\n this._setupOutputTexture();\r\n }\r\n\r\n if (this.subKernels !== null) {\r\n if (this.immutable) {\r\n this._setupSubOutputTextures();\r\n }\r\n this.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(this.drawBuffersMap);\r\n }\r\n\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n }\r\n\r\n /**\r\n * @desc This return defined outputTexture, which is setup in .build(), or if immutable, is defined in .run()\r\n * @returns {Object} Output Texture Cache\r\n */\r\n getOutputTexture() {\r\n return this.outputTexture;\r\n }\r\n\r\n /**\r\n * @desc Setup and replace output texture\r\n */\r\n _setupOutputTexture() {\r\n const gl = this.context;\r\n const texSize = this.texSize;\r\n const texture = this.outputTexture = this.context.createTexture();\r\n gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n // if (this.precision === 'single') {\r\n // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n // } else {\r\n // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n // }\r\n if (this.precision === 'single') {\r\n if (this.pipeline) {\r\n // TODO: investigate if webgl1 can handle gl.RED usage in gl.texImage2D, otherwise, simplify the below\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Float':\r\n case 'Integer':\r\n if (this.optimizeFloatMemory) {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n }\r\n break;\r\n case 'Array(2)':\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n break;\r\n case 'Array(3)':\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n break;\r\n case 'Array(4)':\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n break;\r\n default:\r\n if (!this.graphical) {\r\n throw new Error('Unhandled return type');\r\n }\r\n }\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n }\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n }\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);\r\n }\r\n\r\n /**\r\n * @desc Setup and replace sub-output textures\r\n */\r\n _setupSubOutputTextures() {\r\n const gl = this.context;\r\n const texSize = this.texSize;\r\n this.drawBuffersMap = [gl.COLOR_ATTACHMENT0];\r\n this.subKernelOutputTextures = [];\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const texture = this.context.createTexture();\r\n this.subKernelOutputTextures.push(texture);\r\n this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1);\r\n gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n if (this.precision === 'single') {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n }\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0);\r\n }\r\n }\r\n\r\n /**\r\n * @desc Returns the Texture Cache of the supplied parameter (can be kernel, sub-kernel or argument)\r\n * @param {String} name - Name of the subkernel, argument, or kernel.\r\n * @returns {Object} Texture cache\r\n */\r\n getTextureCache(name) {\r\n if (this.textureCache.hasOwnProperty(name)) {\r\n return this.textureCache[name];\r\n }\r\n return this.textureCache[name] = this.context.createTexture();\r\n }\r\n\r\n /**\r\n * @desc removes a texture from the kernel's cache\r\n * @param {String} name - Name of texture\r\n */\r\n detachTextureCache(name) {\r\n delete this.textureCache[name];\r\n }\r\n\r\n setUniform1f(name, value) {\r\n if (this.uniform1fCache.hasOwnProperty(name)) {\r\n const cache = this.uniform1fCache[name];\r\n if (value === cache) {\r\n return;\r\n }\r\n }\r\n this.uniform1fCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform1f(loc, value);\r\n }\r\n\r\n setUniform1i(name, value) {\r\n if (this.uniform1iCache.hasOwnProperty(name)) {\r\n const cache = this.uniform1iCache[name];\r\n if (value === cache) {\r\n return;\r\n }\r\n }\r\n this.uniform1iCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform1i(loc, value);\r\n }\r\n\r\n setUniform2f(name, value1, value2) {\r\n if (this.uniform2fCache.hasOwnProperty(name)) {\r\n const cache = this.uniform2fCache[name];\r\n if (\r\n value1 === cache[0] &&\r\n value2 === cache[1]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform2fCache[name] = [value1, value2];\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform2f(loc, value1, value2);\r\n }\r\n\r\n setUniform2fv(name, value) {\r\n if (this.uniform2fvCache.hasOwnProperty(name)) {\r\n const cache = this.uniform2fvCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform2fvCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform2fv(loc, value);\r\n }\r\n\r\n setUniform2iv(name, value) {\r\n if (this.uniform2ivCache.hasOwnProperty(name)) {\r\n const cache = this.uniform2ivCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform2ivCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform2iv(loc, value);\r\n }\r\n\r\n setUniform3fv(name, value) {\r\n if (this.uniform3fvCache.hasOwnProperty(name)) {\r\n const cache = this.uniform3fvCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1] &&\r\n value[2] === cache[2]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform3fvCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform3fv(loc, value);\r\n }\r\n\r\n setUniform3iv(name, value) {\r\n if (this.uniform3ivCache.hasOwnProperty(name)) {\r\n const cache = this.uniform3ivCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1] &&\r\n value[2] === cache[2]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform3ivCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform3iv(loc, value);\r\n }\r\n\r\n setUniform3fv(name, value) {\r\n if (this.uniform3fvCache.hasOwnProperty(name)) {\r\n const cache = this.uniform3fvCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1] &&\r\n value[2] === cache[2]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform3fvCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform3fv(loc, value);\r\n }\r\n\r\n setUniform4iv(name, value) {\r\n if (this.uniform4ivCache.hasOwnProperty(name)) {\r\n const cache = this.uniform4ivCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1] &&\r\n value[2] === cache[2] &&\r\n value[3] === cache[3]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform4ivCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform4iv(loc, value);\r\n }\r\n\r\n setUniform4fv(name, value) {\r\n if (this.uniform4fvCache.hasOwnProperty(name)) {\r\n const cache = this.uniform4fvCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1] &&\r\n value[2] === cache[2] &&\r\n value[3] === cache[3]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform4fvCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform4fv(loc, value);\r\n }\r\n\r\n /**\r\n * @desc Return WebGlUniformLocation for various variables\r\n * related to webGl program, such as user-defined variables,\r\n * as well as, dimension sizes, etc.\r\n */\r\n getUniformLocation(name) {\r\n if (this.programUniformLocationCache.hasOwnProperty(name)) {\r\n return this.programUniformLocationCache[name];\r\n }\r\n return this.programUniformLocationCache[name] = this.context.getUniformLocation(this.program, name);\r\n }\r\n\r\n /**\r\n * @desc Generate Shader artifacts for the kernel program.\r\n * The final object contains HEADER, KERNEL, MAIN_RESULT, and others.\r\n *\r\n * @param {Array} args - The actual parameters sent to the Kernel\r\n * @returns {Object} An object containing the Shader Artifacts(CONSTANTS, HEADER, KERNEL, etc.)\r\n */\r\n _getFragShaderArtifactMap(args) {\r\n return {\r\n HEADER: this._getHeaderString(),\r\n LOOP_MAX: this._getLoopMaxString(),\r\n PLUGINS: this._getPluginsString(),\r\n CONSTANTS: this._getConstantsString(),\r\n DECODE32_ENDIANNESS: this._getDecode32EndiannessString(),\r\n ENCODE32_ENDIANNESS: this._getEncode32EndiannessString(),\r\n DIVIDE_WITH_INTEGER_CHECK: this._getDivideWithIntegerCheckString(),\r\n INJECTED_NATIVE: this._getInjectedNative(),\r\n MAIN_CONSTANTS: this._getMainConstantsString(),\r\n MAIN_ARGUMENTS: this._getMainArgumentsString(args),\r\n KERNEL: this.getKernelString(),\r\n MAIN_RESULT: this.getMainResultString(),\r\n FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(),\r\n INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(),\r\n SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(),\r\n SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(),\r\n };\r\n }\r\n\r\n /**\r\n * @desc Generate Shader artifacts for the kernel program.\r\n * The final object contains HEADER, KERNEL, MAIN_RESULT, and others.\r\n *\r\n * @param {Array} args - The actual parameters sent to the Kernel\r\n * @returns {Object} An object containing the Shader Artifacts(CONSTANTS, HEADER, KERNEL, etc.)\r\n */\r\n _getVertShaderArtifactMap(args) {\r\n return {\r\n FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(),\r\n INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(),\r\n SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(),\r\n SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(),\r\n };\r\n }\r\n\r\n /**\r\n * @desc Get the header string for the program.\r\n * This returns an empty string if no sub-kernels are defined.\r\n *\r\n * @returns {String} result\r\n */\r\n _getHeaderString() {\r\n return (\r\n this.subKernels !== null ?\r\n '#extension GL_EXT_draw_buffers : require\\n' :\r\n ''\r\n );\r\n }\r\n\r\n /**\r\n * @desc Get the maximum loop size String.\r\n * @returns {String} result\r\n */\r\n _getLoopMaxString() {\r\n return (\r\n this.loopMaxIterations ?\r\n ` ${parseInt(this.loopMaxIterations)};\\n` :\r\n ' 1000;\\n'\r\n );\r\n }\r\n\r\n _getPluginsString() {\r\n if (!this.plugins) return '\\n';\r\n return this.plugins.map(plugin => plugin.source && this.source.match(plugin.functionMatch) ? plugin.source : '').join('\\n');\r\n }\r\n\r\n /**\r\n * @desc Generate transpiled glsl Strings for constant parameters sent to a kernel\r\n * @returns {String} result\r\n */\r\n _getConstantsString() {\r\n const result = [];\r\n const { threadDim, texSize } = this;\r\n if (this.dynamicOutput) {\r\n result.push(\r\n 'uniform ivec3 uOutputDim',\r\n 'uniform ivec2 uTexSize'\r\n );\r\n } else {\r\n result.push(\r\n `ivec3 uOutputDim = ivec3(${threadDim[0]}, ${threadDim[1]}, ${threadDim[2]})`,\r\n `ivec2 uTexSize = ivec2(${texSize[0]}, ${texSize[1]})`\r\n );\r\n }\r\n return utils.linesToString(result);\r\n }\r\n\r\n /**\r\n * @desc Get texture coordinate string for the program\r\n * @returns {String} result\r\n */\r\n _getTextureCoordinate() {\r\n const subKernels = this.subKernels;\r\n if (subKernels === null || subKernels.length < 1) {\r\n return 'varying vec2 vTexCoord;\\n';\r\n } else {\r\n return 'out vec2 vTexCoord;\\n';\r\n }\r\n }\r\n\r\n /**\r\n * @desc Get Decode32 endianness string for little-endian and big-endian\r\n * @returns {String} result\r\n */\r\n _getDecode32EndiannessString() {\r\n return (\r\n this.endianness === 'LE' ?\r\n '' :\r\n ' texel.rgba = texel.abgr;\\n'\r\n );\r\n }\r\n\r\n /**\r\n * @desc Get Encode32 endianness string for little-endian and big-endian\r\n * @returns {String} result\r\n */\r\n _getEncode32EndiannessString() {\r\n return (\r\n this.endianness === 'LE' ?\r\n '' :\r\n ' texel.rgba = texel.abgr;\\n'\r\n );\r\n }\r\n\r\n /**\r\n * @desc if fixIntegerDivisionAccuracy provide method to replace /\r\n * @returns {String} result\r\n */\r\n _getDivideWithIntegerCheckString() {\r\n return this.fixIntegerDivisionAccuracy ?\r\n `float div_with_int_check(float x, float y) {\r\n if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) {\r\n return float(int(x)/int(y));\r\n }\r\n return x / y;\r\n}` :\r\n '';\r\n }\r\n\r\n /**\r\n * @desc Generate transpiled glsl Strings for user-defined parameters sent to a kernel\r\n * @param {Array} args - The actual parameters sent to the Kernel\r\n * @returns {String} result\r\n */\r\n _getMainArgumentsString(args) {\r\n const results = [];\r\n const { argumentNames } = this;\r\n for (let i = 0; i < argumentNames.length; i++) {\r\n results.push(this.kernelArguments[i].getSource(args[i]));\r\n }\r\n return results.join('');\r\n }\r\n\r\n _getInjectedNative() {\r\n return this.injectedNative || '';\r\n }\r\n\r\n _getMainConstantsString() {\r\n const result = [];\r\n const { constants } = this;\r\n if (constants) {\r\n let i = 0;\r\n for (const name in constants) {\r\n result.push(this.kernelConstants[i++].getSource(this.constants[name]));\r\n }\r\n }\r\n return result.join('');\r\n }\r\n\r\n /**\r\n * @desc Get Kernel program string (in *glsl*) for a kernel.\r\n * @returns {String} result\r\n */\r\n getKernelString() {\r\n let kernelResultDeclaration;\r\n switch (this.returnType) {\r\n case 'Array(2)':\r\n kernelResultDeclaration = 'vec2 kernelResult';\r\n break;\r\n case 'Array(3)':\r\n kernelResultDeclaration = 'vec3 kernelResult';\r\n break;\r\n case 'Array(4)':\r\n kernelResultDeclaration = 'vec4 kernelResult';\r\n break;\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n kernelResultDeclaration = 'float kernelResult';\r\n break;\r\n default:\r\n if (this.graphical) {\r\n kernelResultDeclaration = 'float kernelResult';\r\n } else {\r\n throw new Error(`unrecognized output type \"${ this.returnType }\"`);\r\n }\r\n }\r\n\r\n const result = [];\r\n const subKernels = this.subKernels;\r\n if (subKernels !== null) {\r\n result.push(\r\n kernelResultDeclaration\r\n );\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Float':\r\n case 'Integer':\r\n for (let i = 0; i < subKernels.length; i++) {\r\n const subKernel = subKernels[i];\r\n result.push(\r\n subKernel.returnType === 'Integer' ?\r\n `int subKernelResult_${ subKernel.name } = 0` :\r\n `float subKernelResult_${ subKernel.name } = 0.0`\r\n );\r\n }\r\n break;\r\n case 'Array(2)':\r\n for (let i = 0; i < subKernels.length; i++) {\r\n result.push(\r\n `vec2 subKernelResult_${ subKernels[i].name }`\r\n );\r\n }\r\n break;\r\n case 'Array(3)':\r\n for (let i = 0; i < subKernels.length; i++) {\r\n result.push(\r\n `vec3 subKernelResult_${ subKernels[i].name }`\r\n );\r\n }\r\n break;\r\n case 'Array(4)':\r\n for (let i = 0; i < subKernels.length; i++) {\r\n result.push(\r\n `vec4 subKernelResult_${ subKernels[i].name }`\r\n );\r\n }\r\n break;\r\n }\r\n } else {\r\n result.push(\r\n kernelResultDeclaration\r\n );\r\n }\r\n\r\n return utils.linesToString(result) + this.translatedSource;\r\n }\r\n\r\n getMainResultGraphical() {\r\n return utils.linesToString([\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' gl_FragColor = actualColor',\r\n ]);\r\n }\r\n\r\n getMainResultPackedPixels() {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n return this.getMainResultKernelPackedPixels() +\r\n this.getMainResultSubKernelPackedPixels();\r\n default:\r\n throw new Error(`packed output only usable with Numbers, \"${this.returnType}\" specified`);\r\n }\r\n }\r\n\r\n /**\r\n * @return {String}\r\n */\r\n getMainResultKernelPackedPixels() {\r\n return utils.linesToString([\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ` gl_FragData[0] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)`\r\n ]);\r\n }\r\n\r\n /**\r\n * @return {String}\r\n */\r\n getMainResultSubKernelPackedPixels() {\r\n const result = [];\r\n if (!this.subKernels) return '';\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))`\r\n );\r\n } else {\r\n result.push(\r\n ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})`\r\n );\r\n }\r\n }\r\n return utils.linesToString(result);\r\n }\r\n\r\n getMainResultMemoryOptimizedFloats() {\r\n const result = [\r\n ' index *= 4',\r\n ];\r\n\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n const channels = ['r', 'g', 'b', 'a'];\r\n for (let i = 0; i < channels.length; i++) {\r\n const channel = channels[i];\r\n this.getMainResultKernelMemoryOptimizedFloats(result, channel);\r\n this.getMainResultSubKernelMemoryOptimizedFloats(result, channel);\r\n if (i + 1 < channels.length) {\r\n result.push(' index += 1');\r\n }\r\n }\r\n break;\r\n default:\r\n throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`);\r\n }\r\n\r\n return utils.linesToString(result);\r\n }\r\n\r\n getMainResultKernelMemoryOptimizedFloats(result, channel) {\r\n result.push(\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ` gl_FragData[0].${channel} = kernelResult`,\r\n );\r\n }\r\n\r\n getMainResultSubKernelMemoryOptimizedFloats(result, channel) {\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` gl_FragData[${i + 1}].${channel} = float(subKernelResult_${this.subKernels[i].name})`,\r\n );\r\n } else {\r\n result.push(\r\n ` gl_FragData[${i + 1}].${channel} = subKernelResult_${this.subKernels[i].name}`,\r\n );\r\n }\r\n }\r\n }\r\n\r\n getMainResultKernelNumberTexture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' gl_FragData[0][0] = kernelResult',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelNumberTexture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = float(subKernelResult_${subKernel.name})`,\r\n );\r\n } else {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${subKernel.name}`,\r\n );\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray2Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' gl_FragData[0][0] = kernelResult[0]',\r\n ' gl_FragData[0][1] = kernelResult[1]',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray2Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,\r\n ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray3Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' gl_FragData[0][0] = kernelResult[0]',\r\n ' gl_FragData[0][1] = kernelResult[1]',\r\n ' gl_FragData[0][2] = kernelResult[2]',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray3Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,\r\n ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,\r\n ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`,\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray4Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' gl_FragData[0] = kernelResult',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray4Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Float':\r\n case 'Integer':\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` gl_FragData[${i + 1}] = float(subKernelResult_${this.subKernels[i].name})`,\r\n );\r\n } else {\r\n result.push(\r\n ` gl_FragData[${i + 1}] = subKernelResult_${this.subKernels[i].name}`,\r\n );\r\n }\r\n }\r\n break;\r\n case 'Array(2)':\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,\r\n ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,\r\n );\r\n }\r\n break;\r\n case 'Array(3)':\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,\r\n ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,\r\n ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`,\r\n );\r\n }\r\n break;\r\n case 'Array(4)':\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,\r\n ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,\r\n ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`,\r\n ` gl_FragData[${i + 1}][3] = subKernelResult_${this.subKernels[i].name}[3]`,\r\n );\r\n }\r\n break;\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * @param {String} src - Shader string\r\n * @param {Object} map - Variables/Constants associated with shader\r\n */\r\n replaceArtifacts(src, map) {\r\n return src.replace(/[ ]*__([A-Z]+[0-9]*([_]?[A-Z]*[0-9]?)*)__;\\n/g, (match, artifact) => {\r\n if (map.hasOwnProperty(artifact)) {\r\n return map[artifact];\r\n }\r\n throw `unhandled artifact ${artifact}`;\r\n });\r\n }\r\n\r\n /**\r\n * @desc Get the fragment shader String.\r\n * If the String hasn't been compiled yet,\r\n * then this method compiles it as well\r\n *\r\n * @param {Array} args - The actual parameters sent to the Kernel\r\n * @returns {string} Fragment Shader string\r\n */\r\n getFragmentShader(args) {\r\n if (this.compiledFragmentShader !== null) {\r\n return this.compiledFragmentShader;\r\n }\r\n return this.compiledFragmentShader = this.replaceArtifacts(this.constructor.fragmentShader, this._getFragShaderArtifactMap(args));\r\n }\r\n\r\n /**\r\n * @desc Get the vertical shader String\r\n * @param {Array|IArguments} args - The actual parameters sent to the Kernel\r\n * @returns {string} Vertical Shader string\r\n */\r\n getVertexShader(args) {\r\n if (this.compiledVertexShader !== null) {\r\n return this.compiledVertexShader;\r\n }\r\n return this.compiledVertexShader = this.replaceArtifacts(this.constructor.vertexShader, this._getVertShaderArtifactMap(args));\r\n }\r\n\r\n /**\r\n * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused.\r\n */\r\n toString() {\r\n const setupContextString = utils.linesToString([\r\n `const gl = context`,\r\n ]);\r\n return glKernelString(this.constructor, arguments, this, setupContextString);\r\n }\r\n\r\n destroy(removeCanvasReferences) {\r\n if (this.outputTexture) {\r\n this.context.deleteTexture(this.outputTexture);\r\n }\r\n if (this.buffer) {\r\n this.context.deleteBuffer(this.buffer);\r\n }\r\n if (this.framebuffer) {\r\n this.context.deleteFramebuffer(this.framebuffer);\r\n }\r\n if (this.vertShader) {\r\n this.context.deleteShader(this.vertShader);\r\n }\r\n if (this.fragShader) {\r\n this.context.deleteShader(this.fragShader);\r\n }\r\n if (this.program) {\r\n this.context.deleteProgram(this.program);\r\n }\r\n\r\n const keys = Object.keys(this.textureCache);\r\n\r\n for (let i = 0; i < keys.length; i++) {\r\n const name = keys[i];\r\n this.context.deleteTexture(this.textureCache[name]);\r\n }\r\n\r\n if (this.subKernelOutputTextures) {\r\n for (let i = 0; i < this.subKernelOutputTextures.length; i++) {\r\n this.context.deleteTexture(this.subKernelOutputTextures[i]);\r\n }\r\n }\r\n if (removeCanvasReferences) {\r\n const idx = canvases.indexOf(this.canvas);\r\n if (idx >= 0) {\r\n canvases[idx] = null;\r\n maxTexSizes[idx] = null;\r\n }\r\n }\r\n this.destroyExtensions();\r\n delete this.context;\r\n delete this.canvas;\r\n }\r\n\r\n destroyExtensions() {\r\n this.extensions.OES_texture_float = null;\r\n this.extensions.OES_texture_float_linear = null;\r\n this.extensions.OES_element_index_uint = null;\r\n this.extensions.WEBGL_draw_buffers = null;\r\n }\r\n\r\n static destroyContext(context) {\r\n const extension = context.getExtension('WEBGL_lose_context');\r\n if (extension) {\r\n extension.loseContext();\r\n }\r\n }\r\n\r\n toJSON() {\r\n const json = super.toJSON();\r\n json.functionNodes = FunctionBuilder.fromKernel(this, WebGLFunctionNode).toJSON();\r\n return json;\r\n }\r\n}\r\n","import { WebGLFunctionNode } from '../web-gl/function-node';\r\n\r\n/**\r\n * @class WebGL2FunctionNode\r\n * @desc [INTERNAL] Takes in a function node, and does all the AST voodoo required to toString its respective webGL code.\r\n * @extends WebGLFunctionNode\r\n * @returns the converted webGL function string\r\n */\r\nexport class WebGL2FunctionNode extends WebGLFunctionNode {\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *identifier* expression\r\n * @param {Object} idtNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astIdentifierExpression(idtNode, retArr) {\r\n if (idtNode.type !== 'Identifier') {\r\n throw this.astErrorOutput(\r\n 'IdentifierExpression - not an Identifier',\r\n idtNode\r\n );\r\n }\r\n\r\n const type = this.getType(idtNode);\r\n\r\n if (idtNode.name === 'Infinity') {\r\n retArr.push('intBitsToFloat(2139095039)');\r\n } else if (type === 'Boolean') {\r\n if (this.argumentNames.indexOf(idtNode.name) > -1) {\r\n retArr.push(`bool(user_${idtNode.name})`);\r\n } else {\r\n retArr.push(`user_${idtNode.name}`);\r\n }\r\n } else {\r\n retArr.push(`user_${idtNode.name}`);\r\n }\r\n\r\n return retArr;\r\n }\r\n}\r\n","// language=GLSL\r\nexport const fragmentShader = `#version 300 es\r\n__HEADER__;\r\n__FLOAT_TACTIC_DECLARATION__;\r\n__INT_TACTIC_DECLARATION__;\r\n__SAMPLER_2D_TACTIC_DECLARATION__;\r\n__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__;\r\n\r\nconst int LOOP_MAX = __LOOP_MAX__;\r\n\r\n__PLUGINS__;\r\n__CONSTANTS__;\r\n\r\nin vec2 vTexCoord;\r\n\r\nconst int BIT_COUNT = 32;\r\nint modi(int x, int y) {\r\n return x - y * (x / y);\r\n}\r\n\r\nint bitwiseOr(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 || b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseXOR(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 || b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseAnd(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 && b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseNot(int a) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (modi(a, 2) == 0) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n n = n * 2;\r\n }\r\n return result;\r\n}\r\nint bitwiseZeroFillLeftShift(int n, int shift) {\r\n int maxBytes = BIT_COUNT;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (maxBytes >= n) {\r\n break;\r\n }\r\n maxBytes *= 2;\r\n }\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= shift) {\r\n break;\r\n }\r\n n *= 2;\r\n }\r\n\r\n int result = 0;\r\n int byteVal = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= maxBytes) break;\r\n if (modi(n, 2) > 0) { result += byteVal; }\r\n n = int(n / 2);\r\n byteVal *= 2;\r\n }\r\n return result;\r\n}\r\n\r\nint bitwiseSignedRightShift(int num, int shifts) {\r\n return int(floor(float(num) / pow(2.0, float(shifts))));\r\n}\r\n\r\nint bitwiseZeroFillRightShift(int n, int shift) {\r\n int maxBytes = BIT_COUNT;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (maxBytes >= n) {\r\n break;\r\n }\r\n maxBytes *= 2;\r\n }\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= shift) {\r\n break;\r\n }\r\n n /= 2;\r\n }\r\n int result = 0;\r\n int byteVal = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= maxBytes) break;\r\n if (modi(n, 2) > 0) { result += byteVal; }\r\n n = int(n / 2);\r\n byteVal *= 2;\r\n }\r\n return result;\r\n}\r\n\r\nvec2 integerMod(vec2 x, float y) {\r\n vec2 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nvec3 integerMod(vec3 x, float y) {\r\n vec3 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nvec4 integerMod(vec4 x, vec4 y) {\r\n vec4 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nfloat integerMod(float x, float y) {\r\n float res = floor(mod(x, y));\r\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\r\n}\r\n\r\nint integerMod(int x, int y) {\r\n return x - (y * int(x/y));\r\n}\r\n\r\n__DIVIDE_WITH_INTEGER_CHECK__;\r\n\r\n// Here be dragons!\r\n// DO NOT OPTIMIZE THIS CODE\r\n// YOU WILL BREAK SOMETHING ON SOMEBODY\\'S MACHINE\r\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\r\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\r\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\r\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\r\nfloat decode32(vec4 texel) {\r\n __DECODE32_ENDIANNESS__;\r\n texel *= 255.0;\r\n vec2 gte128;\r\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\r\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\r\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\r\n float res = exp2(round(exponent));\r\n texel.b = texel.b - 128.0 * gte128.x;\r\n res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;\r\n res *= gte128.y * -2.0 + 1.0;\r\n return res;\r\n}\r\n\r\nfloat decode16(vec4 texel, int index) {\r\n int channel = integerMod(index, 2);\r\n return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0;\r\n}\r\n\r\nfloat decode8(vec4 texel, int index) {\r\n int channel = integerMod(index, 4);\r\n return texel[channel] * 255.0;\r\n}\r\n\r\nvec4 legacyEncode32(float f) {\r\n float F = abs(f);\r\n float sign = f < 0.0 ? 1.0 : 0.0;\r\n float exponent = floor(log2(F));\r\n float mantissa = (exp2(-exponent) * F);\r\n // exponent += floor(log2(mantissa));\r\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\r\n texel.rg = integerMod(texel.rg, 256.0);\r\n texel.b = integerMod(texel.b, 128.0);\r\n texel.a = exponent*0.5 + 63.5;\r\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\r\n texel = floor(texel);\r\n texel *= 0.003921569; // 1/255\r\n __ENCODE32_ENDIANNESS__;\r\n return texel;\r\n}\r\n\r\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\r\nvec4 encode32(float value) {\r\n if (value == 0.0) return vec4(0, 0, 0, 0);\r\n\r\n float exponent;\r\n float mantissa;\r\n vec4 result;\r\n float sgn;\r\n\r\n sgn = step(0.0, -value);\r\n value = abs(value);\r\n\r\n exponent = floor(log2(value));\r\n\r\n mantissa = value*pow(2.0, -exponent)-1.0;\r\n exponent = exponent+127.0;\r\n result = vec4(0,0,0,0);\r\n\r\n result.a = floor(exponent/2.0);\r\n exponent = exponent - result.a*2.0;\r\n result.a = result.a + 128.0*sgn;\r\n\r\n result.b = floor(mantissa * 128.0);\r\n mantissa = mantissa - result.b / 128.0;\r\n result.b = result.b + exponent*128.0;\r\n\r\n result.g = floor(mantissa*32768.0);\r\n mantissa = mantissa - result.g/32768.0;\r\n\r\n result.r = floor(mantissa*8388608.0);\r\n return result/255.0;\r\n}\r\n// Dragons end here\r\n\r\nint index;\r\nivec3 threadId;\r\n\r\nivec3 indexTo3D(int idx, ivec3 texDim) {\r\n int z = int(idx / (texDim.x * texDim.y));\r\n idx -= z * int(texDim.x * texDim.y);\r\n int y = int(idx / texDim.x);\r\n int x = int(integerMod(idx, texDim.x));\r\n return ivec3(x, y, z);\r\n}\r\n\r\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture(tex, st / vec2(texSize));\r\n return decode32(texel);\r\n}\r\n\r\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + (texDim.x * (y + (texDim.y * z)));\r\n int w = texSize.x * 2;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y));\r\n return decode16(texel, index);\r\n}\r\n\r\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + (texDim.x * (y + (texDim.y * z)));\r\n int w = texSize.x * 4;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y));\r\n return decode8(texel, index);\r\n}\r\n\r\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + (texDim.x * (y + (texDim.y * z)));\r\n int channel = integerMod(index, 4);\r\n index = index / 4;\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n index = index / 4;\r\n vec4 texel = texture(tex, st / vec2(texSize));\r\n return texel[channel];\r\n}\r\n\r\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n return texture(tex, st / vec2(texSize));\r\n}\r\n\r\nvec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n return texture(tex, vec3(st / vec2(texSize), z));\r\n}\r\n\r\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return result[0];\r\n}\r\n\r\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return vec2(result[0], result[1]);\r\n}\r\n\r\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int channel = integerMod(index, 2);\r\n index = index / 2;\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture(tex, st / vec2(texSize));\r\n if (channel == 0) return vec2(texel.r, texel.g);\r\n if (channel == 1) return vec2(texel.b, texel.a);\r\n return vec2(0.0, 0.0);\r\n}\r\n\r\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return vec3(result[0], result[1], result[2]);\r\n}\r\n\r\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\r\n int vectorIndex = fieldIndex / 4;\r\n int vectorOffset = fieldIndex - vectorIndex * 4;\r\n int readY = vectorIndex / texSize.x;\r\n int readX = vectorIndex - readY * texSize.x;\r\n vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\r\n\r\n if (vectorOffset == 0) {\r\n return tex1.xyz;\r\n } else if (vectorOffset == 1) {\r\n return tex1.yzw;\r\n } else {\r\n readX++;\r\n if (readX >= texSize.x) {\r\n readX = 0;\r\n readY++;\r\n }\r\n vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize));\r\n if (vectorOffset == 2) {\r\n return vec3(tex1.z, tex1.w, tex2.x);\r\n } else {\r\n return vec3(tex1.w, tex2.x, tex2.y);\r\n }\r\n }\r\n}\r\n\r\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n return getImage2D(tex, texSize, texDim, z, y, x);\r\n}\r\n\r\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int channel = integerMod(index, 2);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture(tex, st / vec2(texSize));\r\n return vec4(texel.r, texel.g, texel.b, texel.a);\r\n}\r\n\r\nvec4 actualColor;\r\nvoid color(float r, float g, float b, float a) {\r\n actualColor = vec4(r,g,b,a);\r\n}\r\n\r\nvoid color(float r, float g, float b) {\r\n color(r,g,b,1.0);\r\n}\r\n\r\n__INJECTED_NATIVE__;\r\n__MAIN_CONSTANTS__;\r\n__MAIN_ARGUMENTS__;\r\n__KERNEL__;\r\n\r\nvoid main(void) {\r\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\r\n __MAIN_RESULT__;\r\n}`;\r\n","// language=GLSL\r\nexport const vertexShader = `#version 300 es\r\n__FLOAT_TACTIC_DECLARATION__;\r\n__INT_TACTIC_DECLARATION__;\r\n__SAMPLER_2D_TACTIC_DECLARATION__;\r\n\r\nin vec2 aPos;\r\nin vec2 aTexCoord;\r\n\r\nout vec2 vTexCoord;\r\nuniform vec2 ratio;\r\n\r\nvoid main(void) {\r\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\r\n vTexCoord = aTexCoord;\r\n}`;\r\n","import { WebGLKernelValueBoolean } from '../../web-gl/kernel-value/boolean';\r\n\r\nexport class WebGL2KernelValueBoolean extends WebGLKernelValueBoolean {}\r\n","import { WebGLKernelValueFloat } from '../../web-gl/kernel-value/float';\r\n\r\nexport class WebGL2KernelValueFloat extends WebGLKernelValueFloat {}\r\n","import { WebGLKernelValueInteger } from '../../web-gl/kernel-value/integer';\r\n\r\nexport class WebGL2KernelValueInteger extends WebGLKernelValueInteger {\r\n getSource(value) {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n if (this.origin === 'constants') {\r\n return `const ${ variablePrecision } int ${this.id} = ${ parseInt(value) };\\n`;\r\n }\r\n return `uniform ${ variablePrecision } int ${this.id};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform1i(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueHTMLImage } from '../../web-gl/kernel-value/html-image';\r\n\r\nexport class WebGL2KernelValueHTMLImage extends WebGLKernelValueHTMLImage {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueDynamicHTMLImage } from '../../web-gl/kernel-value/dynamic-html-image';\r\n\r\nexport class WebGL2KernelValueDynamicHTMLImage extends WebGLKernelValueDynamicHTMLImage {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from '../../web-gl/kernel-value/index';\r\n\r\nexport class WebGL2KernelValueHTMLImageArray extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.checkSize(value[0].width, value[0].height);\r\n this.requestTexture();\r\n this.dimensions = [value[0].width, value[0].height, value.length];\r\n this.textureSize = [value[0].width, value[0].height];\r\n }\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2DArray ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(images) {\r\n const { context: gl } = this;\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\r\n // Upload the images into the texture.\r\n gl.texImage3D(\r\n gl.TEXTURE_2D_ARRAY,\r\n 0,\r\n gl.RGBA,\r\n images[0].width,\r\n images[0].height,\r\n images.length,\r\n 0,\r\n gl.RGBA,\r\n gl.UNSIGNED_BYTE,\r\n null\r\n );\r\n for (let i = 0; i < images.length; i++) {\r\n const xOffset = 0;\r\n const yOffset = 0;\r\n const imageDepth = 1;\r\n gl.texSubImage3D(\r\n gl.TEXTURE_2D_ARRAY,\r\n 0,\r\n xOffset,\r\n yOffset,\r\n i,\r\n images[i].width,\r\n images[i].height,\r\n imageDepth,\r\n gl.RGBA,\r\n gl.UNSIGNED_BYTE,\r\n this.uploadValue = images[i]\r\n );\r\n }\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { WebGL2KernelValueHTMLImageArray } from './html-image-array';\r\n\r\nexport class WebGL2KernelValueDynamicHTMLImageArray extends WebGL2KernelValueHTMLImageArray {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2DArray ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(images) {\r\n const { width, height } = images[0];\r\n this.checkSize(width, height);\r\n this.dimensions = [width, height, images.length];\r\n this.textureSize = [width, height];\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(images);\r\n }\r\n}\r\n","import { WebGL2KernelValueHTMLImage } from './html-image';\r\n\r\nexport class WebGL2KernelValueHTMLVideo extends WebGL2KernelValueHTMLImage {}\r\n","import { WebGL2KernelValueDynamicHTMLImage } from './dynamic-html-image';\r\n\r\nexport class WebGL2KernelValueDynamicHTMLVideo extends WebGL2KernelValueDynamicHTMLImage {}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleInput } from '../../web-gl/kernel-value/single-input';\r\n\r\nexport class WebGL2KernelValueSingleInput extends WebGLKernelValueSingleInput {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(input) {\r\n const { context: gl } = this;\r\n utils.flattenTo(input.value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } from '../../web-gl/kernel-value/dynamic-memory-optimized-number-texture';\r\n\r\nexport class WebGL2KernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueDynamicMemoryOptimizedNumberTexture {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueNumberTexture } from '../../web-gl/kernel-value/number-texture';\r\n\r\nexport class WebGL2KernelValueNumberTexture extends WebGLKernelValueNumberTexture {\r\n getSource() {\r\n const { id, sizeId, textureSize, dimensionsId, dimensions } = this;\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${id}`,\r\n `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueDynamicNumberTexture } from '../../web-gl/kernel-value/dynamic-number-texture';\r\n\r\nexport class WebGL2KernelValueDynamicNumberTexture extends WebGLKernelValueDynamicNumberTexture {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray } from '../../web-gl/kernel-value/single-array';\r\n\r\nexport class WebGL2KernelValueSingleArray extends WebGLKernelValueSingleArray {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray1DI } from '../../web-gl/kernel-value/single-array1d-i';\r\n\r\nexport class WebGL2KernelValueSingleArray1DI extends WebGLKernelValueSingleArray1DI {\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGL2KernelValueSingleArray1DI } from '../../web-gl2/kernel-value/single-array1d-i';\r\n\r\nexport class WebGL2KernelValueDynamicSingleArray1DI extends WebGL2KernelValueSingleArray1DI {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray2DI } from '../../web-gl/kernel-value/single-array2d-i';\r\n\r\nexport class WebGL2KernelValueSingleArray2DI extends WebGLKernelValueSingleArray2DI {\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGL2KernelValueSingleArray2DI } from '../../web-gl2/kernel-value/single-array2d-i';\r\n\r\nexport class WebGL2KernelValueDynamicSingleArray2DI extends WebGL2KernelValueSingleArray2DI {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray3DI } from '../../web-gl/kernel-value/single-array3d-i';\r\n\r\nexport class WebGL2KernelValueSingleArray3DI extends WebGLKernelValueSingleArray3DI {\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGL2KernelValueSingleArray3DI } from '../../web-gl2/kernel-value/single-array3d-i';\r\n\r\nexport class WebGL2KernelValueDynamicSingleArray3DI extends WebGL2KernelValueSingleArray3DI {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { WebGLKernelValueSingleArray2 } from '../../web-gl/kernel-value/single-array2';\r\n\r\nexport class WebGL2KernelValueSingleArray2 extends WebGLKernelValueSingleArray2 {}\r\n","import { WebGLKernelValueSingleArray3 } from '../../web-gl/kernel-value/single-array3';\r\n\r\nexport class WebGL2KernelValueSingleArray3 extends WebGLKernelValueSingleArray3 {}\r\n","import { WebGLKernelValueSingleArray4 } from '../../web-gl/kernel-value/single-array4';\r\n\r\nexport class WebGL2KernelValueSingleArray4 extends WebGLKernelValueSingleArray4 {}\r\n","import { WebGL2KernelValueBoolean } from './kernel-value/boolean';\r\nimport { WebGL2KernelValueFloat } from './kernel-value/float';\r\nimport { WebGL2KernelValueInteger } from './kernel-value/integer';\r\n\r\nimport { WebGL2KernelValueHTMLImage } from './kernel-value/html-image';\r\nimport { WebGL2KernelValueDynamicHTMLImage } from './kernel-value/dynamic-html-image';\r\n\r\nimport { WebGL2KernelValueHTMLImageArray } from './kernel-value/html-image-array';\r\nimport { WebGL2KernelValueDynamicHTMLImageArray } from './kernel-value/dynamic-html-image-array';\r\n\r\nimport { WebGL2KernelValueHTMLVideo } from './kernel-value/html-video';\r\nimport { WebGL2KernelValueDynamicHTMLVideo } from './kernel-value/dynamic-html-video';\r\n\r\nimport { WebGL2KernelValueSingleInput } from './kernel-value/single-input';\r\nimport { WebGL2KernelValueDynamicSingleInput } from './kernel-value/dynamic-single-input';\r\n\r\nimport { WebGL2KernelValueUnsignedInput } from './kernel-value/unsigned-input';\r\nimport { WebGL2KernelValueDynamicUnsignedInput } from './kernel-value/dynamic-unsigned-input';\r\n\r\nimport { WebGL2KernelValueMemoryOptimizedNumberTexture } from './kernel-value/memory-optimized-number-texture';\r\nimport { WebGL2KernelValueDynamicMemoryOptimizedNumberTexture } from './kernel-value/dynamic-memory-optimized-number-texture';\r\n\r\nimport { WebGL2KernelValueNumberTexture } from './kernel-value/number-texture';\r\nimport { WebGL2KernelValueDynamicNumberTexture } from './kernel-value/dynamic-number-texture';\r\n\r\nimport { WebGL2KernelValueSingleArray } from './kernel-value/single-array';\r\nimport { WebGL2KernelValueDynamicSingleArray } from './kernel-value/dynamic-single-array';\r\n\r\nimport { WebGL2KernelValueSingleArray1DI } from './kernel-value/single-array1d-i';\r\nimport { WebGL2KernelValueDynamicSingleArray1DI } from './kernel-value/dynamic-single-array1d-i';\r\n\r\nimport { WebGL2KernelValueSingleArray2DI } from './kernel-value/single-array2d-i';\r\nimport { WebGL2KernelValueDynamicSingleArray2DI } from './kernel-value/dynamic-single-array2d-i';\r\n\r\nimport { WebGL2KernelValueSingleArray3DI } from './kernel-value/single-array3d-i';\r\nimport { WebGL2KernelValueDynamicSingleArray3DI } from './kernel-value/dynamic-single-array3d-i';\r\n\r\nimport { WebGL2KernelValueSingleArray2 } from './kernel-value/single-array2';\r\nimport { WebGL2KernelValueSingleArray3 } from './kernel-value/single-array3';\r\nimport { WebGL2KernelValueSingleArray4 } from './kernel-value/single-array4';\r\n\r\nimport { WebGL2KernelValueUnsignedArray } from './kernel-value/unsigned-array';\r\nimport { WebGL2KernelValueDynamicUnsignedArray } from './kernel-value/dynamic-unsigned-array';\r\n\r\nexport const kernelValueMaps = {\r\n unsigned: {\r\n dynamic: {\r\n 'Boolean': WebGL2KernelValueBoolean,\r\n 'Integer': WebGL2KernelValueInteger,\r\n 'Float': WebGL2KernelValueFloat,\r\n 'Array': WebGL2KernelValueDynamicUnsignedArray,\r\n 'Array(2)': false,\r\n 'Array(3)': false,\r\n 'Array(4)': false,\r\n 'Array1D(2)': false,\r\n 'Array1D(3)': false,\r\n 'Array1D(4)': false,\r\n 'Array2D(2)': false,\r\n 'Array2D(3)': false,\r\n 'Array2D(4)': false,\r\n 'Array3D(2)': false,\r\n 'Array3D(3)': false,\r\n 'Array3D(4)': false,\r\n 'Input': WebGL2KernelValueDynamicUnsignedInput,\r\n 'NumberTexture': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGL2KernelValueDynamicHTMLImage,\r\n 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray,\r\n 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo,\r\n },\r\n static: {\r\n 'Boolean': WebGL2KernelValueBoolean,\r\n 'Float': WebGL2KernelValueFloat,\r\n 'Integer': WebGL2KernelValueInteger,\r\n 'Array': WebGL2KernelValueUnsignedArray,\r\n 'Array(2)': false,\r\n 'Array(3)': false,\r\n 'Array(4)': false,\r\n 'Array1D(2)': false,\r\n 'Array1D(3)': false,\r\n 'Array1D(4)': false,\r\n 'Array2D(2)': false,\r\n 'Array2D(3)': false,\r\n 'Array2D(4)': false,\r\n 'Array3D(2)': false,\r\n 'Array3D(3)': false,\r\n 'Array3D(4)': false,\r\n 'Input': WebGL2KernelValueUnsignedInput,\r\n 'NumberTexture': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(1)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(2)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(3)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(4)': WebGL2KernelValueNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGL2KernelValueHTMLImage,\r\n 'HTMLImageArray': WebGL2KernelValueHTMLImageArray,\r\n 'HTMLVideo': WebGL2KernelValueHTMLVideo,\r\n }\r\n },\r\n single: {\r\n dynamic: {\r\n 'Boolean': WebGL2KernelValueBoolean,\r\n 'Integer': WebGL2KernelValueInteger,\r\n 'Float': WebGL2KernelValueFloat,\r\n 'Array': WebGL2KernelValueDynamicSingleArray,\r\n 'Array(2)': WebGL2KernelValueSingleArray2,\r\n 'Array(3)': WebGL2KernelValueSingleArray3,\r\n 'Array(4)': WebGL2KernelValueSingleArray4,\r\n 'Array1D(2)': WebGL2KernelValueDynamicSingleArray1DI,\r\n 'Array1D(3)': WebGL2KernelValueDynamicSingleArray1DI,\r\n 'Array1D(4)': WebGL2KernelValueDynamicSingleArray1DI,\r\n 'Array2D(2)': WebGL2KernelValueDynamicSingleArray2DI,\r\n 'Array2D(3)': WebGL2KernelValueDynamicSingleArray2DI,\r\n 'Array2D(4)': WebGL2KernelValueDynamicSingleArray2DI,\r\n 'Array3D(2)': WebGL2KernelValueDynamicSingleArray3DI,\r\n 'Array3D(3)': WebGL2KernelValueDynamicSingleArray3DI,\r\n 'Array3D(4)': WebGL2KernelValueDynamicSingleArray3DI,\r\n 'Input': WebGL2KernelValueDynamicSingleInput,\r\n 'NumberTexture': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGL2KernelValueDynamicHTMLImage,\r\n 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray,\r\n 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo,\r\n },\r\n static: {\r\n 'Boolean': WebGL2KernelValueBoolean,\r\n 'Float': WebGL2KernelValueFloat,\r\n 'Integer': WebGL2KernelValueInteger,\r\n 'Array': WebGL2KernelValueSingleArray,\r\n 'Array(2)': WebGL2KernelValueSingleArray2,\r\n 'Array(3)': WebGL2KernelValueSingleArray3,\r\n 'Array(4)': WebGL2KernelValueSingleArray4,\r\n 'Array1D(2)': WebGL2KernelValueSingleArray1DI,\r\n 'Array1D(3)': WebGL2KernelValueSingleArray1DI,\r\n 'Array1D(4)': WebGL2KernelValueSingleArray1DI,\r\n 'Array2D(2)': WebGL2KernelValueSingleArray2DI,\r\n 'Array2D(3)': WebGL2KernelValueSingleArray2DI,\r\n 'Array2D(4)': WebGL2KernelValueSingleArray2DI,\r\n 'Array3D(2)': WebGL2KernelValueSingleArray3DI,\r\n 'Array3D(3)': WebGL2KernelValueSingleArray3DI,\r\n 'Array3D(4)': WebGL2KernelValueSingleArray3DI,\r\n 'Input': WebGL2KernelValueSingleInput,\r\n 'NumberTexture': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(1)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(2)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(3)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(4)': WebGL2KernelValueNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGL2KernelValueMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGL2KernelValueHTMLImage,\r\n 'HTMLImageArray': WebGL2KernelValueHTMLImageArray,\r\n 'HTMLVideo': WebGL2KernelValueHTMLVideo,\r\n }\r\n },\r\n};\r\n\r\nexport function lookupKernelValueType(type, dynamic, precision, value) {\r\n if (!type) {\r\n throw new Error('type missing');\r\n }\r\n if (!dynamic) {\r\n throw new Error('dynamic missing');\r\n }\r\n if (!precision) {\r\n throw new Error('precision missing');\r\n }\r\n if (value.type) {\r\n type = value.type;\r\n }\r\n const types = kernelValueMaps[precision][dynamic];\r\n if (types[type] === false) {\r\n return null;\r\n } else if (types[type] === undefined) {\r\n throw new Error(`Could not find a KernelValue for ${ type }`);\r\n }\r\n return types[type];\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueDynamicUnsignedArray } from '../../web-gl/kernel-value/dynamic-unsigned-array';\r\n\r\nexport class WebGL2KernelValueDynamicUnsignedArray extends WebGLKernelValueDynamicUnsignedArray {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueDynamicUnsignedInput } from '../../web-gl/kernel-value/dynamic-unsigned-input';\r\n\r\nexport class WebGL2KernelValueDynamicUnsignedInput extends WebGLKernelValueDynamicUnsignedInput {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueUnsignedArray } from '../../web-gl/kernel-value/unsigned-array';\r\n\r\nexport class WebGL2KernelValueUnsignedArray extends WebGLKernelValueUnsignedArray {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueUnsignedInput } from '../../web-gl/kernel-value/unsigned-input';\r\n\r\nexport class WebGL2KernelValueUnsignedInput extends WebGLKernelValueUnsignedInput {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGL2KernelValueSingleArray } from '../../web-gl2/kernel-value/single-array';\r\n\r\nexport class WebGL2KernelValueDynamicSingleArray extends WebGL2KernelValueSingleArray {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.dimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGL2KernelValueSingleInput } from '../../web-gl2/kernel-value/single-input';\r\n\r\nexport class WebGL2KernelValueDynamicSingleInput extends WebGL2KernelValueSingleInput {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n let [w, h, d] = value.size;\r\n this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueMemoryOptimizedNumberTexture } from '../../web-gl/kernel-value/memory-optimized-number-texture';\r\n\r\nexport class WebGL2KernelValueMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture {\r\n getSource() {\r\n const { id, sizeId, textureSize, dimensionsId, dimensions } = this;\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform sampler2D ${id}`,\r\n `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`,\r\n ]);\r\n }\r\n}\r\n","import { WebGLKernel } from '../web-gl/kernel';\r\nimport { WebGL2FunctionNode } from './function-node';\r\nimport { FunctionBuilder } from '../function-builder';\r\nimport { utils } from '../../utils';\r\nimport { fragmentShader } from './fragment-shader';\r\nimport { vertexShader } from './vertex-shader';\r\nimport { lookupKernelValueType } from './kernel-value-maps';\r\n\r\nlet isSupported = null;\r\nlet testCanvas = null;\r\nlet testContext = null;\r\nlet testExtensions = null;\r\n\r\n/**\r\n *\r\n * @type {IKernelFeatures}\r\n */\r\nlet features = null;\r\n\r\n/**\r\n * @extends WebGLKernel\r\n */\r\nexport class WebGL2Kernel extends WebGLKernel {\r\n static get isSupported() {\r\n if (isSupported !== null) {\r\n return isSupported;\r\n }\r\n this.setupFeatureChecks();\r\n isSupported = this.isContextMatch(testContext);\r\n return isSupported;\r\n }\r\n\r\n static setupFeatureChecks() {\r\n if (typeof document !== 'undefined') {\r\n testCanvas = document.createElement('canvas');\r\n } else if (typeof OffscreenCanvas !== 'undefined') {\r\n testCanvas = new OffscreenCanvas(0, 0);\r\n }\r\n if (!testCanvas) return;\r\n testContext = testCanvas.getContext('webgl2');\r\n if (!testContext || !testContext.getExtension) return;\r\n testExtensions = {\r\n EXT_color_buffer_float: testContext.getExtension('EXT_color_buffer_float'),\r\n OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'),\r\n };\r\n features = this.getFeatures();\r\n }\r\n\r\n static isContextMatch(context) {\r\n // from global\r\n if (typeof WebGL2RenderingContext !== 'undefined') {\r\n return context instanceof WebGL2RenderingContext;\r\n }\r\n return false;\r\n }\r\n\r\n static getFeatures() {\r\n return Object.freeze({\r\n isFloatRead: this.getIsFloatRead(),\r\n isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(),\r\n kernelMap: true,\r\n isTextureFloat: true,\r\n channelCount: this.getChannelCount(),\r\n maxTextureSize: this.getMaxTextureSize(),\r\n });\r\n }\r\n\r\n static getIsTextureFloat() {\r\n return true;\r\n }\r\n\r\n static getIsIntegerDivisionAccurate() {\r\n return super.getIsIntegerDivisionAccurate();\r\n }\r\n\r\n static getChannelCount() {\r\n return testContext.getParameter(testContext.MAX_DRAW_BUFFERS);\r\n }\r\n\r\n static getMaxTextureSize() {\r\n return testContext.getParameter(testContext.MAX_TEXTURE_SIZE);\r\n }\r\n\r\n static lookupKernelValueType(type, dynamic, precision, value) {\r\n return lookupKernelValueType(type, dynamic, precision, value);\r\n }\r\n\r\n static get testCanvas() {\r\n return testCanvas;\r\n }\r\n\r\n static get testContext() {\r\n return testContext;\r\n }\r\n\r\n /**\r\n *\r\n * @returns {{isFloatRead: Boolean, isIntegerDivisionAccurate: Boolean, kernelMap: Boolean, isTextureFloat: Boolean}}\r\n */\r\n static get features() {\r\n return features;\r\n }\r\n\r\n static get fragmentShader() {\r\n return fragmentShader;\r\n }\r\n static get vertexShader() {\r\n return vertexShader;\r\n }\r\n\r\n initContext() {\r\n const settings = {\r\n alpha: false,\r\n depth: false,\r\n antialias: false\r\n };\r\n const context = this.canvas.getContext('webgl2', settings);\r\n return context;\r\n }\r\n\r\n initExtensions() {\r\n this.extensions = {\r\n EXT_color_buffer_float: this.context.getExtension('EXT_color_buffer_float'),\r\n OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'),\r\n };\r\n }\r\n\r\n /**\r\n * @desc Validate settings related to Kernel, such as dimensions size, and auto output support.\r\n * @param {IArguments} args\r\n */\r\n validateSettings(args) {\r\n if (!this.validate) {\r\n this.texSize = utils.getKernelTextureSize({\r\n optimizeFloatMemory: this.optimizeFloatMemory,\r\n precision: this.precision,\r\n }, this.output);\r\n return;\r\n }\r\n\r\n const features = this.constructor.features;\r\n if (this.precision === 'single' && !features.isFloatRead) {\r\n throw new Error('Float texture outputs are not supported');\r\n } else if (!this.graphical && this.precision === null) {\r\n this.precision = features.isFloatRead ? 'single' : 'unsigned';\r\n }\r\n\r\n if (this.fixIntegerDivisionAccuracy === null) {\r\n this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate;\r\n } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) {\r\n this.fixIntegerDivisionAccuracy = false;\r\n }\r\n\r\n this.checkOutput();\r\n\r\n if (!this.output || this.output.length === 0) {\r\n if (args.length !== 1) {\r\n throw new Error('Auto output only supported for kernels with only one input');\r\n }\r\n\r\n const argType = utils.getVariableType(args[0], this.strictIntegers);\r\n switch (argType) {\r\n case 'Array':\r\n this.output = utils.getDimensions(argType);\r\n break;\r\n case 'NumberTexture':\r\n case 'MemoryOptimizedNumberTexture':\r\n case 'ArrayTexture(1)':\r\n case 'ArrayTexture(2)':\r\n case 'ArrayTexture(3)':\r\n case 'ArrayTexture(4)':\r\n this.output = args[0].output;\r\n break;\r\n default:\r\n throw new Error('Auto output not supported for input type: ' + argType);\r\n }\r\n }\r\n\r\n if (this.graphical) {\r\n if (this.output.length !== 2) {\r\n throw new Error('Output must have 2 dimensions on graphical mode');\r\n }\r\n\r\n if (this.precision === 'single') {\r\n console.warn('Cannot use graphical mode and single precision at the same time');\r\n this.precision = 'unsigned';\r\n }\r\n\r\n this.texSize = utils.clone(this.output);\r\n return;\r\n } else if (!this.graphical && this.precision === null && features.isTextureFloat) {\r\n this.precision = 'single';\r\n }\r\n\r\n this.texSize = utils.getKernelTextureSize({\r\n optimizeFloatMemory: this.optimizeFloatMemory,\r\n precision: this.precision,\r\n }, this.output);\r\n\r\n this.checkTextureSize();\r\n }\r\n\r\n translateSource() {\r\n const functionBuilder = FunctionBuilder.fromKernel(this, WebGL2FunctionNode, {\r\n fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy\r\n });\r\n this.translatedSource = functionBuilder.getPrototypeString('kernel');\r\n if (!this.graphical && !this.returnType) {\r\n this.returnType = functionBuilder.getKernelResultType();\r\n }\r\n\r\n if (this.subKernels && this.subKernels.length > 0) {\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (!subKernel.returnType) {\r\n subKernel.returnType = functionBuilder.getSubKernelResultType(i);\r\n }\r\n }\r\n }\r\n }\r\n\r\n run() {\r\n const { kernelArguments, texSize, forceUploadKernelConstants } = this;\r\n const gl = this.context;\r\n\r\n gl.useProgram(this.program);\r\n gl.scissor(0, 0, texSize[0], texSize[1]);\r\n\r\n if (this.dynamicOutput) {\r\n this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim));\r\n this.setUniform2iv('uTexSize', texSize);\r\n }\r\n\r\n this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]);\r\n\r\n this.switchingKernels = false;\r\n for (let i = 0; i < forceUploadKernelConstants.length; i++) {\r\n const constant = forceUploadKernelConstants[i];\r\n constant.updateValue(this.constants[constant.name]);\r\n if (this.switchingKernels) return;\r\n }\r\n for (let i = 0; i < kernelArguments.length; i++) {\r\n kernelArguments[i].updateValue(arguments[i]);\r\n if (this.switchingKernels) return;\r\n }\r\n\r\n if (this.plugins) {\r\n for (let i = 0; i < this.plugins.length; i++) {\r\n const plugin = this.plugins[i];\r\n if (plugin.onBeforeRun) {\r\n plugin.onBeforeRun(this);\r\n }\r\n }\r\n }\r\n\r\n if (this.graphical) {\r\n if (this.pipeline) {\r\n gl.bindRenderbuffer(gl.RENDERBUFFER, null);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n if (!this.outputTexture || this.immutable) {\r\n this._setupOutputTexture();\r\n }\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n return new this.TextureConstructor({\r\n texture: this.outputTexture,\r\n size: texSize,\r\n dimensions: this.threadDim,\r\n output: this.output,\r\n context: this.context\r\n });\r\n }\r\n gl.bindRenderbuffer(gl.RENDERBUFFER, null);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n return;\r\n }\r\n\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n if (this.immutable) {\r\n this._setupOutputTexture();\r\n }\r\n\r\n if (this.subKernels !== null) {\r\n if (this.immutable) {\r\n this._setupSubOutputTextures();\r\n }\r\n gl.drawBuffers(this.drawBuffersMap);\r\n }\r\n\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n }\r\n\r\n drawBuffers() {\r\n this.context.drawBuffers(this.drawBuffersMap);\r\n }\r\n\r\n getOutputTexture() {\r\n return this.outputTexture;\r\n }\r\n\r\n _setupOutputTexture() {\r\n const { texSize } = this;\r\n const gl = this.context;\r\n const texture = this.outputTexture = gl.createTexture();\r\n gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n if (this.precision === 'single') {\r\n if (this.pipeline) {\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Float':\r\n case 'Integer':\r\n if (this.optimizeFloatMemory) {\r\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]);\r\n } else {\r\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.R32F, texSize[0], texSize[1]);\r\n }\r\n break;\r\n case 'Array(2)':\r\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RG32F, texSize[0], texSize[1]);\r\n break;\r\n case 'Array(3)': // there is _no_ 3 channel format which is guaranteed to be color-renderable\r\n case 'Array(4)':\r\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]);\r\n break;\r\n default:\r\n throw new Error('Unhandled return type');\r\n }\r\n } else {\r\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]);\r\n }\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n }\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);\r\n }\r\n\r\n _setupSubOutputTextures() {\r\n const { texSize } = this;\r\n const gl = this.context;\r\n this.drawBuffersMap = [gl.COLOR_ATTACHMENT0];\r\n this.subKernelOutputTextures = [];\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const texture = this.context.createTexture();\r\n this.subKernelOutputTextures.push(texture);\r\n this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1);\r\n gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n // TODO: upgrade this\r\n if (this.precision === 'single') {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n }\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0);\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @desc Get the header string for the program.\r\n * This returns an empty string if no sub-kernels are defined.\r\n *\r\n * @returns {String} result\r\n */\r\n _getHeaderString() {\r\n return '';\r\n }\r\n\r\n /**\r\n * @desc Get texture coordinate string for the program\r\n * @returns {String} result\r\n */\r\n _getTextureCoordinate() {\r\n const subKernels = this.subKernels;\r\n if (subKernels === null || subKernels.length < 1) {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'in lowp vec2 vTexCoord;\\n';\r\n case 'performance':\r\n return 'in highp vec2 vTexCoord;\\n';\r\n case 'balanced':\r\n default:\r\n return 'in mediump vec2 vTexCoord;\\n';\r\n }\r\n } else {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'out lowp vec2 vTexCoord;\\n';\r\n case 'performance':\r\n return 'out highp vec2 vTexCoord;\\n';\r\n case 'balanced':\r\n default:\r\n return 'out mediump vec2 vTexCoord;\\n';\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @desc Generate transpiled glsl Strings for user-defined parameters sent to a kernel\r\n * @param {Array} args - The actual parameters sent to the Kernel\r\n * @returns {String} result\r\n */\r\n _getMainArgumentsString(args) {\r\n const result = [];\r\n const argumentNames = this.argumentNames;\r\n for (let i = 0; i < argumentNames.length; i++) {\r\n result.push(this.kernelArguments[i].getSource(args[i]));\r\n }\r\n return result.join('');\r\n }\r\n\r\n /**\r\n * @desc Get Kernel program string (in *glsl*) for a kernel.\r\n * @returns {String} result\r\n */\r\n getKernelString() {\r\n let kernelResultDeclaration;\r\n switch (this.returnType) {\r\n case 'Array(2)':\r\n kernelResultDeclaration = 'vec2 kernelResult';\r\n break;\r\n case 'Array(3)':\r\n kernelResultDeclaration = 'vec3 kernelResult';\r\n break;\r\n case 'Array(4)':\r\n kernelResultDeclaration = 'vec4 kernelResult';\r\n break;\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n kernelResultDeclaration = 'float kernelResult';\r\n break;\r\n default:\r\n if (this.graphical) {\r\n kernelResultDeclaration = 'float kernelResult';\r\n } else {\r\n throw new Error(`unrecognized output type \"${ this.returnType }\"`);\r\n }\r\n }\r\n\r\n const result = [];\r\n const subKernels = this.subKernels;\r\n if (subKernels !== null) {\r\n result.push(\r\n kernelResultDeclaration,\r\n 'layout(location = 0) out vec4 data0'\r\n );\r\n for (let i = 0; i < subKernels.length; i++) {\r\n const subKernel = subKernels[i];\r\n result.push(\r\n subKernel.returnType === 'Integer' ?\r\n `int subKernelResult_${ subKernel.name } = 0` :\r\n `float subKernelResult_${ subKernel.name } = 0.0`,\r\n `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }`\r\n );\r\n }\r\n } else {\r\n result.push(\r\n 'out vec4 data0',\r\n kernelResultDeclaration\r\n );\r\n }\r\n\r\n return utils.linesToString(result) + this.translatedSource;\r\n }\r\n\r\n getMainResultGraphical() {\r\n return utils.linesToString([\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' data0 = actualColor',\r\n ]);\r\n }\r\n\r\n getMainResultPackedPixels() {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n return this.getMainResultKernelPackedPixels() +\r\n this.getMainResultSubKernelPackedPixels();\r\n default:\r\n throw new Error(`packed output only usable with Numbers, \"${this.returnType}\" specified`);\r\n }\r\n }\r\n\r\n /**\r\n * @return {String}\r\n */\r\n getMainResultKernelPackedPixels() {\r\n return utils.linesToString([\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ` data0 = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)`\r\n ]);\r\n }\r\n\r\n /**\r\n * @return {String}\r\n */\r\n getMainResultSubKernelPackedPixels() {\r\n const result = [];\r\n if (!this.subKernels) return '';\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))`\r\n );\r\n } else {\r\n result.push(\r\n ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})`\r\n );\r\n }\r\n }\r\n return utils.linesToString(result);\r\n }\r\n\r\n getMainResultMemoryOptimizedFloats() {\r\n const result = [\r\n ' index *= 4',\r\n ];\r\n\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n const channels = ['r', 'g', 'b', 'a'];\r\n for (let i = 0; i < channels.length; i++) {\r\n const channel = channels[i];\r\n this.getMainResultKernelMemoryOptimizedFloats(result, channel);\r\n this.getMainResultSubKernelMemoryOptimizedFloats(result, channel);\r\n if (i + 1 < channels.length) {\r\n result.push(' index += 1');\r\n }\r\n }\r\n break;\r\n default:\r\n throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`);\r\n }\r\n\r\n return utils.linesToString(result);\r\n }\r\n\r\n getMainResultKernelMemoryOptimizedFloats(result, channel) {\r\n result.push(\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ` data0.${channel} = kernelResult`,\r\n );\r\n }\r\n\r\n getMainResultSubKernelMemoryOptimizedFloats(result, channel) {\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` data${i + 1}.${channel} = float(subKernelResult_${subKernel.name})`,\r\n );\r\n } else {\r\n result.push(\r\n ` data${i + 1}.${channel} = subKernelResult_${subKernel.name}`,\r\n );\r\n }\r\n }\r\n }\r\n\r\n getMainResultKernelNumberTexture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' data0[0] = kernelResult',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelNumberTexture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` data${i + 1}[0] = float(subKernelResult_${subKernel.name})`,\r\n );\r\n } else {\r\n result.push(\r\n ` data${i + 1}[0] = subKernelResult_${subKernel.name}`,\r\n );\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray2Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' data0[0] = kernelResult[0]',\r\n ' data0[1] = kernelResult[1]',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray2Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n const subKernel = this.subKernels[i];\r\n result.push(\r\n ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`,\r\n ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`,\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray3Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' data0[0] = kernelResult[0]',\r\n ' data0[1] = kernelResult[1]',\r\n ' data0[2] = kernelResult[2]',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray3Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n const subKernel = this.subKernels[i];\r\n result.push(\r\n ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`,\r\n ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`,\r\n ` data${i + 1}[2] = subKernelResult_${subKernel.name}[2]`,\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray4Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' data0 = kernelResult',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray4Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` data${i + 1} = subKernelResult_${this.subKernels[i].name}`,\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n destroyExtensions() {\r\n this.extensions.EXT_color_buffer_float = null;\r\n this.extensions.OES_texture_float_linear = null;\r\n }\r\n\r\n toJSON() {\r\n const json = super.toJSON();\r\n json.functionNodes = FunctionBuilder.fromKernel(this, WebGL2FunctionNode).toJSON();\r\n return json;\r\n }\r\n}\r\n","import { utils } from './utils';\r\n\r\n/**\r\n * Makes kernels easier for mortals (including me)\r\n * @param kernel\r\n * @returns {function()}\r\n */\r\nexport function kernelRunShortcut(kernel) {\r\n let run = function() {\r\n kernel.build.apply(kernel, arguments);\r\n if (kernel.renderKernels) {\r\n run = function() {\r\n kernel.run.apply(kernel, arguments);\r\n if (kernel.switchingKernels) {\r\n kernel.switchingKernels = false;\r\n return kernel.onRequestSwitchKernel(arguments, kernel);\r\n }\r\n return kernel.renderKernels();\r\n };\r\n } else if (kernel.renderOutput) {\r\n run = function() {\r\n kernel.run.apply(kernel, arguments);\r\n if (kernel.switchingKernels) {\r\n kernel.switchingKernels = false;\r\n return kernel.onRequestSwitchKernel(arguments, kernel);\r\n }\r\n return kernel.renderOutput();\r\n };\r\n } else {\r\n run = function() {\r\n return kernel.run.apply(kernel, arguments);\r\n };\r\n }\r\n return run.apply(kernel, arguments);\r\n };\r\n const shortcut = function() {\r\n return run.apply(kernel, arguments);\r\n };\r\n /**\r\n * Run kernel in async mode\r\n * @returns {Promise}\r\n */\r\n shortcut.exec = function() {\r\n return new Promise((accept, reject) => {\r\n try {\r\n accept(run.apply(this, arguments));\r\n } catch (e) {\r\n reject(e);\r\n }\r\n });\r\n };\r\n shortcut.replaceKernel = function(replacementKernel) {\r\n kernel = replacementKernel;\r\n bindKernelToShortcut(kernel, shortcut);\r\n shortcut.kernel = kernel;\r\n };\r\n\r\n bindKernelToShortcut(kernel, shortcut);\r\n shortcut.kernel = kernel;\r\n return shortcut;\r\n}\r\n\r\nfunction bindKernelToShortcut(kernel, shortcut) {\r\n const properties = utils.allPropertiesOf(kernel);\r\n for (let i = 0; i < properties.length; i++) {\r\n const property = properties[i];\r\n if (property[0] === '_' && property[1] === '_') continue;\r\n if (typeof kernel[property] === 'function') {\r\n if (property.substring(0, 3) === 'add' || property.substring(0, 3) === 'set') {\r\n shortcut[property] = function() {\r\n kernel[property].apply(kernel, arguments);\r\n return shortcut;\r\n };\r\n } else {\r\n if (property === 'toString') {\r\n shortcut.toString = function() {\r\n return kernel.toString.apply(kernel, arguments);\r\n };\r\n } else {\r\n shortcut[property] = kernel[property].bind(kernel);\r\n }\r\n }\r\n } else {\r\n shortcut.__defineGetter__(property, () => {\r\n return kernel[property];\r\n });\r\n shortcut.__defineSetter__(property, (value) => {\r\n kernel[property] = value;\r\n });\r\n }\r\n }\r\n}\r\n","import { gpuMock } from 'gpu-mock.js';\r\nimport { CPUKernel } from './backend/cpu/kernel';\r\nimport { WebGL2Kernel } from './backend/web-gl2/kernel';\r\nimport { WebGLKernel } from './backend/web-gl/kernel';\r\nimport { kernelRunShortcut } from './kernel-run-shortcut';\r\nimport {\r\n functionToIFunction,\r\n getFunctionNameFromString,\r\n isFunction,\r\n warnDeprecated\r\n} from './common';\r\nimport { getVariableType } from './utils';\r\n\r\n/**\r\n * @type {Kernel[]}\r\n */\r\nconst kernelOrder = [ WebGL2Kernel, WebGLKernel ];\r\n\r\n/**\r\n * @type {string[]}\r\n */\r\nconst kernelTypes = [ 'gpu', 'cpu' ];\r\n\r\nconst internalKernels = {\r\n 'webgl2': WebGL2Kernel,\r\n 'webgl': WebGLKernel,\r\n};\r\n\r\nlet validate = true;\r\n\r\n/**\r\n * The GPU.js library class which manages the GPU context for the creating kernels\r\n */\r\nexport class GPU {\r\n static disableValidation() {\r\n validate = false;\r\n }\r\n\r\n static enableValidation() {\r\n validate = true;\r\n }\r\n\r\n static get isGPUSupported() {\r\n return kernelOrder.some(Kernel => Kernel.isSupported);\r\n }\r\n\r\n /**\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isKernelMapSupported() {\r\n return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.kernelMap);\r\n }\r\n\r\n /**\r\n * @desc TRUE is platform supports OffscreenCanvas\r\n */\r\n static get isOffscreenCanvasSupported() {\r\n return (typeof Worker !== 'undefined' && typeof OffscreenCanvas !== 'undefined') || typeof importScripts !== 'undefined';\r\n }\r\n\r\n /**\r\n * @desc TRUE if platform supports WebGL\r\n */\r\n static get isWebGLSupported() {\r\n return WebGLKernel.isSupported;\r\n }\r\n\r\n /**\r\n * @desc TRUE if platform supports WebGL2\r\n */\r\n static get isWebGL2Supported() {\r\n return WebGL2Kernel.isSupported;\r\n }\r\n\r\n /**\r\n * @desc TRUE if platform supports HeadlessGL\r\n */\r\n static get isHeadlessGLSupported() {\r\n return false;\r\n }\r\n\r\n /**\r\n *\r\n * @desc TRUE if platform supports Canvas\r\n */\r\n static get isCanvasSupported() {\r\n return typeof HTMLCanvasElement !== 'undefined';\r\n }\r\n\r\n /**\r\n * @desc TRUE if platform supports HTMLImageArray}\r\n */\r\n static get isGPUHTMLImageArraySupported() {\r\n return WebGL2Kernel.isSupported;\r\n }\r\n\r\n /**\r\n * @desc TRUE if platform supports single precision}\r\n * @returns {boolean}\r\n */\r\n static get isSinglePrecisionSupported() {\r\n return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.isFloatRead && Kernel.features.isTextureFloat);\r\n }\r\n\r\n /**\r\n * Creates an instance of GPU.\r\n * @param {IGPUSettings} [settings] - Settings to set mode, and other properties\r\n */\r\n constructor(settings) {\r\n settings = settings || {};\r\n this.canvas = settings.canvas || null;\r\n this.context = settings.context || null;\r\n this.mode = settings.mode;\r\n this.Kernel = null;\r\n this.kernels = [];\r\n this.functions = [];\r\n this.nativeFunctions = [];\r\n this.injectedNative = null;\r\n if (this.mode === 'dev') return;\r\n this.chooseKernel();\r\n // add functions from settings\r\n if (settings.functions) {\r\n for (let i = 0; i < settings.functions.length; i++) {\r\n this.addFunction(settings.functions[i]);\r\n }\r\n }\r\n\r\n // add native functions from settings\r\n if (settings.nativeFunctions) {\r\n for (const p in settings.nativeFunctions) {\r\n this.addNativeFunction(p, settings.nativeFunctions[p]);\r\n }\r\n }\r\n }\r\n\r\n getValidate() {\r\n return validate;\r\n }\r\n\r\n /**\r\n * Choose kernel type and save on .Kernel property of GPU\r\n */\r\n chooseKernel() {\r\n if (this.Kernel) return;\r\n\r\n let Kernel = null;\r\n\r\n if (this.context) {\r\n for (let i = 0; i < kernelOrder.length; i++) {\r\n const ExternalKernel = kernelOrder[i];\r\n if (ExternalKernel.isContextMatch(this.context)) {\r\n if (!ExternalKernel.isSupported) {\r\n throw new Error(`Kernel type ${ExternalKernel.name} not supported`);\r\n }\r\n Kernel = ExternalKernel;\r\n break;\r\n }\r\n }\r\n if (Kernel === null) {\r\n throw new Error('unknown Context');\r\n }\r\n } else if (this.mode) {\r\n if (this.mode in internalKernels) {\r\n if (!validate || internalKernels[this.mode].isSupported) {\r\n Kernel = internalKernels[this.mode];\r\n }\r\n } else if (this.mode === 'gpu') {\r\n for (let i = 0; i < kernelOrder.length; i++) {\r\n if (kernelOrder[i].isSupported) {\r\n Kernel = kernelOrder[i];\r\n break;\r\n }\r\n }\r\n } else if (this.mode === 'cpu') {\r\n Kernel = CPUKernel;\r\n }\r\n if (!Kernel) {\r\n throw new Error(`A requested mode of \"${this.mode}\" and is not supported`);\r\n }\r\n } else {\r\n for (let i = 0; i < kernelOrder.length; i++) {\r\n if (kernelOrder[i].isSupported) {\r\n Kernel = kernelOrder[i];\r\n break;\r\n }\r\n }\r\n if (!Kernel) {\r\n Kernel = CPUKernel;\r\n }\r\n }\r\n\r\n if (!this.mode) {\r\n this.mode = Kernel.mode;\r\n }\r\n this.Kernel = Kernel;\r\n }\r\n\r\n /**\r\n * @desc This creates a callable function object to call the kernel function with the argument parameter set\r\n * @param {Function|String|object} source - The calling to perform the conversion\r\n * @param {Object} [settings] - The parameter configuration object\r\n * @return {Kernel} callable function to run\r\n */\r\n createKernel(source, settings) {\r\n if (typeof source === 'undefined') {\r\n throw new Error('Missing source parameter');\r\n }\r\n if (typeof source !== 'object' && !isFunction(source) && typeof source !== 'string') {\r\n throw new Error('source parameter not a function');\r\n }\r\n\r\n if (this.mode === 'dev') {\r\n const devKernel = gpuMock(source, upgradeDeprecatedCreateKernelSettings(settings));\r\n this.kernels.push(devKernel);\r\n return devKernel;\r\n }\r\n\r\n source = typeof source === 'function' ? source.toString() : source;\r\n const switchableKernels = {};\r\n const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings) || {};\r\n // handle conversion of argumentTypes\r\n if (settings && typeof settings.argumentTypes === 'object') {\r\n settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]);\r\n }\r\n\r\n function onRequestFallback(args) {\r\n const fallbackKernel = new CPUKernel(source, {\r\n argumentTypes: kernelRun.argumentTypes,\r\n constantTypes: kernelRun.constantTypes,\r\n graphical: kernelRun.graphical,\r\n loopMaxIterations: kernelRun.loopMaxIterations,\r\n constants: kernelRun.constants,\r\n dynamicOutput: kernelRun.dynamicOutput,\r\n dynamicArgument: kernelRun.dynamicArguments,\r\n output: kernelRun.output,\r\n precision: kernelRun.precision,\r\n pipeline: kernelRun.pipeline,\r\n immutable: kernelRun.immutable,\r\n optimizeFloatMemory: kernelRun.optimizeFloatMemory,\r\n fixIntegerDivisionAccuracy: kernelRun.fixIntegerDivisionAccuracy,\r\n functions: kernelRun.functions,\r\n nativeFunctions: kernelRun.nativeFunctions,\r\n injectedNative: kernelRun.injectedNative,\r\n subKernels: kernelRun.subKernels,\r\n strictIntegers: kernelRun.strictIntegers,\r\n debug: kernelRun.debug,\r\n warnVarUsage: kernelRun.warnVarUsage,\r\n });\r\n fallbackKernel.build.apply(fallbackKernel, args);\r\n const result = fallbackKernel.run.apply(fallbackKernel, args);\r\n kernelRun.replaceKernel(fallbackKernel);\r\n return result;\r\n }\r\n\r\n function onRequestSwitchKernel(args, kernel) {\r\n const argumentTypes = new Array(args.length);\r\n for (let i = 0; i < args.length; i++) {\r\n const arg = args[i];\r\n const type = kernel.argumentTypes[i];\r\n if (arg.type) {\r\n argumentTypes[i] = arg.type;\r\n } else {\r\n switch (type) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n case 'ArrayTexture(1)':\r\n argumentTypes[i] = getVariableType(arg);\r\n break;\r\n default:\r\n argumentTypes[i] = type;\r\n }\r\n }\r\n }\r\n const signature = argumentTypes.join(',');\r\n const existingKernel = switchableKernels[signature];\r\n if (existingKernel) {\r\n existingKernel.run.apply(existingKernel, args);\r\n if (existingKernel.renderKernels) {\r\n return existingKernel.renderKernels();\r\n } else {\r\n return existingKernel.renderOutput();\r\n }\r\n }\r\n\r\n const newKernel = switchableKernels[signature] = new kernel.constructor(source, {\r\n argumentTypes,\r\n constantTypes: kernel.constantTypes,\r\n graphical: kernel.graphical,\r\n loopMaxIterations: kernel.loopMaxIterations,\r\n constants: kernel.constants,\r\n dynamicOutput: kernel.dynamicOutput,\r\n dynamicArgument: kernel.dynamicArguments,\r\n context: kernel.context,\r\n canvas: kernel.canvas,\r\n output: kernel.output,\r\n precision: kernel.precision,\r\n pipeline: kernel.pipeline,\r\n immutable: kernel.immutable,\r\n optimizeFloatMemory: kernel.optimizeFloatMemory,\r\n fixIntegerDivisionAccuracy: kernel.fixIntegerDivisionAccuracy,\r\n functions: kernel.functions,\r\n nativeFunctions: kernel.nativeFunctions,\r\n injectedNative: kernel.injectedNative,\r\n subKernels: kernel.subKernels,\r\n strictIntegers: kernel.strictIntegers,\r\n debug: kernel.debug,\r\n gpu: kernel.gpu,\r\n validate,\r\n warnVarUsage: kernel.warnVarUsage,\r\n returnType: kernel.returnType,\r\n onRequestFallback,\r\n onRequestSwitchKernel,\r\n });\r\n newKernel.build.apply(newKernel, args);\r\n newKernel.run.apply(newKernel, args);\r\n kernelRun.replaceKernel(newKernel);\r\n if (newKernel.renderKernels) {\r\n return newKernel.renderKernels();\r\n } else {\r\n return newKernel.renderOutput();\r\n }\r\n }\r\n const mergedSettings = Object.assign({\r\n context: this.context,\r\n canvas: this.canvas,\r\n functions: this.functions,\r\n nativeFunctions: this.nativeFunctions,\r\n injectedNative: this.injectedNative,\r\n gpu: this,\r\n validate,\r\n onRequestFallback,\r\n onRequestSwitchKernel\r\n }, settingsCopy);\r\n\r\n const kernelRun = kernelRunShortcut(new this.Kernel(source, mergedSettings));\r\n\r\n //if canvas didn't come from this, propagate from kernel\r\n if (!this.canvas) {\r\n this.canvas = kernelRun.canvas;\r\n }\r\n\r\n //if context didn't come from this, propagate from kernel\r\n if (!this.context) {\r\n this.context = kernelRun.context;\r\n }\r\n\r\n this.kernels.push(kernelRun);\r\n\r\n return kernelRun;\r\n }\r\n\r\n /**\r\n *\r\n * Create a super kernel which executes sub kernels\r\n * and saves their output to be used with the next sub kernel.\r\n * This can be useful if we want to save the output on one kernel,\r\n * and then use it as an input to another kernel. *Machine Learning*\r\n *\r\n * @param {Object|Array} subKernels - Sub kernels for this kernel\r\n * @param {Function} rootKernel - Root kernel\r\n *\r\n * @returns {Function} callable kernel function\r\n *\r\n * @example\r\n * const megaKernel = gpu.createKernelMap({\r\n * addResult: function add(a, b) {\r\n * return a[this.thread.x] + b[this.thread.x];\r\n * },\r\n * multiplyResult: function multiply(a, b) {\r\n * return a[this.thread.x] * b[this.thread.x];\r\n * },\r\n * }, function(a, b, c) {\r\n * return multiply(add(a, b), c);\r\n * });\r\n *\r\n * megaKernel(a, b, c);\r\n *\r\n * Note: You can also define subKernels as an array of functions.\r\n * > [add, multiply]\r\n *\r\n */\r\n createKernelMap() {\r\n let fn;\r\n let settings;\r\n if (typeof arguments[arguments.length - 2] === 'function') {\r\n fn = arguments[arguments.length - 2];\r\n settings = arguments[arguments.length - 1];\r\n } else {\r\n fn = arguments[arguments.length - 1];\r\n }\r\n\r\n if (this.mode !== 'dev') {\r\n if (!this.Kernel.isSupported || !this.Kernel.features.kernelMap) {\r\n if (this.mode && kernelTypes.indexOf(this.mode) < 0) {\r\n throw new Error(`kernelMap not supported on ${this.Kernel.name}`);\r\n }\r\n }\r\n }\r\n\r\n const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings);\r\n // handle conversion of argumentTypes\r\n if (settings && typeof settings.argumentTypes === 'object') {\r\n settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]);\r\n }\r\n\r\n if (Array.isArray(arguments[0])) {\r\n settingsCopy.subKernels = [];\r\n const functions = arguments[0];\r\n for (let i = 0; i < functions.length; i++) {\r\n const source = functions[i].toString();\r\n const name = getFunctionNameFromString(source);\r\n settingsCopy.subKernels.push({\r\n name,\r\n source,\r\n property: i,\r\n });\r\n }\r\n } else {\r\n settingsCopy.subKernels = [];\r\n const functions = arguments[0];\r\n for (let p in functions) {\r\n if (!functions.hasOwnProperty(p)) continue;\r\n const source = functions[p].toString();\r\n const name = getFunctionNameFromString(source);\r\n settingsCopy.subKernels.push({\r\n name: name || p,\r\n source,\r\n property: p,\r\n });\r\n }\r\n }\r\n const kernel = this.createKernel(fn, settingsCopy);\r\n\r\n return kernel;\r\n }\r\n\r\n /**\r\n *\r\n * Combine different kernels into one super Kernel,\r\n * useful to perform multiple operations inside one\r\n * kernel without the penalty of data transfer between\r\n * cpu and gpu.\r\n *\r\n * The number of kernel functions sent to this method can be variable.\r\n * You can send in one, two, etc.\r\n *\r\n * @param {Function} subKernels - Kernel function(s) to combine.\r\n * @param {Function} rootKernel - Root kernel to combine kernels into\r\n *\r\n * @example\r\n * combineKernels(add, multiply, function(a,b,c){\r\n * return add(multiply(a,b), c)\r\n * })\r\n *\r\n * @returns {Function} Callable kernel function\r\n *\r\n */\r\n combineKernels() {\r\n const firstKernel = arguments[0];\r\n const combinedKernel = arguments[arguments.length - 1];\r\n if (firstKernel.kernel.constructor.mode === 'cpu') return combinedKernel;\r\n const canvas = arguments[0].canvas;\r\n const context = arguments[0].context;\r\n const max = arguments.length - 1;\r\n for (let i = 0; i < max; i++) {\r\n arguments[i]\r\n .setCanvas(canvas)\r\n .setContext(context)\r\n .setPipeline(true);\r\n }\r\n\r\n return function() {\r\n const texture = combinedKernel.apply(this, arguments);\r\n if (texture.toArray) {\r\n return texture.toArray();\r\n }\r\n return texture;\r\n };\r\n }\r\n\r\n /**\r\n * @desc Adds additional functions, that the kernel may call.\r\n * @param {Function|String} source - Javascript function to convert\r\n * @param {IFunctionSettings} [settings]\r\n * @returns {GPU} returns itself\r\n */\r\n addFunction(source, settings) {\r\n this.functions.push(functionToIFunction(source, settings));\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Adds additional native functions, that the kernel may call.\r\n * @param {String} name - native function name, used for reverse lookup\r\n * @param {String} source - the native function implementation, as it would be defined in it's entirety\r\n * @param {object} [settings]\r\n * @returns {GPU} returns itself\r\n */\r\n addNativeFunction(name, source, settings) {\r\n if (this.kernels.length > 0) {\r\n throw new Error('Cannot call \"addNativeFunction\" after \"createKernels\" has been called.');\r\n }\r\n settings = settings || {};\r\n const { argumentTypes, argumentNames } = this.Kernel.nativeFunctionArguments(source) || {};\r\n this.nativeFunctions.push({\r\n name,\r\n source,\r\n settings,\r\n argumentTypes,\r\n argumentNames,\r\n returnType: settings.returnType || this.Kernel.nativeFunctionReturnType(source),\r\n });\r\n return this;\r\n }\r\n\r\n /**\r\n * Inject a string just before translated kernel functions\r\n * @param {String} source\r\n * @return {GPU}\r\n */\r\n injectNative(source) {\r\n this.injectedNative = source;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Destroys all memory associated with gpu.js & the webGl if we created it\r\n */\r\n destroy() {\r\n if (!this.kernels) return;\r\n // perform on next run loop - for some reason we dont get lose context events\r\n // if webGl is created and destroyed in the same run loop.\r\n setTimeout(() => {\r\n for (let i = 0; i < this.kernels.length; i++) {\r\n this.kernels[i].destroy(true); // remove canvas if exists\r\n }\r\n // all kernels are associated with one context, go ahead and take care of it here\r\n let firstKernel = this.kernels[0];\r\n if (firstKernel) {\r\n // if it is shortcut\r\n if (firstKernel.kernel) {\r\n firstKernel = firstKernel.kernel;\r\n }\r\n if (firstKernel.constructor.destroyContext) {\r\n firstKernel.constructor.destroyContext(this.context);\r\n }\r\n }\r\n }, 0);\r\n }\r\n}\r\n\r\nfunction upgradeDeprecatedCreateKernelSettings(settings) {\r\n if (!settings) {\r\n return {};\r\n }\r\n const upgradedSettings = Object.assign({}, settings);\r\n\r\n if (settings.hasOwnProperty('floatOutput')) {\r\n warnDeprecated('setting', 'floatOutput', 'precision');\r\n upgradedSettings.precision = settings.floatOutput ? 'single' : 'unsigned';\r\n }\r\n if (settings.hasOwnProperty('outputToTexture')) {\r\n warnDeprecated('setting', 'outputToTexture', 'pipeline');\r\n upgradedSettings.pipeline = Boolean(settings.outputToTexture);\r\n }\r\n if (settings.hasOwnProperty('outputImmutable')) {\r\n warnDeprecated('setting', 'outputImmutable', 'immutable');\r\n upgradedSettings.immutable = Boolean(settings.outputImmutable);\r\n }\r\n if (settings.hasOwnProperty('floatTextures')) {\r\n warnDeprecated('setting', 'floatTextures', 'optimizeFloatMemory');\r\n upgradedSettings.optimizeFloatMemory = Boolean(settings.floatTextures);\r\n }\r\n return upgradedSettings;\r\n}\r\n","import { GPU } from './base-gpu';\r\nimport { alias } from './alias';\r\nimport { utils } from './utils';\r\nimport * as common from './common';\r\nimport { Input, input } from './input';\r\nimport { Texture } from './texture';\r\nimport { FunctionBuilder } from './backend/function-builder';\r\nimport { FunctionNode } from './backend/function-node';\r\nimport { CPUFunctionNode } from './backend/cpu/function-node';\r\nimport { CPUKernel } from './backend/cpu/kernel';\r\nimport { WebGLFunctionNode } from './backend/web-gl/function-node';\r\nimport { WebGLKernel } from './backend/web-gl/kernel';\r\nimport { WebGL2FunctionNode } from './backend/web-gl2/function-node';\r\nimport { WebGL2Kernel } from './backend/web-gl2/kernel';\r\nimport { GLKernel } from './backend/gl/kernel';\r\nimport { Kernel } from './backend/kernel';\r\n\r\n/**\r\n * Stub for HeadlessGL.\r\n */\r\nclass HeadlessGLKernel extends WebGLKernel {\r\n static get isSupported() { return false }\r\n static isContextMatch() { return false }\r\n static getIsTextureFloat() { return false }\r\n static getIsDrawBuffers() { return false }\r\n static getChannelCount() { return 1 }\r\n static get testCanvas() { return null }\r\n static get testContext() { return null }\r\n static get features() { return null }\r\n static setupFeatureChecks() {}\r\n static destroyContext() {}\r\n initCanvas() { return {} }\r\n initContext() { return null }\r\n toString() { return '' }\r\n initExtensions() {}\r\n build() {}\r\n destroyExtensions() {}\r\n setOutput() {}\r\n\r\n static getFeatures() {\r\n return Object.freeze({\r\n isFloatRead: false,\r\n isIntegerDivisionAccurate: false,\r\n isTextureFloat: false,\r\n isDrawBuffers: false,\r\n kernelMap: false,\r\n channelCount: 1,\r\n });\r\n }\r\n};\r\n\r\nconst lib = GPU;\r\nlib.alias = alias;\r\nlib.CPUFunctionNode = CPUFunctionNode;\r\nlib.CPUKernel = CPUKernel;\r\nlib.FunctionBuilder = FunctionBuilder;\r\nlib.FunctionNode = FunctionNode;\r\nlib.HeadlessGLKernel = HeadlessGLKernel;\r\nlib.Input = Input;\r\nlib.input = input;\r\nlib.Texture = Texture;\r\nlib.utils = { ...common, ...utils };\r\nlib.WebGL2FunctionNode = WebGL2FunctionNode;\r\nlib.WebGL2Kernel = WebGL2Kernel;\r\nlib.WebGLFunctionNode = WebGLFunctionNode;\r\nlib.WebGLKernel = WebGLKernel;\r\nlib.GLKernel = GLKernel;\r\nlib.Kernel = Kernel;\r\n\r\nexport default lib;\r\n","import { utils } from './utils';\r\n\r\n/**\r\n * @param name\r\n * @param source\r\n * @returns {Function}\r\n */\r\nexport function alias(name, source) {\r\n const fnString = source.toString();\r\n return new Function(`return function ${ name } (${ utils.getArgumentNamesFromString(fnString).join(', ') }) {\r\n ${ utils.getFunctionBodyFromString(fnString) }\r\n}`)();\r\n}\r\n"],"names":["setupArguments","args","newArguments","Array","length","i","arg","toArray","mock1D","arguments","row","Float32Array","this","output","x","thread","y","z","_fn","apply","mock2D","matrix","mock2DGraphical","mock3D","cube","apiDecorate","kernel","setOutput","setupOutput","graphical","setupGraphical","toJSON","Error","setConstants","flag","constants","setGraphical","setCanvas","canvas","setContext","context","exec","Promise","resolve","reject","e","getPixels","flip","pixels","width","height","halfHeight","bytesPerRow","temp","Uint8ClampedArray","result","slice","topOffset","bottomOffset","set","subarray","copyWithin","flipPixels","_imageData","data","color","r","g","b","a","Math","floor","index","_colorData","setWarnVarUsage","setOptimizeFloatMemory","setArgumentTypes","setDebug","setLoopMaxIterations","setPipeline","setPrecision","setImmutable","setFunctions","addSubKernel","destroy","validateSettings","createImageData","fn","settings","ARGUMENT_NAMES","FUNCTION_NAME","STRIP_COMMENTS","isFunction","funcObj","getFunctionNameFromString","funcStr","trim","functionToIFunction","source","sourceString","toString","argumentTypes","isArray","getArgumentNamesFromString","map","name","returnType","warnDeprecated","type","oldName","newName","msg","console","warn","isFunctionString","toLowerCase","fnStr","replace","indexOf","match","array","isNaN","erectMemoryOptimized2DFloat","yResults","offset","erectMemoryOptimized3DFloat","depth","zResults","getAstString","ast","lines","split","start","loc","end","line","push","substring","column","join","Input","[object Object]","value","size","Int32Array","w","h","d","Texture","texture","dimensions","constructor","deleteTexture","getSystemEndianness","ArrayBuffer","Uint32Array","c","Uint8Array","_systemEndianness","getVariableType","strictIntegers","nodeName","Boolean","Number","isInteger","hasOwnProperty","utils","systemEndianness","getFunctionBodyFromString","lastIndexOf","obj","key","Object","prototype","call","isActiveClone","clone","texelCount","optimizeFloatMemory","precision","ceil","closestSquareDimensions","sqrt","high","low","bitRatio","roundTo","n","pad","ret","dim","reverse","from","target","l","flatten4dArrayTo","flatten3dArrayTo","flatten2dArrayTo","part","buffer","byteOffset","props","getOwnPropertyNames","getPrototypeOf","linesToString","erectPackedFloat","erect2DPackedFloat","xStart","xEnd","erect3DPackedFloat","erectMemoryOptimizedFloat","erectFloat","xResults","erect2DFloat","erect3DFloat","erectArray2","xResultsMax","erect2DArray2","XResultsMax","erect3DArray2","erectArray3","erect2DArray3","erect3DArray3","erectArray4","erect2DArray4","erect3DArray4","flattenFunctionToString","findDependency","thisLookup","doNotDefine","flattened","parse","functionDependencies","flatten","results","body","id","params","declarations","init","properties","declaration","test","lookups","lookup","property","kind","callee","object","foundSource","argument","left","operator","right","prefix","expression","raw","computed","update","consequent","elements","alternate","flattenedFunctionDependencies","functionDependency","Kernel","isSupported","useLegacyEncoder","fallbackRequested","onRequestFallback","argumentNames","argumentSizes","argumentBitRatios","kernelArguments","kernelConstants","debug","loopMaxIterations","constantTypes","constantBitRatios","dynamicArguments","dynamicOutput","checkContext","gpu","functions","nativeFunctions","injectedNative","subKernels","validate","immutable","pipeline","tactic","plugins","leadingReturnStatement","followingReturnStatement","fixIntegerDivisionAccuracy","warnVarUsage","p","initCanvas","initContext","initPlugins","argType","getBitRatio","needsConstantTypes","max","setDynamicOutput","setDynamicArguments","argumentIndex","subKernel","removeCanvasReferences","Int8Array","Uint16Array","Int16Array","threadDim","argumentsTypes","pluginNames","plugin","FunctionBuilder","FunctionNode","extraNodeOptions","kernelConstant","needsArgumentType","functionName","functionBuilder","assignArgumentType","lookupReturnType","requestingNode","lookupFunctionArgumentTypes","lookupFunctionArgumentName","lookupFunctionArgumentBitRatio","argumentName","triggerImplyArgumentType","argumentType","triggerTrackArgumentSynonym","calleeFunctionName","trackArgumentSynonym","lookupArgumentSynonym","originFunctionName","onFunctionCall","trackFunctionCall","nodeOptions","assign","isRootKernel","onNestedFunction","nestedFunction","traceFunctionAST","addFunctionNode","rootNodeOptions","functionNodes","fromJSON","rootNode","subKernelNodes","isSubKernel","functionMap","nativeFunctionNames","lookupChain","argumentChain","functionNodeDependencies","functionCalls","nativeFunction","functionNode","retList","functionIndex","calledFunctions","traceFunctionCalls","dependantFunctionName","splice","getPrototypes","getPrototypesFromFunctionNames","keys","functionList","node","nativeIndex","jsonFunctionNodes","jsonFunctionNode","getStringFromFunctionNames","_isNativeFunction","_lookupNativeFunctionReturnType","_isFunction","_getFunction","j","getType","pop","getJsAST","_getNativeFunction","argumentSynonym","synonymIndex","fnNode","calleeArgumentName","synonymUseIndex","Set","add","subKernelNode","called","functionCallIndex","list","FunctionTracer","runningContexts","contexts","identifiers","returnStatements","inLoopInit","scan","currentContext","run","newContext","origin","forceInteger","assignable","discriminant","cases","states","triggerImplyArgumentBitRatio","strictTypingChecking","literalTypes","_string","_internalVariableNames","state","astMemberExpressionUnroll","firstExpression","expressions","astErrorOutput","inParser","parser","freeze","locations","functionAST","dependencies","getDependencies","valueType","realType","isSafe","isSafeDependencies","identifier","getDeclaration","typeLookupMap","constantName","astGeneric","literalKey","isAstMathFunction","inferArgumentTypesIfNeeded","isState","rightType","lastType","isAstVariable","getVariableSignature","findIdentifierOrigin","getLookupType","getConstantType","isAstMathVariable","lastReturn","findLastReturn","every","dependency","isNotSafe","Infinity","details","getMemberExpressionDetails","signature","xProperty","yProperty","zProperty","unshift","signatureString","retArr","astFunctionDeclaration","astFunctionExpression","astReturnStatement","astLiteral","astBinaryExpression","astIdentifierExpression","astAssignmentExpression","astExpressionStatement","astEmptyStatement","astBlockStatement","astIfStatement","astSwitchStatement","astBreakStatement","astContinueStatement","astForStatement","astWhileStatement","astDoWhileStatement","astVariableDeclaration","astVariableDeclarator","astThisExpression","astSequenceExpression","astUnaryExpression","astUpdateExpression","astLogicalExpression","astMemberExpression","astCallExpression","astArrayExpression","astDebuggerStatement","astConditionalExpression","error","debugString","splitLines","substr","lineBefore","arrNode","isChildFunction","astFunction","esNode","eNode","brNode","crNode","varDecNode","firstDeclaration","markupType","typeMap","iVarDecNode","sNode","uNode","checkAndUpconvertBitwiseUnary","logNode","variableSignature","astToFind","stack","atNode","shift","Float","Integer","Array(2)","Array(3)","Array(4)","Array2D","Array3D","HTMLImage","HTMLVideo","HTMLImageArray","NumberTexture","MemoryOptimizedNumberTexture","Array1D(2)","Array1D(3)","Array1D(4)","Array2D(2)","Array2D(3)","Array2D(4)","Array3D(2)","Array3D(3)","Array3D(4)","ArrayTexture(1)","ArrayTexture(2)","ArrayTexture(3)","ArrayTexture(4)","CPUFunctionNode","idtNode","forNode","initArr","testArr","updateArr","bodyArr","pushState","includes","popState","iVariableName","getInternalVariableName","whileNode","doWhileNode","assNode","bNode","varWarn","ifNode","tNode","mNode","markupName","isInput","constant","targetTypes","arrLen","subNode","cpuKernelString","cpuKernel","header","thisProperties","beforeReturn","useFunctionKeyword","JSON","stringify","types","constantsToString","colorFn","propertyName","getPixelsFn","constantKeys","flattenedImageTo3DArray","_imageTo3DArray","flattenedImageTo2DArray","_mediaTo2DArray","_kernelString","CPUKernel","features","kernelMap","isIntegerDivisionAccurate","mode","combinedKernel","super","mergeSettings","translatedSources","document","createElement","OffscreenCanvas","getContext","getDimensions","checkOutput","fromKernel","getKernelResultType","setupConstants","translateSource","kernelString","getKernelString","log","Function","bind","kernelThreadString","filter","_getLoopMaxString","_processConstants","_processArguments","_graphicalKernelBody","_resultKernelBody","parseInt","variableName","media","videoWidth","videoHeight","ctx","drawImage","pixelsData","getImageData","imageArray","pixel","images","imagesArray","_resultKernel1DLoop","_kernelOutput","_resultKernel2DLoop","_resultKernel3DLoop","_graphicalKernel2DLoop","_graphicalOutput","constructorString","_getKernelResultTypeConstructorString","_mapSubKernels","removeCanvasReference","json","GLTextureFloat","gl","framebuffer","createFramebuffer","bindFramebuffer","FRAMEBUFFER","framebufferTexture2D","COLOR_ATTACHMENT0","TEXTURE_2D","readPixels","RGBA","FLOAT","renderRawOutput","renderValues","GLTextureArray2Float","GLTextureArray2Float2D","GLTextureArray2Float3D","GLTextureArray3Float","GLTextureArray3Float2D","GLTextureArray3Float3D","GLTextureArray4Float","GLTextureArray4Float2D","GLTextureArray4Float3D","GLTextureFloat2D","GLTextureFloat3D","GLTextureMemoryOptimized","GLTextureMemoryOptimized2D","GLTextureMemoryOptimized3D","GLTextureUnsigned","UNSIGNED_BYTE","GLTextureUnsigned2D","GLTextureUnsigned3D","GLTextureGraphical","GLKernel","testContext","testCanvas","build","renderOutput","v1","v2","fix","floatTextures","isStartingVariableName","isVariableChar","char","nextChar","lastKernel","texSize","bytes","splitArray","transferValues","formatValues","TextureConstructor","translatedSource","renderStrategy","compiledFragmentShader","compiledVertexShader","maxTextureSize","readPackedPixelsToUint8Array","readPackedPixelsToFloat32Array","renderTexture","renderKernels","renderKernelsToTextures","PackedPixelTo3DFloat","PackedPixelTo2DFloat","PackedPixelToFloat","requestFallback","renderKernelsToArrays","readFloatPixelsToFloat32Array","FloatTexture","MemoryOptimizedFloatPixelToMemoryOptimized3DFloat","MemoryOptimizedFloatPixelToMemoryOptimized2DFloat","MemoryOptimizedFloatPixelToMemoryOptimizedFloat","FloatPixelTo3DArray2","FloatPixelTo2DArray2","FloatPixelToArray2","FloatPixelTo3DArray3","FloatPixelTo2DArray3","FloatPixelToArray3","FloatPixelTo3DArray4","FloatPixelTo2DArray4","FloatPixelToArray4","FloatPixelTo3DFloat","FloatPixelTo2DFloat","FloatPixelToFloat","getMainResultNumberTexture","getMainResultArray2Texture","getMainResultArray3Texture","getMainResultArray4Texture","getMainResultGraphical","getMainResultMemoryOptimizedFloats","getMainResultTexture","getMainResultPackedPixels","getMainResultKernelNumberTexture","getMainResultSubKernelNumberTexture","getMainResultKernelArray2Texture","getMainResultSubKernelArray2Texture","getMainResultKernelArray3Texture","getMainResultSubKernelArray3Texture","getMainResultKernelArray4Texture","getMainResultSubKernelArray4Texture","outputTexture","subKernelOutputTextures","program","getKernelTextureSize","updateMaxTexSize","viewport","maxTexSize","_setupOutputTexture","_setupSubOutputTextures","PackedPixelToUint8Array","Symbol","PackedTexture","FloatPixelToFloat32Array","int","float","vec2","vec3","vec4","WebGLFunctionNode","castLiteralToFloat","castValueToInteger","castLiteralToInteger","round","checkAndUpconvertOperator","castValueToFloat","leftType","operatorMap","literalResult","bitwiseResult","checkAndUpconvertBitwiseOperators","foundOperator","%","**","&","|","^","<<",">>",">>>","~","inForLoopInit","info","actualType","declarationResult","varName","fallingThrough","defaultResult","movingDefaultToEnd","pastFirstIf","memberExpressionPropertyMarkup","memberExpressionXYZ","isMathFunction","functionMatch","functionReplace","targetType","LiteralInteger","===","!==","onBeforeRun","setUniform1f","random","functionReturnType","fragmentShader","vertexShader","glWiretap","options","contextName","throwGetError","useTrackablePrimitives","readPixelsFile","recording","variables","onReadPixels","onUnrecognizedArgumentLookup","proxy","Proxy","get","addComment","checkThrowError","readPixelsVariableName","insertVariable","reset","setIndent","getContextVariableName","indent","getError","contextVariables","extension","getExtension","tappedExtension","glExtensionWiretap","getEntity","targetVariableName","getVariableName","argumentAsStrings","writePPM","argumentsToString","addVariable","drawBuffers","methodCallToString","trackablePrimitive","entityNames","imageCount","spaces","repeat","sourceVariable","imageVariable","method","getExtensionEntity","drawBuffersWEBGL","extensionEntityNames","hasLines","hasSingleQuotes","hasDoubleQuotes","instantiationString","argumentToString","module","window","toStringWithoutUtils","glKernelString","originKernel","setupContextString","destroyContextString","postResult","targetName","subKernelsResultVariableSetup","subKernelsResultIndex","getRenderString","findKernelValue","forEach","kernelArgument","uploadValue","imageIndex","flattenTo","getStringValueHandler","textureName","getToArrayString","subKernelResult","subKernelTextureName","getGetPixelsString","constantsUpload","readBackValue","kernelResult","kernelValues","values","uploadedValues","HTMLImageElement","kernelValue","variableIndex","variable","KernelValue","onRequestContextHandle","onUpdateValueMismatch","contextHandle","forceUploadEachRun","WebGLKernelValue","dimensionsId","sizeId","initialValueConstructor","onRequestTexture","onRequestIndex","textureSize","setupTexture","getTransferArrayType","Float64Array","Type","valuesFlat","WebGLKernelValueBoolean","setUniform1i","WebGLKernelValueFloat","WebGLKernelValueInteger","WebGLKernelValueHTMLImage","checkSize","requestTexture","inputImage","activeTexture","bindTexture","texParameteri","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","TEXTURE_MIN_FILTER","NEAREST","TEXTURE_MAG_FILTER","pixelStorei","UNPACK_FLIP_Y_WEBGL","texImage2D","WebGLKernelValueDynamicHTMLImage","setUniform3iv","setUniform2iv","updateValue","WebGLKernelValueHTMLVideo","WebGLKernelValueDynamicHTMLVideo","WebGLKernelValueSingleInput","getMemoryOptimizedFloatTextureSize","uploadArrayLength","input","WebGLKernelValueUnsignedInput","getMemoryOptimizedPackedTextureSize","TranserArrayType","preUploadValue","WebGLKernelValueDynamicUnsignedInput","WebGLKernelValueMemoryOptimizedNumberTexture","inputTexture","WebGLKernelValueDynamicMemoryOptimizedNumberTexture","WebGLKernelValueNumberTexture","WebGLKernelValueDynamicNumberTexture","WebGLKernelValueSingleArray","WebGLKernelValueSingleArray1DI","setShape","valueDimensions","WebGLKernelValueDynamicSingleArray1DI","WebGLKernelValueSingleArray2DI","WebGLKernelValueDynamicSingleArray2DI","WebGLKernelValueSingleArray3DI","WebGLKernelValueDynamicSingleArray3DI","WebGLKernelValueSingleArray2","setUniform2fv","WebGLKernelValueSingleArray3","setUniform3fv","WebGLKernelValueSingleArray4","setUniform4fv","WebGLKernelValueUnsignedArray","WebGLKernelValueDynamicUnsignedArray","kernelValueMaps","unsigned","dynamic","static","single","testExtensions","triangleNoise","canvases","maxTexSizes","WebGLKernel","setupFeatureChecks","isContextMatch","OES_texture_float","OES_texture_float_linear","OES_element_index_uint","WEBGL_draw_buffers","getFeatures","WebGLRenderingContext","isDrawBuffers","getIsDrawBuffers","isFloatRead","getIsFloatRead","getIsIntegerDivisionAccurate","isTextureFloat","getIsTextureFloat","channelCount","getChannelCount","getParameter","MAX_DRAW_BUFFERS_WEBGL","undefined","lookupKernelValueType","endianness","extensions","argumentTextureCount","constantTextureCount","fragShader","vertShader","drawBuffersMap","switchingKernels","onRequestSwitchKernel","textureCache","programUniformLocationCache","uniform1fCache","uniform1iCache","uniform2fCache","uniform2fvCache","uniform2ivCache","uniform3fvCache","uniform3ivCache","uniform4fvCache","uniform4ivCache","alpha","antialias","pluginsToUse","some","pluginName","WEBGL_color_buffer_float","checkTextureSize","canvasIndex","getPrototypeString","requiredChannels","returnTypes","getReturnTypes","needsArgumentTypes","textureIndexes","createTexture","TEXTURE0","forceUploadKernelConstants","initExtensions","failureResult","pickRenderStrategy","enable","SCISSOR_TEST","getVertexShader","createShader","VERTEX_SHADER","shaderSource","compileShader","getFragmentShader","FRAGMENT_SHADER","getShaderParameter","COMPILE_STATUS","getShaderInfoLog","createProgram","attachShader","linkProgram","vertices","texCoords","texCoordOffset","byteLength","bindBuffer","ARRAY_BUFFER","createBuffer","bufferData","STATIC_DRAW","bufferSubData","aPosLoc","getAttribLocation","enableVertexAttribArray","vertexAttribPointer","aTexCoordLoc","useProgram","getSubKernelResultType","scissor","setUniform2f","bindRenderbuffer","RENDERBUFFER","drawArrays","TRIANGLE_STRIP","getUniformLocation","uniform1f","uniform1i","value1","value2","cache","uniform2f","uniform2fv","uniform2iv","uniform3fv","uniform3iv","uniform4iv","uniform4fv","HEADER","_getHeaderString","LOOP_MAX","PLUGINS","_getPluginsString","CONSTANTS","_getConstantsString","DECODE32_ENDIANNESS","_getDecode32EndiannessString","ENCODE32_ENDIANNESS","_getEncode32EndiannessString","DIVIDE_WITH_INTEGER_CHECK","_getDivideWithIntegerCheckString","INJECTED_NATIVE","_getInjectedNative","MAIN_CONSTANTS","_getMainConstantsString","MAIN_ARGUMENTS","_getMainArgumentsString","KERNEL","MAIN_RESULT","getMainResultString","FLOAT_TACTIC_DECLARATION","getFloatTacticDeclaration","INT_TACTIC_DECLARATION","getIntTacticDeclaration","SAMPLER_2D_TACTIC_DECLARATION","getSampler2DTacticDeclaration","SAMPLER_2D_ARRAY_TACTIC_DECLARATION","getSampler2DArrayTacticDeclaration","getSource","kernelResultDeclaration","getMainResultKernelPackedPixels","getMainResultSubKernelPackedPixels","channels","channel","getMainResultKernelMemoryOptimizedFloats","getMainResultSubKernelMemoryOptimizedFloats","src","artifact","replaceArtifacts","_getFragShaderArtifactMap","_getVertShaderArtifactMap","deleteBuffer","deleteFramebuffer","deleteShader","deleteProgram","idx","destroyExtensions","loseContext","WebGL2FunctionNode","WebGL2KernelValueBoolean","WebGL2KernelValueFloat","WebGL2KernelValueInteger","variablePrecision","getVariablePrecisionString","WebGL2KernelValueHTMLImage","WebGL2KernelValueDynamicHTMLImage","WebGL2KernelValueHTMLImageArray","TEXTURE_2D_ARRAY","texImage3D","xOffset","yOffset","imageDepth","texSubImage3D","WebGL2KernelValueDynamicHTMLImageArray","WebGL2KernelValueHTMLVideo","WebGL2KernelValueDynamicHTMLVideo","WebGL2KernelValueSingleInput","RGBA32F","WebGL2KernelValueDynamicMemoryOptimizedNumberTexture","WebGL2KernelValueNumberTexture","WebGL2KernelValueDynamicNumberTexture","WebGL2KernelValueSingleArray","WebGL2KernelValueSingleArray1DI","WebGL2KernelValueDynamicSingleArray1DI","WebGL2KernelValueSingleArray2DI","WebGL2KernelValueDynamicSingleArray2DI","WebGL2KernelValueSingleArray3DI","WebGL2KernelValueDynamicSingleArray3DI","WebGL2KernelValueSingleArray2","WebGL2KernelValueSingleArray3","WebGL2KernelValueSingleArray4","WebGL2Kernel","EXT_color_buffer_float","WebGL2RenderingContext","getMaxTextureSize","MAX_DRAW_BUFFERS","MAX_TEXTURE_SIZE","texStorage2D","R32F","RG32F","bindKernelToShortcut","shortcut","allPropertiesOf","__defineGetter__","__defineSetter__","kernelOrder","kernelTypes","internalKernels","webgl2","webgl","upgradeDeprecatedCreateKernelSettings","upgradedSettings","floatOutput","outputToTexture","outputImmutable","lib","isGPUSupported","isKernelMapSupported","isOffscreenCanvasSupported","Worker","importScripts","isWebGLSupported","isWebGL2Supported","isHeadlessGLSupported","isCanvasSupported","HTMLCanvasElement","isGPUHTMLImageArraySupported","isSinglePrecisionSupported","kernels","chooseKernel","addFunction","addNativeFunction","ExternalKernel","devKernel","gpuMock","switchableKernels","settingsCopy","fallbackKernel","kernelRun","dynamicArgument","replaceKernel","mergedSettings","existingKernel","newKernel","accept","replacementKernel","kernelRunShortcut","createKernel","firstKernel","nativeFunctionArguments","nativeFunctionReturnType","setTimeout","destroyContext","alias","fnString","HeadlessGLKernel","common"],"mappings":"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"} \ No newline at end of file diff --git a/dist/gpu-browser.js b/dist/gpu-browser.js index a02e3462..cfd9dae4 100644 --- a/dist/gpu-browser.js +++ b/dist/gpu-browser.js @@ -1,18882 +1,16271 @@ /** * gpu.js - * http://gpu.rocks/ + * https://gpu.rocks/ * * GPU Accelerated JavaScript * * @version 2.0.5 - * @date Fri Oct 11 2019 07:23:33 GMT-0400 (Eastern Daylight Time) + * @date Tue Oct 29 2019 10:46:59 GMT-0400 (Eastern Daylight Time) * * @license MIT * The MIT License * * Copyright (c) 2019 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 } - } -} - - -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("!/~", {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, ecma2019String) { - return code === 10 || code === 13 || (!ecma2019String && (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) + 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; } -} - - -var defaultOptions = { - ecmaVersion: 7, - sourceType: "script", - onInsertedSemicolon: null, - onTrailingComma: null, - allowReserved: null, - allowReturnOutsideFunction: false, - allowImportExportEverywhere: false, - allowAwaitOutsideFunction: 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(); - - this.regexpState = null; -}; - -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 && !this.containsEsc -}; - - -pp.eatContextual = function(name) { - if (!this.isContextual(name)) { return false } - this.next(); - return true -}; - - -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 = - this.doubleProto = - -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) { - 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.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.adaptDirectivePrologue(node.body); - 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.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 === 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 (!keywordRelationalOperator.test(ident)) { return true } - } - return false -}; - -pp$1.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; - 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()) { - if (!declaration) { this.unexpected(); } - this.next(); - return this.parseFunctionStatement(node, true) + 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); } - - 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(); + return row; } - - 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 } + 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; } - 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(); - var awaitAt = (this.options.ecmaVersion >= 9 && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction)) && this.eatContextual("await")) ? this.lastTokStart : -1; - this.labels.push(loopLabel); - this.enterLexicalScope(); - this.expect(types.parenL); - if (this.type === types.semi) { - if (awaitAt > -1) { this.unexpected(awaitAt); } - return this.parseFor(node, null) + 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); + } + } } - 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)) { - if (this.options.ecmaVersion >= 9) { - if (this.type === types._in) { - if (awaitAt > -1) { this.unexpected(awaitAt); } - } else { node.await = awaitAt > -1; } + 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; } - return this.parseForIn(node, init$1) + cube[z] = matrix; } - if (awaitAt > -1) { this.unexpected(awaitAt); } - return this.parseFor(node, init$1) + return cube; } - var refDestructuringErrors = new DestructuringErrors; - var init = this.parseExpression(true, refDestructuringErrors); - if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) { - if (this.options.ecmaVersion >= 9) { - if (this.type === types._in) { - if (awaitAt > -1) { this.unexpected(awaitAt); } - } else { node.await = awaitAt > -1; } - } - this.toAssignable(init, false, refDestructuringErrors); - this.checkLVal(init); - return this.parseForIn(node, init) - } else { - this.checkExpressionErrors(refDestructuringErrors, true); + 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.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; + }; + kernel.setWarnVarUsage = () => { + return kernel; + }; + kernel.setOptimizeFloatMemory = () => { + return kernel; + }; + kernel.setArgumentTypes = () => { + return kernel; + }; + kernel.setDebug = () => { + return kernel; + }; + kernel.setLoopMaxIterations = () => { + return kernel; + }; + kernel.setPipeline = () => { + return kernel; + }; + kernel.setPrecision = () => { + return kernel; + }; + kernel.setImmutable = () => { + return kernel; + }; + kernel.setFunctions = () => { + return kernel; + }; + kernel.addSubKernel = () => { + return kernel; + }; + kernel.destroy = () => {}; + kernel.validateSettings = () => {}; + if (kernel.graphical && kernel.output) { + setupGraphical(kernel); + } + return kernel; } - if (awaitAt > -1) { this.unexpected(awaitAt); } - return this.parseFor(node, init) -}; - -pp$1.parseFunctionStatement = function(node, isAsync) { - this.next(); - return this.parseFunction(node, true, false, isAsync) -}; - -pp$1.parseIfStatement = function(node) { - this.next(); - node.test = this.parseParenExpression(); - node.consequent = this.parseStatement(!this.strict && this.type === types._function); - node.alternate = this.eat(types._else) ? this.parseStatement(!this.strict && this.type === types._function) : 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(); + 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 { - if (sawDefault) { this$1.raiseRecoverable(this$1.lastTokStart, "Multiple default clauses"); } - sawDefault = true; - cur.test = null; + const [x] = output; + result = { x }; } - this$1.expect(types.colon); } else { - if (!cur) { this$1.unexpected(); } - cur.consequent.push(this$1.parseStatement(true)); + result = output; } + return result; } - 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(); - if (this.eat(types.parenL)) { - clause.param = this.parseBindingAtom(); - this.enterLexicalScope(); - this.checkLVal(clause.param, "let"); - this.expect(types.parenR); - } else { - if (this.options.ecmaVersion < 10) { this.unexpected(); } - clause.param = null; - this.enterLexicalScope(); + 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); } - clause.body = this.parseBlock(false); - this.exitLexicalScope(); - node.handler = this.finishNode(clause, "CatchClause"); + return result; } - 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") -}; + var gpuMock_js = { + gpuMock + }; + var gpuMock_js_1 = gpuMock_js.gpuMock; -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 || node.body.async)) - { 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(); - if (type === "ForInStatement") { - if (init.type === "AssignmentPattern" || - (init.type === "VariableDeclaration" && init.declarations[0].init != null && - (this.strict || init.declarations[0].id.type !== "Identifier"))) - { this.raise(init.start, "Invalid assignment in for-in loop head"); } - } - node.left = init; - node.right = type === "ForInStatement" ? this.parseExpression() : this.parseMaybeAssign(); - 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"); + const ARGUMENT_NAMES = /([^\s,]+)/g; + const FUNCTION_NAME = /function ([^(]*)/; + const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; + function isFunction(funcObj) { + return typeof(funcObj) === 'function'; + }function getFunctionNameFromString(funcStr) { + return FUNCTION_NAME.exec(funcStr)[1].trim(); + }function functionToIFunction(source, settings) { + settings = 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 = getArgumentNamesFromString(sourceString) + .map(name => settings.argumentTypes[name]) || []; } else { - decl.init = null; + argumentTypes = settings.argumentTypes || []; } - 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 >= 9 || 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, this.inModule && !this.inFunction ? "let" : "var"); + return { + source: sourceString, + argumentTypes, + returnType: settings.returnType || null, + }; + }function warnDeprecated(type, oldName, newName) { + const msg = newName + ? `It has been replaced with "${ newName }"` + : 'It has been removed'; + console.warn(`You are using a deprecated ${ type } "${ oldName }". ${msg}. Fixing, but please upgrade as it will soon be removed.`); + }function isFunctionString(fn) { + if (typeof fn === 'string') { + return (fn + .slice(0, 'function'.length) + .toLowerCase() === 'function'); + } + return false; + }function 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; + }function isArray(array) { + return !isNaN(array.length); + }function 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; + }function 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; + }function 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'); } - 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(); + var common = /*#__PURE__*/Object.freeze({ + isFunction: isFunction, + getFunctionNameFromString: getFunctionNameFromString, + functionToIFunction: functionToIFunction, + warnDeprecated: warnDeprecated, + isFunctionString: isFunctionString, + getArgumentNamesFromString: getArgumentNamesFromString, + isArray: isArray, + erectMemoryOptimized2DFloat: erectMemoryOptimized2DFloat, + erectMemoryOptimized3DFloat: erectMemoryOptimized3DFloat, + getAstString: getAstString + }); - 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)) { - var member = this$1.parseClassMember(classBody); - if (member && member.type === "MethodDefinition" && member.kind === "constructor") { - if (hadConstructor) { this$1.raise(member.start, "Duplicate constructor in the same class"); } - hadConstructor = true; + 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 [ w, h, d ] = this.size; + if (d) { + return erectMemoryOptimized3DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h, d); + } else if (h) { + return 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); } - node.body = this.finishNode(classBody, "ClassBody"); - return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") -}; - -pp$1.parseClassMember = function(classBody) { - var this$1 = this; - if (this.eat(types.semi)) { return null } - - var method = this.startNode(); - var tryContextual = function (k, noLineBreak) { - if ( noLineBreak === void 0 ) noLineBreak = false; - - var start = this$1.start, startLoc = this$1.startLoc; - if (!this$1.eatContextual(k)) { return false } - if (this$1.type !== types.parenL && (!noLineBreak || !this$1.canInsertSemicolon())) { return true } - if (method.key) { this$1.unexpected(); } - method.computed = false; - method.key = this$1.startNodeAt(start, startLoc); - method.key.name = k; - this$1.finishNode(method.key, "Identifier"); - return false + 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" }; - - method.kind = "method"; - method.static = tryContextual("static"); - var isGenerator = this.eat(types.star); - var isAsync = false; - if (!isGenerator) { - if (this.options.ecmaVersion >= 8 && tryContextual("async", true)) { - isAsync = true; - isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star); - } else if (tryContextual("get")) { - method.kind = "get"; - } else if (tryContextual("set")) { - method.kind = "set"; + 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 keywordRelationalOperator = /^in(stanceof)?$/; + 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\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\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\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\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-\u1878\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\u1c90-\u1cba\u1cbd-\u1cbf\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-\u312f\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fef\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7b9\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\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\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\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\u0d00-\u0d03\u0d3b\u0d3c\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\u1cf7-\u1cf9\u1dc0-\u1df9\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\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; + 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,14,29,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,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,14,35,477,28,11,0,9,21,190,52,76,44,33,24,27,35,30,0,12,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,26,230,43,117,63,32,0,257,0,11,39,8,0,22,0,12,39,3,3,20,0,35,56,264,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,26,5,2,1,2,31,15,0,328,18,270,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,689,63,129,68,12,0,67,12,65,1,31,6129,15,754,9486,286,82,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,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,15,7472,3104,541]; + var astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,525,10,176,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,4,9,83,11,7,0,161,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,243,14,166,9,280,9,41,6,2,3,9,0,10,10,47,15,406,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,49,4,2,1,2,4,9,9,330,3,19306,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("!/~", {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, ecma2019String) { + return code === 10 || code === 13 || (!ecma2019String && (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$1 = 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, + allowAwaitOutsideFunction: 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$1(options.onToken)) { + var tokens = options.onToken; + options.onToken = function (token) { return tokens.push(token); }; + } + if (isArray$1(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(); + this.regexpState = null; + }; + 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]); } - } - if (!method.key) { this.parsePropertyName(method); } - var key = method.key; - if (!method.computed && !method.static && (key.type === "Identifier" && key.name === "constructor" || - key.type === "Literal" && key.value === "constructor")) { - if (method.kind !== "method") { this.raise(key.start, "Constructor can't have get/set modifier"); } - 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"); } - method.kind = "constructor"; - } else if (method.static && key.type === "Identifier" && key.name === "prototype") { - this.raise(key.start, "Classes may not have a static property named prototype"); - } - this.parseClassMethod(classBody, method, isGenerator, isAsync); - if (method.kind === "get" && method.value.params.length !== 0) - { this.raiseRecoverable(method.value.start, "getter should have no params"); } - if (method.kind === "set" && method.value.params.length !== 1) - { this.raiseRecoverable(method.value.start, "setter should have exactly one param"); } - if (method.kind === "set" && method.value.params[0].type === "RestElement") - { this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); } - return method -}; - -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"); - if (this.type !== types.string) { this.unexpected(); } - node.source = this.parseExprAtom(); - 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(); + }; + 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(); - 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"); + return true } else { - node.declaration = this.parseMaybeAssign(); + return false + } + }; + pp.isContextual = function(name) { + return this.type === types.name && this.value === name && !this.containsEsc + }; + pp.eatContextual = function(name) { + if (!this.isContextual(name)) { return false } + this.next(); + return true + }; + 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 = + this.doubleProto = + -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) { + 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.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.adaptDirectivePrologue(node.body); + 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.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 === 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 (!keywordRelationalOperator.test(ident)) { return true } + } + return false + }; + pp$1.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; + 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()) { + if (!declaration) { this.unexpected(); } + 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(); } - return this.finishNode(node, "ExportDefaultDeclaration") - } - if (this.shouldParseExportStatement()) { - node.declaration = this.parseStatement(true); - if (node.declaration.type === "VariableDeclaration") - { this.checkVariableExport(exports, node.declaration.declarations); } + 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.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")) { - if (this.type !== types.string) { this.unexpected(); } - node.source = this.parseExprAtom(); + { this.semicolon(); } + return this.finishNode(node, "DoWhileStatement") + }; + pp$1.parseForStatement = function(node) { + this.next(); + var awaitAt = (this.options.ecmaVersion >= 9 && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction)) && this.eatContextual("await")) ? this.lastTokStart : -1; + this.labels.push(loopLabel); + this.enterLexicalScope(); + this.expect(types.parenL); + if (this.type === types.semi) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + 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)) { + if (this.options.ecmaVersion >= 9) { + if (this.type === types._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 refDestructuringErrors = new DestructuringErrors; + var init = this.parseExpression(true, refDestructuringErrors); + if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) { + if (this.options.ecmaVersion >= 9) { + if (this.type === types._in) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + } else { node.await = awaitAt > -1; } + } + this.toAssignable(init, false, refDestructuringErrors); + this.checkLVal(init); + return this.parseForIn(node, init) } else { - for (var i = 0, list = node.specifiers; i < list.length; i += 1) { - var spec = list[i]; - - this$1.checkUnreserved(spec.local); + this.checkExpressionErrors(refDestructuringErrors, true); + } + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, init) + }; + pp$1.parseFunctionStatement = function(node, isAsync) { + this.next(); + return this.parseFunction(node, true, false, isAsync) + }; + pp$1.parseIfStatement = function(node) { + this.next(); + node.test = this.parseParenExpression(); + node.consequent = this.parseStatement(!this.strict && this.type === types._function); + node.alternate = this.eat(types._else) ? this.parseStatement(!this.strict && this.type === types._function) : 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)); } - - node.source = null; } + 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, "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) + 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(); + if (this.eat(types.parenL)) { + clause.param = this.parseBindingAtom(); + this.enterLexicalScope(); + this.checkLVal(clause.param, "let"); + this.expect(types.parenR); + } else { + if (this.options.ecmaVersion < 10) { this.unexpected(); } + clause.param = null; + this.enterLexicalScope(); + } + 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 prop = list[i]; - - this$1.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$1.checkPatternExport(exports, elt); } + var label = list[i$1]; + if (label.name === maybeName) + { this$1.raise(expr.start, "Label '" + maybeName + "' is already declared"); } } - 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); } - 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 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 || node.body.async)) + { 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.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(); + 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(); + if (type === "ForInStatement") { + if (init.type === "AssignmentPattern" || + (init.type === "VariableDeclaration" && init.declarations[0].init != null && + (this.strict || init.declarations[0].id.type !== "Identifier"))) + { this.raise(init.start, "Invalid assignment in for-in loop head"); } + } + node.left = init; + node.right = type === "ForInStatement" ? this.parseExpression() : this.parseMaybeAssign(); + 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 >= 9 || 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, this.inModule && !this.inFunction ? "let" : "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)) { + var member = this$1.parseClassMember(classBody); + if (member && member.type === "MethodDefinition" && member.kind === "constructor") { + if (hadConstructor) { this$1.raise(member.start, "Duplicate constructor in the same class"); } + hadConstructor = true; + } + } + node.body = this.finishNode(classBody, "ClassBody"); + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") + }; + pp$1.parseClassMember = function(classBody) { + var this$1 = this; + if (this.eat(types.semi)) { return null } + var method = this.startNode(); + var tryContextual = function (k, noLineBreak) { + if ( noLineBreak === void 0 ) noLineBreak = false; + var start = this$1.start, startLoc = this$1.startLoc; + if (!this$1.eatContextual(k)) { return false } + if (this$1.type !== types.parenL && (!noLineBreak || !this$1.canInsertSemicolon())) { return true } + if (method.key) { this$1.unexpected(); } + method.computed = false; + method.key = this$1.startNodeAt(start, startLoc); + method.key.name = k; + this$1.finishNode(method.key, "Identifier"); + return false + }; + method.kind = "method"; + method.static = tryContextual("static"); + var isGenerator = this.eat(types.star); + var isAsync = false; + if (!isGenerator) { + if (this.options.ecmaVersion >= 8 && tryContextual("async", true)) { + isAsync = true; + isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star); + } else if (tryContextual("get")) { + method.kind = "get"; + } else if (tryContextual("set")) { + method.kind = "set"; + } + } + if (!method.key) { this.parsePropertyName(method); } + var key = method.key; + if (!method.computed && !method.static && (key.type === "Identifier" && key.name === "constructor" || + key.type === "Literal" && key.value === "constructor")) { + if (method.kind !== "method") { this.raise(key.start, "Constructor can't have get/set modifier"); } + 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"); } + method.kind = "constructor"; + } else if (method.static && key.type === "Identifier" && key.name === "prototype") { + this.raise(key.start, "Classes may not have a static property named prototype"); + } + this.parseClassMethod(classBody, method, isGenerator, isAsync); + if (method.kind === "get" && method.value.params.length !== 0) + { this.raiseRecoverable(method.value.start, "getter should have no params"); } + if (method.kind === "set" && method.value.params.length !== 1) + { this.raiseRecoverable(method.value.start, "setter should have exactly one param"); } + if (method.kind === "set" && method.value.params[0].type === "RestElement") + { this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); } + return method + }; + 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(); - this.expectContextual("as"); - node$1.local = this.parseIdent(); - this.checkLVal(node$1.local, "let"); - nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier")); + if (this.eat(types.star)) { + this.expectContextual("from"); + if (this.type !== types.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + 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")) { + if (this.type !== types.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + } 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); + } } + 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 === "Property") + { this.checkPatternExport(exports, pat.value); } + else if (type === "AssignmentPattern") + { this.checkPatternExport(exports, pat.left); } + else if (type === "RestElement") + { this.checkPatternExport(exports, pat.argument); } + 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 - } - 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(); + }; + pp$1.parseImport = function(node) { + this.next(); + if (this.type === types.string) { + node.specifiers = empty; + node.source = this.parseExprAtom(); } else { - this$1.checkUnreserved(node$2.imported); - node$2.local = node$2.imported; + node.specifiers = this.parseImportSpecifiers(); + this.expectContextual("from"); + node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected(); } - this$1.checkLVal(node$2.local, "let"); - nodes.push(this$1.finishNode(node$2, "ImportSpecifier")); - } - return nodes -}; - -pp$1.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$1.isDirectiveCandidate = function(statement) { - return ( - statement.type === "ExpressionStatement" && - statement.expression.type === "Literal" && - typeof statement.expression.value === "string" && - (this.input[statement.start] === "\"" || this.input[statement.start] === "'") - ) -}; - -var pp$2 = Parser.prototype; - - -pp$2.toAssignable = function(node, isBinding, refDestructuringErrors) { - var this$1 = this; - - if (this.options.ecmaVersion >= 6 && node) { - switch (node.type) { + 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 + }; + pp$1.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$1.isDirectiveCandidate = function(statement) { + return ( + statement.type === "ExpressionStatement" && + statement.expression.type === "Literal" && + typeof statement.expression.value === "string" && + (this.input[statement.start] === "\"" || this.input[statement.start] === "'") + ) + }; + var pp$2 = Parser.prototype; + pp$2.toAssignable = function(node, isBinding, refDestructuringErrors) { + 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": + 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$1.toAssignable(prop, isBinding); + if ( + prop.type === "RestElement" && + (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern") + ) { + this$1.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); + case "AssignmentPattern": + break + case "ParenthesizedExpression": + this.toAssignable(node.expression, isBinding); + break + case "MemberExpression": + if (!isBinding) { break } + default: + this.raise(node.start, "Assigning to rvalue"); + } + } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + return node + }; + pp$2.toAssignableList = function(exprList, isBinding) { + var this$1 = this; + var end = exprList.length; + for (var i = 0; i < end; i++) { + var elt = exprList[i]; + if (elt) { this$1.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$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) { + switch (this.type) { + 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) + } + } + return this.parseIdent() + }; + 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.inAsync && node.name === "await") - { this.raise(node.start, "Can not use 'await' as identifier inside an async function"); } - break - - case "ObjectPattern": - case "ArrayPattern": - 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$1.toAssignable(prop, isBinding); + 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 ( - prop.type === "RestElement" && - (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern") + bindingType === "var" && !this.canDeclareVarName(expr.name) || + bindingType !== "var" && !this.canDeclareLexicalName(expr.name) ) { - this$1.raise(prop.argument.start, "Unexpected token"); + 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 "Property": - if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); } - this.toAssignable(node.value, isBinding); + case "MemberExpression": + if (bindingType) { this.raiseRecoverable(expr.start, "Binding member expression"); } break - - case "ArrayExpression": - node.type = "ArrayPattern"; - if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } - this.toAssignableList(node.elements, isBinding); + case "ObjectPattern": + for (var i = 0, list = expr.properties; i < list.length; i += 1) + { + var prop = list[i]; + this$1.checkLVal(prop, bindingType, checkClashes); + } 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"); } + case "Property": + this.checkLVal(expr.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 "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); - case "AssignmentPattern": + this.checkLVal(expr.left, bindingType, checkClashes); + break + case "RestElement": + this.checkLVal(expr.argument, bindingType, checkClashes); break - case "ParenthesizedExpression": - this.toAssignable(node.expression, isBinding); + this.checkLVal(expr.expression, bindingType, checkClashes); break - - case "MemberExpression": - if (!isBinding) { break } - default: - this.raise(node.start, "Assigning to rvalue"); - } - } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } - return node -}; - - -pp$2.toAssignableList = function(exprList, isBinding) { - var this$1 = this; - - var end = exprList.length; - for (var i = 0; i < end; i++) { - var elt = exprList[i]; - if (elt) { this$1.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$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) { - switch (this.type) { - 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) - } - } - return this.parseIdent() -}; - -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); + this.raise(expr.start, (bindingType ? "Binding" : "Assigning to") + " rvalue"); } - } - 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")); + }; + var pp$3 = Parser.prototype; + pp$3.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 && refDestructuringErrors.doubleProto < 0) { refDestructuringErrors.doubleProto = key.start; } + else { this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); } + } + propHash.proto = true; } - if (bindingType === "var") { - this.declareVarName(expr.name); + return + } + name = "$" + name; + var other = propHash[name]; + if (other) { + var redefinition; + if (kind === "init") { + redefinition = this.strict && other.init || other.get || other.set; } else { - this.declareLexicalName(expr.name); + redefinition = other.init || other[kind]; } + if (redefinition) + { this.raiseRecoverable(key.start, "Redefinition of property"); } + } else { + other = propHash[name] = { + init: false, + get: false, + set: false + }; } - break - - case "MemberExpression": - if (bindingType) { this.raiseRecoverable(expr.start, "Binding 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, bindingType, checkClashes); - } - break - - case "Property": - this.checkLVal(expr.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); } + 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") } - 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, 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 && refDestructuringErrors.doubleProto < 0) { refDestructuringErrors.doubleProto = key.start; } - else { this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); } - } - propHash.proto = true; + 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) { + var node = this.startNodeAt(startPos, startLoc); + node.operator = this.value; + node.left = this.type === types.eq ? this.toAssignable(left, false, refDestructuringErrors) : left; + if (!ownDestructuringErrors) { DestructuringErrors.call(refDestructuringErrors); } + 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); } } - return - } - name = "$" + name; - var other = propHash[name]; - if (other) { - var redefinition; - if (kind === "init") { - redefinition = this.strict && other.init || other.get || other.set; + 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.isContextual("await") && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction))) { + expr = this.parseAwait(); + 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 { - 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) { - var node = this.startNodeAt(startPos, startLoc); - node.operator = this.value; - node.left = this.type === types.eq ? this.toAssignable(left, false, refDestructuringErrors) : left; - if (!ownDestructuringErrors) { DestructuringErrors.call(refDestructuringErrors); } - 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; + 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() && this.input.slice(base.start, base.end) === "async"; + 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"); } + node = this.startNode(); + this.next(); + if (this.type !== types.dot && this.type !== types.bracketL && this.type !== types.parenL) + { this.unexpected(); } + return this.finishNode(node, "Super") + case types._this: + node = this.startNode(); 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 this.finishNode(node, "ThisExpression") + case types.name: + var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc; + var id = this.parseIdent(this.type !== types.name); + if (this.options.ecmaVersion >= 8 && !containsEsc && 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 && !containsEsc) { + 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(); } - } - 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.isContextual("await") && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction))) { - expr = this.parseAwait(); - sawUnary = true; - } else if (this.type.prefix) { - var node = this.startNode(), update = this.type === types.incDec; - node.operator = this.value; - node.prefix = true; + }; + pp$3.parseLiteral = function(value) { + var node = this.startNode(); + node.value = value; + node.raw = this.input.slice(this.start, this.end); 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"); + 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; + 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 { + 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(); + 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 (!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() && this.input.slice(base.start, base.end) === "async"; - 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"); + if (this.options.preserveParens) { + var par = this.startNodeAt(startPos, startLoc); + par.expression = val; + return this.finishNode(par, "ParenthesizedExpression") } else { - return base + 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; + var containsEsc = this.containsEsc; + node.property = this.parseIdent(true); + if (node.property.name !== "target" || containsEsc) + { 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 + }; } - } -}; - - -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"); } - node = this.startNode(); - this.next(); - if (this.type !== types.dot && this.type !== types.bracketL && this.type !== types.parenL) - { this.unexpected(); } - return this.finishNode(node, "Super") - - case types._this: - node = this.startNode(); this.next(); - return this.finishNode(node, "ThisExpression") - - case types.name: - var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc; - var id = this.parseIdent(this.type !== types.name); - if (this.options.ecmaVersion >= 8 && !containsEsc && 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 && !containsEsc) { - 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; + 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(); - 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; } + node.expressions = []; + var curElt = this.parseTemplateElement({isTagged: isTagged}); + node.quasis = [curElt]; + while (!curElt.tail) { + if (this$1.type === types.eof) { this$1.raise(this$1.pos, "Unterminated template literal"); } + 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})); } - 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) { + 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 || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types.star)) && + !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(); - - 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.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 { - exprList.push(this$1.parseMaybeAssign(false, refDestructuringErrors, this$1.parseParenItem)); + 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.parseProperty(isPattern, refDestructuringErrors); + if (!isPattern) { this$1.checkPropClash(prop, propHash, refDestructuringErrors); } + node.properties.push(prop); + } + return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression") + }; + pp$3.parseProperty = function(isPattern, refDestructuringErrors) { + var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc; + if (this.options.ecmaVersion >= 9 && this.eat(types.ellipsis)) { + if (isPattern) { + prop.argument = this.parseIdent(false); + if (this.type === types.comma) { + this.raise(this.start, "Comma is not permitted after the rest element"); + } + return this.finishNode(prop, "RestElement") } + if (this.type === types.parenL && refDestructuringErrors) { + if (refDestructuringErrors.parenthesizedAssign < 0) { + refDestructuringErrors.parenthesizedAssign = this.start; + } + if (refDestructuringErrors.parenthesizedBind < 0) { + refDestructuringErrors.parenthesizedBind = this.start; + } + } + prop.argument = this.parseMaybeAssign(false, refDestructuringErrors); + if (this.type === types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) { + refDestructuringErrors.trailingComma = this.start; + } + return this.finishNode(prop, "SpreadElement") } - 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(); - 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]; + 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.star); } } - } 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; var containsEsc = this.containsEsc; - node.property = this.parseIdent(true); - if (node.property.name !== "target" || containsEsc) - { 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) { - if (this$1.type === types.eof) { this$1.raise(this$1.pos, "Unterminated template literal"); } - 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 || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types.star)) && - !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.parseProperty(isPattern, refDestructuringErrors); - if (!isPattern) { this$1.checkPropClash(prop, propHash, refDestructuringErrors); } - node.properties.push(prop); - } - return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression") -}; - -pp$3.parseProperty = function(isPattern, refDestructuringErrors) { - var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc; - if (this.options.ecmaVersion >= 9 && this.eat(types.ellipsis)) { - if (isPattern) { - prop.argument = this.parseIdent(false); - if (this.type === types.comma) { - this.raise(this.start, "Comma is not permitted after the rest element"); - } - return this.finishNode(prop, "RestElement") + this.parsePropertyName(prop); + if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) { + isAsync = true; + isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star); + this.parsePropertyName(prop, refDestructuringErrors); + } else { + isAsync = false; } - if (this.type === types.parenL && refDestructuringErrors) { - if (refDestructuringErrors.parenthesizedAssign < 0) { - refDestructuringErrors.parenthesizedAssign = this.start; + this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc); + return this.finishNode(prop, "Property") + }; + pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) { + 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 (!isPattern && !containsEsc && + 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) { 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; } - if (refDestructuringErrors.parenthesizedBind < 0) { - refDestructuringErrors.parenthesizedBind = this.start; + 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; } } - prop.argument = this.parseMaybeAssign(false, refDestructuringErrors); - if (this.type === types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) { - refDestructuringErrors.trailingComma = this.start; + 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; } - 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.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.star); - this.parsePropertyName(prop, refDestructuringErrors); - } else { - isAsync = false; - } - this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc); - return this.finishNode(prop, "Property") -}; - -pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) { - 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 (!isPattern && !containsEsc && - 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) { 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); + 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 { - prop.value = prop.key; + 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.adaptDirectivePrologue(node.body.body); + 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); } - 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; + }; + 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 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.adaptDirectivePrologue(node.body.body); - 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; } + 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)) { + if (!this.inAsync && name === "await") + { this.raiseRecoverable(start, "Can not use keyword 'await' outside an async function"); } + 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; + if ((node.name === "class" || node.name === "function") && + (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) { + this.context.pop(); + } } else { - elt = this$1.parseMaybeAssign(false, refDestructuringErrors); + this.unexpected(); } - 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)) { - if (!this.inAsync && name === "await") - { this.raiseRecoverable(start, "Can not use keyword 'await' outside an async function"); } - 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; - - if ((node.name === "class" || node.name === "function") && - (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) { - this.context.pop(); + 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(); } - } 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 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 } - 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) { + 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; - 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; } + }; + 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[index] = types$1.f_gen; } - } - this.exprAllowed = true; -}; - -types.name.updateContext = function(prevType) { - var allowed = false; - if (this.options.ecmaVersion >= 6 && prevType !== types.dot) { - if (this.value === "of" && !this.exprAllowed || - this.value === "yield" && this.inGeneratorContext()) - { allowed = true; } - } - this.exprAllowed = allowed; -}; - -var data = { - "$LONE": [ - "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" - ], - "General_Category": [ - "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" - ], - "Script": [ - "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", - "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", - "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", - "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", - "Tibetan", - "Tibt", - "Tifinagh", - "Tfng", - "Tirhuta", - "Tirh", - "Ugaritic", - "Ugar", - "Vai", - "Vaii", - "Warang_Citi", - "Wara", - "Yi", - "Yiii", - "Zanabazar_Square", - "Zanb" - ] -}; -Array.prototype.push.apply(data.$LONE, data.General_Category); -data.gc = data.General_Category; -data.sc = data.Script_Extensions = data.scx = data.Script; - -var pp$9 = Parser.prototype; - -var RegExpValidationState = function RegExpValidationState(parser) { - this.parser = parser; - this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : ""); - this.source = ""; - this.flags = ""; - this.start = 0; - this.switchU = false; - this.switchN = false; - this.pos = 0; - this.lastIntValue = 0; - this.lastStringValue = ""; - this.lastAssertionIsQuantifiable = false; - this.numCapturingParens = 0; - this.maxBackReference = 0; - this.groupNames = []; - this.backReferenceNames = []; -}; - -RegExpValidationState.prototype.reset = function reset (start, pattern, flags) { - var unicode = flags.indexOf("u") !== -1; - this.start = start | 0; - this.source = pattern + ""; - this.flags = flags; - this.switchU = unicode && this.parser.options.ecmaVersion >= 6; - 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) { - var s = this.source; - var l = s.length; - if (i >= l) { - return -1 - } - var c = s.charCodeAt(i); - if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { - return c - } - return (c << 10) + s.charCodeAt(i + 1) - 0x35FDC00 -}; - -RegExpValidationState.prototype.nextIndex = function nextIndex (i) { - var s = this.source; - var l = s.length; - if (i >= l) { - return l - } - var c = s.charCodeAt(i); - if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { - return i + 1 - } - return i + 2 -}; - -RegExpValidationState.prototype.current = function current () { - return this.at(this.pos) -}; - -RegExpValidationState.prototype.lookahead = function lookahead () { - return this.at(this.nextIndex(this.pos)) -}; - -RegExpValidationState.prototype.advance = function advance () { - this.pos = this.nextIndex(this.pos); -}; - -RegExpValidationState.prototype.eat = function eat (ch) { - if (this.current() === ch) { - this.advance(); - return true - } - return false -}; - -function codePointToString$1(ch) { - if (ch <= 0xFFFF) { return String.fromCharCode(ch) } - ch -= 0x10000; - return String.fromCharCode((ch >> 10) + 0xD800, (ch & 0x03FF) + 0xDC00) -} - -pp$9.validateRegExpFlags = function(state) { - var this$1 = this; - - var validFlags = state.validFlags; - var flags = state.flags; - - for (var i = 0; i < flags.length; i++) { - var flag = flags.charAt(i); - if (validFlags.indexOf(flag) === -1) { - this$1.raise(state.start, "Invalid regular expression flag"); + { 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; } } - if (flags.indexOf(flag, i + 1) > -1) { - this$1.raise(state.start, "Duplicate regular expression flag"); + this.exprAllowed = true; + }; + types.name.updateContext = function(prevType) { + var allowed = false; + if (this.options.ecmaVersion >= 6 && prevType !== types.dot) { + if (this.value === "of" && !this.exprAllowed || + this.value === "yield" && this.inGeneratorContext()) + { allowed = true; } + } + this.exprAllowed = allowed; + }; + var data = { + "$LONE": [ + "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" + ], + "General_Category": [ + "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" + ], + "Script": [ + "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", + "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", + "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", + "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", + "Tibetan", + "Tibt", + "Tifinagh", + "Tfng", + "Tirhuta", + "Tirh", + "Ugaritic", + "Ugar", + "Vai", + "Vaii", + "Warang_Citi", + "Wara", + "Yi", + "Yiii", + "Zanabazar_Square", + "Zanb" + ] + }; + Array.prototype.push.apply(data.$LONE, data.General_Category); + data.gc = data.General_Category; + data.sc = data.Script_Extensions = data.scx = data.Script; + var pp$9 = Parser.prototype; + var RegExpValidationState = function RegExpValidationState(parser) { + this.parser = parser; + this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : ""); + this.source = ""; + this.flags = ""; + this.start = 0; + this.switchU = false; + this.switchN = false; + this.pos = 0; + this.lastIntValue = 0; + this.lastStringValue = ""; + this.lastAssertionIsQuantifiable = false; + this.numCapturingParens = 0; + this.maxBackReference = 0; + this.groupNames = []; + this.backReferenceNames = []; + }; + RegExpValidationState.prototype.reset = function reset (start, pattern, flags) { + var unicode = flags.indexOf("u") !== -1; + this.start = start | 0; + this.source = pattern + ""; + this.flags = flags; + this.switchU = unicode && this.parser.options.ecmaVersion >= 6; + 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) { + var s = this.source; + var l = s.length; + if (i >= l) { + return -1 } - } -}; - -pp$9.validateRegExpPattern = function(state) { - this.regexp_pattern(state); - - if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) { - state.switchN = true; - this.regexp_pattern(state); - } -}; - -pp$9.regexp_pattern = function(state) { - state.pos = 0; - state.lastIntValue = 0; - state.lastStringValue = ""; - state.lastAssertionIsQuantifiable = false; - state.numCapturingParens = 0; - state.maxBackReference = 0; - state.groupNames.length = 0; - state.backReferenceNames.length = 0; - - this.regexp_disjunction(state); - - if (state.pos !== state.source.length) { - if (state.eat(0x29 )) { - state.raise("Unmatched ')'"); + var c = s.charCodeAt(i); + if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { + return c } - if (state.eat(0x5D ) || state.eat(0x7D )) { - state.raise("Lone quantifier brackets"); + return (c << 10) + s.charCodeAt(i + 1) - 0x35FDC00 + }; + RegExpValidationState.prototype.nextIndex = function nextIndex (i) { + var s = this.source; + var l = s.length; + if (i >= l) { + return l } - } - 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.indexOf(name) === -1) { - state.raise("Invalid named capture referenced"); + var c = s.charCodeAt(i); + if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { + return i + 1 } + return i + 2 + }; + RegExpValidationState.prototype.current = function current () { + return this.at(this.pos) + }; + RegExpValidationState.prototype.lookahead = function lookahead () { + return this.at(this.nextIndex(this.pos)) + }; + RegExpValidationState.prototype.advance = function advance () { + this.pos = this.nextIndex(this.pos); + }; + RegExpValidationState.prototype.eat = function eat (ch) { + if (this.current() === ch) { + this.advance(); + return true + } + return false + }; + function codePointToString$1(ch) { + if (ch <= 0xFFFF) { return String.fromCharCode(ch) } + ch -= 0x10000; + return String.fromCharCode((ch >> 10) + 0xD800, (ch & 0x03FF) + 0xDC00) } -}; - -pp$9.regexp_disjunction = function(state) { - var this$1 = this; - - this.regexp_alternative(state); - while (state.eat(0x7C )) { - this$1.regexp_alternative(state); - } - - if (this.regexp_eatQuantifier(state, true)) { - state.raise("Nothing to repeat"); - } - if (state.eat(0x7B )) { - state.raise("Lone quantifier brackets"); - } -}; - -pp$9.regexp_alternative = function(state) { - while (state.pos < state.source.length && this.regexp_eatTerm(state)) - { } -}; - -pp$9.regexp_eatTerm = function(state) { - if (this.regexp_eatAssertion(state)) { - if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) { - if (state.switchU) { - state.raise("Invalid quantifier"); + pp$9.validateRegExpFlags = function(state) { + var this$1 = this; + var validFlags = state.validFlags; + var flags = state.flags; + for (var i = 0; i < flags.length; i++) { + var flag = flags.charAt(i); + if (validFlags.indexOf(flag) === -1) { + this$1.raise(state.start, "Invalid regular expression flag"); + } + if (flags.indexOf(flag, i + 1) > -1) { + this$1.raise(state.start, "Duplicate regular expression flag"); } } - return true - } - - if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) { - this.regexp_eatQuantifier(state); - return true - } - - return false -}; - -pp$9.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 + }; + pp$9.validateRegExpPattern = function(state) { + this.regexp_pattern(state); + if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) { + state.switchN = true; + this.regexp_pattern(state); } - state.pos = start; - } - - if (state.eat(0x28 ) && state.eat(0x3F )) { - var lookbehind = false; - if (this.options.ecmaVersion >= 9) { - lookbehind = state.eat(0x3C ); + }; + pp$9.regexp_pattern = function(state) { + state.pos = 0; + state.lastIntValue = 0; + state.lastStringValue = ""; + state.lastAssertionIsQuantifiable = false; + state.numCapturingParens = 0; + state.maxBackReference = 0; + state.groupNames.length = 0; + state.backReferenceNames.length = 0; + 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.eat(0x3D ) || state.eat(0x21 )) { - this.regexp_disjunction(state); - if (!state.eat(0x29 )) { - state.raise("Unterminated group"); + 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.indexOf(name) === -1) { + state.raise("Invalid named capture referenced"); } - state.lastAssertionIsQuantifiable = !lookbehind; - return true } - } - - state.pos = start; - return false -}; - -pp$9.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$9.regexp_eatQuantifierPrefix = function(state, noError) { - return ( - state.eat(0x2A ) || - state.eat(0x2B ) || - state.eat(0x3F ) || - this.regexp_eatBracedQuantifier(state, noError) - ) -}; -pp$9.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"); + }; + pp$9.regexp_disjunction = function(state) { + var this$1 = this; + this.regexp_alternative(state); + while (state.eat(0x7C )) { + this$1.regexp_alternative(state); + } + if (this.regexp_eatQuantifier(state, true)) { + state.raise("Nothing to repeat"); + } + if (state.eat(0x7B )) { + state.raise("Lone quantifier brackets"); + } + }; + pp$9.regexp_alternative = function(state) { + while (state.pos < state.source.length && this.regexp_eatTerm(state)) + { } + }; + pp$9.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 } + return true } - if (state.switchU && !noError) { - state.raise("Incomplete quantifier"); + if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) { + this.regexp_eatQuantifier(state); + return true } - state.pos = start; - } - return false -}; - -pp$9.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$9.regexp_eatReverseSolidusAtomEscape = function(state) { - var start = state.pos; - if (state.eat(0x5C )) { - if (this.regexp_eatAtomEscape(state)) { + return false + }; + pp$9.regexp_eatAssertion = function(state) { + var start = state.pos; + state.lastAssertionIsQuantifiable = false; + if (state.eat(0x5E ) || state.eat(0x24 )) { return true } - state.pos = start; - } - return false -}; -pp$9.regexp_eatUncapturingGroup = function(state) { - var start = state.pos; - if (state.eat(0x28 )) { - if (state.eat(0x3F ) && state.eat(0x3A )) { - this.regexp_disjunction(state); - if (state.eat(0x29 )) { + if (state.eat(0x5C )) { + if (state.eat(0x42 ) || state.eat(0x62 )) { return true } - state.raise("Unterminated group"); + state.pos = start; } - state.pos = start; - } - return false -}; -pp$9.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"); + 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 + } } - this.regexp_disjunction(state); - if (state.eat(0x29 )) { - state.numCapturingParens += 1; + state.pos = start; + return false + }; + pp$9.regexp_eatQuantifier = function(state, noError) { + if ( noError === void 0 ) noError = false; + if (this.regexp_eatQuantifierPrefix(state, noError)) { + state.eat(0x3F ); return true } - state.raise("Unterminated group"); - } - return false -}; - -pp$9.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$9.regexp_eatInvalidBracedQuantifier = function(state) { - if (this.regexp_eatBracedQuantifier(state, true)) { - state.raise("Nothing to repeat"); - } - return false -}; - -pp$9.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$9.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$9.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$9.regexp_groupSpecifier = function(state) { - if (state.eat(0x3F )) { - if (this.regexp_eatGroupName(state)) { - if (state.groupNames.indexOf(state.lastStringValue) !== -1) { - state.raise("Duplicate capture group name"); + return false + }; + pp$9.regexp_eatQuantifierPrefix = function(state, noError) { + return ( + state.eat(0x2A ) || + state.eat(0x2B ) || + state.eat(0x3F ) || + this.regexp_eatBracedQuantifier(state, noError) + ) + }; + pp$9.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 + } } - state.groupNames.push(state.lastStringValue); - return - } - state.raise("Invalid group"); - } -}; - -pp$9.regexp_eatGroupName = function(state) { - state.lastStringValue = ""; - if (state.eat(0x3C )) { - if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E )) { - return true + if (state.switchU && !noError) { + state.raise("Incomplete quantifier"); + } + state.pos = start; } - state.raise("Invalid capture group name"); - } - return false -}; - -pp$9.regexp_eatRegExpIdentifierName = function(state) { - state.lastStringValue = ""; - if (this.regexp_eatRegExpIdentifierStart(state)) { - state.lastStringValue += codePointToString$1(state.lastIntValue); - while (this.regexp_eatRegExpIdentifierPart(state)) { - state.lastStringValue += codePointToString$1(state.lastIntValue); + return false + }; + pp$9.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$9.regexp_eatReverseSolidusAtomEscape = function(state) { + var start = state.pos; + if (state.eat(0x5C )) { + if (this.regexp_eatAtomEscape(state)) { + return true + } + state.pos = start; } - return true - } - return false -}; - -pp$9.regexp_eatRegExpIdentifierStart = function(state) { - var start = state.pos; - var ch = state.current(); - state.advance(); - - if (ch === 0x5C && this.regexp_eatRegExpUnicodeEscapeSequence(state)) { - 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$9.regexp_eatRegExpIdentifierPart = function(state) { - var start = state.pos; - var ch = state.current(); - state.advance(); - - if (ch === 0x5C && this.regexp_eatRegExpUnicodeEscapeSequence(state)) { - 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$9.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"); + return false + }; + pp$9.regexp_eatUncapturingGroup = function(state) { + var start = state.pos; + if (state.eat(0x28 )) { + if (state.eat(0x3F ) && state.eat(0x3A )) { + this.regexp_disjunction(state); + if (state.eat(0x29 )) { + return true + } + state.raise("Unterminated group"); + } + state.pos = start; } - state.raise("Invalid escape"); - } - return false -}; -pp$9.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 false + }; + pp$9.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$9.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$9.regexp_eatInvalidBracedQuantifier = function(state) { + if (this.regexp_eatBracedQuantifier(state, true)) { + state.raise("Nothing to repeat"); + } + return false + }; + pp$9.regexp_eatSyntaxCharacter = function(state) { + var ch = state.current(); + if (isSyntaxCharacter(ch)) { + state.lastIntValue = ch; + state.advance(); return true } - if (n <= state.numCapturingParens) { + 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$9.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$9.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 } - state.pos = start; - } - return false -}; -pp$9.regexp_eatKGroupName = function(state) { - if (state.eat(0x6B )) { - if (this.regexp_eatGroupName(state)) { - state.backReferenceNames.push(state.lastStringValue); + return false + }; + pp$9.regexp_groupSpecifier = function(state) { + if (state.eat(0x3F )) { + if (this.regexp_eatGroupName(state)) { + if (state.groupNames.indexOf(state.lastStringValue) !== -1) { + state.raise("Duplicate capture group name"); + } + state.groupNames.push(state.lastStringValue); + return + } + state.raise("Invalid group"); + } + }; + pp$9.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$9.regexp_eatRegExpIdentifierName = function(state) { + state.lastStringValue = ""; + if (this.regexp_eatRegExpIdentifierStart(state)) { + state.lastStringValue += codePointToString$1(state.lastIntValue); + while (this.regexp_eatRegExpIdentifierPart(state)) { + state.lastStringValue += codePointToString$1(state.lastIntValue); + } return true } - state.raise("Invalid named reference"); - } - return false -}; - -pp$9.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) || - (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) || - this.regexp_eatIdentityEscape(state) - ) -}; -pp$9.regexp_eatCControlLetter = function(state) { - var start = state.pos; - if (state.eat(0x63 )) { - if (this.regexp_eatControlLetter(state)) { + return false + }; + pp$9.regexp_eatRegExpIdentifierStart = function(state) { + var start = state.pos; + var ch = state.current(); + state.advance(); + if (ch === 0x5C && this.regexp_eatRegExpUnicodeEscapeSequence(state)) { + 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 } - return false -}; -pp$9.regexp_eatZero = function(state) { - if (state.current() === 0x30 && !isDecimalDigit(state.lookahead())) { - state.lastIntValue = 0; - state.advance(); - return true - } - return false -}; - -pp$9.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$9.regexp_eatControlLetter = function(state) { - var ch = state.current(); - if (isControlLetter(ch)) { - state.lastIntValue = ch % 0x20; + pp$9.regexp_eatRegExpIdentifierPart = function(state) { + var start = state.pos; + var ch = state.current(); state.advance(); - return true - } - return false -}; -function isControlLetter(ch) { - return ( - (ch >= 0x41 && ch <= 0x5A ) || - (ch >= 0x61 && ch <= 0x7A ) - ) -} - -pp$9.regexp_eatRegExpUnicodeEscapeSequence = function(state) { - var start = state.pos; - - if (state.eat(0x75 )) { - if (this.regexp_eatFixedHexDigits(state, 4)) { - var lead = state.lastIntValue; - if (state.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; - } + if (ch === 0x5C && this.regexp_eatRegExpUnicodeEscapeSequence(state)) { + 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$9.regexp_eatAtomEscape = function(state) { if ( - state.switchU && - state.eat(0x7B ) && - this.regexp_eatHexDigits(state) && - state.eat(0x7D ) && - isValidUnicode(state.lastIntValue) + this.regexp_eatBackReference(state) || + this.regexp_eatCharacterClassEscape(state) || + this.regexp_eatCharacterEscape(state) || + (state.switchN && this.regexp_eatKGroupName(state)) ) { return true } if (state.switchU) { - state.raise("Invalid unicode escape"); + if (state.current() === 0x63 ) { + state.raise("Invalid unicode escape"); + } + state.raise("Invalid escape"); } - state.pos = start; - } - - return false -}; -function isValidUnicode(ch) { - return ch >= 0 && ch <= 0x10FFFF -} - -pp$9.regexp_eatIdentityEscape = function(state) { - if (state.switchU) { - if (this.regexp_eatSyntaxCharacter(state)) { - return true + return false + }; + pp$9.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$9.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$9.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) || + (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) || + this.regexp_eatIdentityEscape(state) + ) + }; + pp$9.regexp_eatCControlLetter = function(state) { + var start = state.pos; + if (state.eat(0x63 )) { + if (this.regexp_eatControlLetter(state)) { + return true + } + state.pos = start; } - if (state.eat(0x2F )) { - state.lastIntValue = 0x2F; + return false + }; + pp$9.regexp_eatZero = function(state) { + if (state.current() === 0x30 && !isDecimalDigit(state.lookahead())) { + state.lastIntValue = 0; + state.advance(); 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$9.regexp_eatDecimalEscape = function(state) { - state.lastIntValue = 0; - var ch = state.current(); - if (ch >= 0x31 && ch <= 0x39 ) { - do { - state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 ); + }; + pp$9.regexp_eatControlEscape = function(state) { + var ch = state.current(); + if (ch === 0x74 ) { + state.lastIntValue = 0x09; state.advance(); - } while ((ch = state.current()) >= 0x30 && ch <= 0x39 ) - return true - } - return false -}; - -pp$9.regexp_eatCharacterClassEscape = function(state) { - var ch = state.current(); - - if (isCharacterClassEscape(ch)) { - state.lastIntValue = -1; - state.advance(); - return true - } - - if ( - state.switchU && - this.options.ecmaVersion >= 9 && - (ch === 0x50 || ch === 0x70 ) - ) { - state.lastIntValue = -1; - state.advance(); - if ( - state.eat(0x7B ) && - this.regexp_eatUnicodePropertyValueExpression(state) && - state.eat(0x7D ) - ) { return true } - state.raise("Invalid property name"); - } - - return false -}; -function isCharacterClassEscape(ch) { - return ( - ch === 0x64 || - ch === 0x44 || - ch === 0x73 || - ch === 0x53 || - ch === 0x77 || - ch === 0x57 - ) -} - -pp$9.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); + if (ch === 0x6E ) { + state.lastIntValue = 0x0A; + state.advance(); return true } - } - state.pos = start; - - if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) { - var nameOrValue = state.lastStringValue; - this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue); - return true - } - return false -}; -pp$9.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) { - if (!data.hasOwnProperty(name) || data[name].indexOf(value) === -1) { - state.raise("Invalid property name"); - } -}; -pp$9.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) { - if (data.$LONE.indexOf(nameOrValue) === -1) { - state.raise("Invalid property name"); - } -}; - -pp$9.regexp_eatUnicodePropertyName = function(state) { - var ch = 0; - state.lastStringValue = ""; - while (isUnicodePropertyNameCharacter(ch = state.current())) { - state.lastStringValue += codePointToString$1(ch); - state.advance(); - } - return state.lastStringValue !== "" -}; -function isUnicodePropertyNameCharacter(ch) { - return isControlLetter(ch) || ch === 0x5F -} - -pp$9.regexp_eatUnicodePropertyValue = function(state) { - var ch = 0; - state.lastStringValue = ""; - while (isUnicodePropertyValueCharacter(ch = state.current())) { - state.lastStringValue += codePointToString$1(ch); - state.advance(); - } - return state.lastStringValue !== "" -}; -function isUnicodePropertyValueCharacter(ch) { - return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch) -} - -pp$9.regexp_eatLoneUnicodePropertyNameOrValue = function(state) { - return this.regexp_eatUnicodePropertyValue(state) -}; - -pp$9.regexp_eatCharacterClass = function(state) { - if (state.eat(0x5B )) { - state.eat(0x5E ); - this.regexp_classRanges(state); - if (state.eat(0x5D )) { + if (ch === 0x76 ) { + state.lastIntValue = 0x0B; + state.advance(); return true } - state.raise("Unterminated character class"); - } - return false -}; - -pp$9.regexp_classRanges = function(state) { - var this$1 = this; - - while (this.regexp_eatClassAtom(state)) { - var left = state.lastIntValue; - if (state.eat(0x2D ) && this$1.regexp_eatClassAtom(state)) { - var right = state.lastIntValue; - if (state.switchU && (left === -1 || right === -1)) { - state.raise("Invalid character class"); + if (ch === 0x66 ) { + state.lastIntValue = 0x0C; + state.advance(); + return true + } + if (ch === 0x72 ) { + state.lastIntValue = 0x0D; + state.advance(); + return true + } + return false + }; + pp$9.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$9.regexp_eatRegExpUnicodeEscapeSequence = function(state) { + var start = state.pos; + if (state.eat(0x75 )) { + if (this.regexp_eatFixedHexDigits(state, 4)) { + var lead = state.lastIntValue; + if (state.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 (left !== -1 && right !== -1 && left > right) { - state.raise("Range out of order in character class"); + if ( + state.switchU && + state.eat(0x7B ) && + this.regexp_eatHexDigits(state) && + state.eat(0x7D ) && + isValidUnicode(state.lastIntValue) + ) { + return true + } + if (state.switchU) { + state.raise("Invalid unicode escape"); } + state.pos = start; } + return false + }; + function isValidUnicode(ch) { + return ch >= 0 && ch <= 0x10FFFF } -}; - -pp$9.regexp_eatClassAtom = function(state) { - var start = state.pos; - - if (state.eat(0x5C )) { - if (this.regexp_eatClassEscape(state)) { - return true - } + pp$9.regexp_eatIdentityEscape = function(state) { if (state.switchU) { - var ch$1 = state.current(); - if (ch$1 === 0x63 || isOctalDigit(ch$1)) { - state.raise("Invalid class escape"); + if (this.regexp_eatSyntaxCharacter(state)) { + return true } - state.raise("Invalid escape"); + if (state.eat(0x2F )) { + state.lastIntValue = 0x2F; + return true + } + return false } - state.pos = start; - } - - var ch = state.current(); - if (ch !== 0x5D ) { - state.lastIntValue = ch; - state.advance(); - return true - } - - return false -}; - -pp$9.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)) { + var ch = state.current(); + if (ch !== 0x63 && (!state.switchN || ch !== 0x6B )) { + state.lastIntValue = ch; + state.advance(); return true } - state.pos = start; - } - - return ( - this.regexp_eatCharacterClassEscape(state) || - this.regexp_eatCharacterEscape(state) - ) -}; - -pp$9.regexp_eatClassControlLetter = function(state) { - var ch = state.current(); - if (isDecimalDigit(ch) || ch === 0x5F ) { - state.lastIntValue = ch % 0x20; - state.advance(); - return true - } - return false -}; - -pp$9.regexp_eatHexEscapeSequence = function(state) { - var start = state.pos; - if (state.eat(0x78 )) { - if (this.regexp_eatFixedHexDigits(state, 2)) { + return false + }; + pp$9.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 } - if (state.switchU) { - state.raise("Invalid escape"); + return false + }; + pp$9.regexp_eatCharacterClassEscape = function(state) { + var ch = state.current(); + if (isCharacterClassEscape(ch)) { + state.lastIntValue = -1; + state.advance(); + return true + } + if ( + state.switchU && + this.options.ecmaVersion >= 9 && + (ch === 0x50 || ch === 0x70 ) + ) { + state.lastIntValue = -1; + state.advance(); + if ( + state.eat(0x7B ) && + this.regexp_eatUnicodePropertyValueExpression(state) && + state.eat(0x7D ) + ) { + return true + } + state.raise("Invalid property name"); + } + return false + }; + function isCharacterClassEscape(ch) { + return ( + ch === 0x64 || + ch === 0x44 || + ch === 0x73 || + ch === 0x53 || + ch === 0x77 || + ch === 0x57 + ) + } + pp$9.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 true + } } state.pos = start; + if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) { + var nameOrValue = state.lastStringValue; + this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue); + return true + } + return false + }; + pp$9.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) { + if (!data.hasOwnProperty(name) || data[name].indexOf(value) === -1) { + state.raise("Invalid property name"); + } + }; + pp$9.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) { + if (data.$LONE.indexOf(nameOrValue) === -1) { + state.raise("Invalid property name"); + } + }; + pp$9.regexp_eatUnicodePropertyName = function(state) { + var ch = 0; + state.lastStringValue = ""; + while (isUnicodePropertyNameCharacter(ch = state.current())) { + state.lastStringValue += codePointToString$1(ch); + state.advance(); + } + return state.lastStringValue !== "" + }; + function isUnicodePropertyNameCharacter(ch) { + return isControlLetter(ch) || ch === 0x5F + } + pp$9.regexp_eatUnicodePropertyValue = function(state) { + var ch = 0; + state.lastStringValue = ""; + while (isUnicodePropertyValueCharacter(ch = state.current())) { + state.lastStringValue += codePointToString$1(ch); + state.advance(); + } + return state.lastStringValue !== "" + }; + function isUnicodePropertyValueCharacter(ch) { + return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch) } - return false -}; - -pp$9.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$9.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(); + pp$9.regexp_eatLoneUnicodePropertyNameOrValue = function(state) { + return this.regexp_eatUnicodePropertyValue(state) + }; + pp$9.regexp_eatCharacterClass = function(state) { + if (state.eat(0x5B )) { + state.eat(0x5E ); + this.regexp_classRanges(state); + if (state.eat(0x5D )) { + return true + } + state.raise("Unterminated character class"); + } + return false + }; + pp$9.regexp_classRanges = function(state) { + var this$1 = this; + while (this.regexp_eatClassAtom(state)) { + var left = state.lastIntValue; + if (state.eat(0x2D ) && this$1.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$9.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$9.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$9.regexp_eatClassControlLetter = function(state) { + var ch = state.current(); + if (isDecimalDigit(ch) || ch === 0x5F ) { + state.lastIntValue = ch % 0x20; + state.advance(); + return true + } + return false + }; + pp$9.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$9.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 } - 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 ) + pp$9.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 ) + ) } - if (ch >= 0x61 && ch <= 0x66 ) { - return 10 + (ch - 0x61 ) + function hexToInt(ch) { + if (ch >= 0x41 && ch <= 0x46 ) { + return 10 + (ch - 0x41 ) + } + if (ch >= 0x61 && ch <= 0x66 ) { + return 10 + (ch - 0x61 ) + } + return ch - 0x30 } - return ch - 0x30 -} - -pp$9.regexp_eatLegacyOctalEscapeSequence = function(state) { - if (this.regexp_eatOctalDigit(state)) { - var n1 = state.lastIntValue; + pp$9.regexp_eatLegacyOctalEscapeSequence = function(state) { if (this.regexp_eatOctalDigit(state)) { - var n2 = state.lastIntValue; - if (n1 <= 3 && this.regexp_eatOctalDigit(state)) { - state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue; + 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 * 8 + n2; + state.lastIntValue = n1; } - } else { - state.lastIntValue = n1; + return true } - return true - } - return false -}; - -pp$9.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$9.regexp_eatFixedHexDigits = function(state, length) { - var start = state.pos; - state.lastIntValue = 0; - for (var i = 0; i < length; ++i) { + return false + }; + pp$9.regexp_eatOctalDigit = function(state) { var ch = state.current(); - if (!isHexDigit(ch)) { - state.pos = start; - return false + if (isOctalDigit(ch)) { + state.lastIntValue = ch - 0x30; + state.advance(); + return true } - state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch); - state.advance(); + state.lastIntValue = 0; + return false + }; + function isOctalDigit(ch) { + return ch >= 0x30 && ch <= 0x37 } - 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$8 = Parser.prototype; - - -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$9.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(); } - }; } - - -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; + 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$8 = Parser.prototype; + 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 + } + } } - case 10: case 8232: case 8233: - ++this$1.pos; - if (this$1.options.locations) { + }; } + 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 = this$1.pos; + this$1.lineStart = match.index + match[0].length; } - break - case 47: - switch (this$1.input.charCodeAt(this$1.pos + 1)) { - case 42: - this$1.skipBlockComment(); + } + 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: - this$1.skipLineComment(2); + 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: - break loop - } - break - default: - if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { - ++this$1.pos; - } else { - break loop + 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 && code === 42 && 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.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() + }; + 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) } - 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.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.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: + }; + pp$8.readToken_slash = function() { 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) } + 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 && code === 42 && 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.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.incDec, 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) -}; - -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 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.regexp, {pattern: pattern, flags: flags, 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; - if (!startsWithDot && this.readInt(10) === 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"); } - if (octal && /[89]/.test(this.input.slice(start, this.pos))) { octal = false; } - var next = this.input.charCodeAt(this.pos); - 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 str = this.input.slice(start, this.pos); - var val = octal ? parseInt(str, 8) : parseFloat(str); - 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.options.ecmaVersion >= 10)) { this$1.raise(this$1.start, "Unterminated string constant"); } - ++this$1.pos; + 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.inModule && this.input.charCodeAt(this.pos + 2) === 45 && + this.input.charCodeAt(this.pos + 3) === 45) { + this.skipLineComment(4); + this.skipSpace(); + return this.nextToken() } - } - 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 + 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) } - } - - 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) + 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) + }; + 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 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) { } - 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); + return this.finishToken(types.regexp, {pattern: pattern, flags: flags, 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; - 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; + 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; + if (!startsWithDot && this.readInt(10) === 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"); } + if (octal && /[89]/.test(this.input.slice(start, this.pos))) { octal = false; } + var next = this.input.charCodeAt(this.pos); + 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 str = this.input.slice(start, this.pos); + var val = octal ? parseInt(str, 8) : parseFloat(str); + 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 { - ++this$1.pos; + 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.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 + 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.options.ecmaVersion >= 10)) { this$1.raise(this$1.start, "Unterminated string constant"); } + ++this$1.pos; } - - 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); - } - 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" - ); + 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 } - 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; + this.inTemplateElement = false; + }; + pp$8.invalidStringToken = function(position, message) { + if (this.inTemplateElement && this.options.ecmaVersion >= 9) { + throw INVALID_TEMPLATE_ESCAPE_ERROR } else { - break + this.raise(position, message); } - 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.7.3"; - - -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 }); - -}))); - -},{}],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; + }; + 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) } - 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; + out += this$1.input.slice(chunkStart, this$1.pos); + return this$1.finishToken(types.template, out) } - } - 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; + 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; } } - return null; - } - - function getContextVariableName(value) { - const i = contextVariables.indexOf(value); - if (i !== -1) { - return `${contextName}Variable${i}`; + }; + 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)) + } } - 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); + 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); + } + 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 result; - }; + return String.fromCharCode(octal) + } + return String.fromCharCode(ch) } - extensionEntityNames[extension[property]] = property; - return extension[property]; - } - - function getExtensionEntity(value) { - if (extensionEntityNames.hasOwnProperty(value)) { - return `${contextName}.${extensionEntityNames[value]}`; + }; + 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 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; + 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) + }; + function parse(input, options) { + return new Parser(options, input).parse() } -} -function argumentsToString(args, options) { - const { variables, onUnrecognizedArgumentLookup } = options; - return (Array.from(args).map((arg) => { - const variableName = getVariableName(arg); - if (variableName) { - return variableName; + class Texture { + constructor(settings) { + const { + texture, + size, + dimensions, + output, + context, + type = 'NumberTexture', + } = settings; + if (!output) throw new Error('settings property "output" required.'); + if (!context) throw new Error('settings property "context" required.'); + this.texture = texture; + this.size = size; + this.dimensions = dimensions; + this.output = output; + this.context = context; + this.kernel = null; + this.type = type; } - 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; - } - } + toArray() { + throw new Error(`Not implemented on ${this.constructor.name}`); } - if (onUnrecognizedArgumentLookup) { - return onUnrecognizedArgumentLookup(value); + delete() { + return this.context.deleteTexture(this.texture); } - 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; - } + function 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'); + }const _systemEndianness = getSystemEndianness(); + function systemEndianness() { + return _systemEndianness; + }function getVariableType(value, strictIntegers) { + if (isArray(value)) { + if (value[0].nodeName === 'IMG') { + return 'HTMLImageArray'; } - 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 'Array'; } - } - 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); + switch (value.constructor) { + case Boolean: + return 'Boolean'; + case Number: + return strictIntegers && Number.isInteger(value) ? 'Integer' : 'Float'; + case Texture: + return value.type; + case Input: + return 'Input'; } - 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); + switch (value.nodeName) { + case 'IMG': + return 'HTMLImage'; + case 'VIDEO': + return 'HTMLVideo'; } - } -} - -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); + return value.hasOwnProperty('type') ? value.type : 'Unknown'; + }const utils$1 = { + systemEndianness, + getSystemEndianness, + isFunction, + isFunctionString, + getFunctionNameFromString, + getFunctionBodyFromString(funcStr) { + return funcStr.substring(funcStr.indexOf('{') + 1, funcStr.lastIndexOf('}')); + }, + getArgumentNamesFromString, + 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$1.clone(obj[key]); + delete obj.isActiveClone; + } + } + return temp; + }, + isArray, + getVariableType, + 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$1.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$1.roundTo((dimensions[0] || 1) * (dimensions[1] || 1) * (dimensions[2] || 1) * (dimensions[3] || 1), 4); + const texelCount = totalArea / bitRatio; + return utils$1.closestSquareDimensions(texelCount); + }, + getMemoryOptimizedPackedTextureSize(dimensions, bitRatio) { + const [w, h, d] = dimensions; + const totalArea = utils$1.roundTo((w || 1) * (h || 1) * (d || 1), 4); + const texelCount = totalArea / (4 / bitRatio); + return utils$1.closestSquareDimensions(texelCount); + }, + roundTo(n, d) { + return Math.floor((n + d - 1) / d) * d; + }, + getDimensions(x, pad) { + let ret; + if (isArray(x)) { + const dim = []; + let temp = x; + while (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}`); } - 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.exec = function() { - return new Promise((resolve, reject) => { - try { - resolve(kernel.apply(kernel, arguments)); - } catch(e) { - reject(e); + if (pad) { + ret = Array.from(ret); + while (ret.length < 3) { + ret.push(1); + } } - }); - }; - 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; - }; - - kernel.setWarnVarUsage = () => { - return kernel; - }; - kernel.setOptimizeFloatMemory = () => { - return kernel; - }; - kernel.setArgumentTypes = () => { - return kernel; - }; - kernel.setDebug = () => { - return kernel; - }; - kernel.setLoopMaxIterations = () => { - return kernel; - }; - kernel.setPipeline = () => { - return kernel; - }; - kernel.setPrecision = () => { - return kernel; - }; - kernel.setImmutable = () => { - return kernel; - }; - kernel.setFunctions = () => { - return kernel; - }; - kernel.addSubKernel = () => { - return kernel; - }; - kernel.destroy = () => {}; - kernel.validateSettings = () => {}; - if (kernel.graphical && kernel.output) { - setupGraphical(kernel); - } - 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 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; } - 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":112}],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(', '); + }, + 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; } - 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; + }, + 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; + } } } - 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'); + }, + flattenTo(array, target) { + if (isArray(array[0])) { + if (isArray(array[0][0])) { + if (isArray(array[0][0][0])) { + utils$1.flatten4dArrayTo(array, target); + } else { + utils$1.flatten3dArrayTo(array, target); + } + } else { + utils$1.flatten2dArrayTo(array, target); + } + } else { + target.set(array); } - retArr.push(`for (let ${iVariableName}=0;${iVariableName} 0) { - retArr.push(`if (!${testArr.join('')}) break;\n`); + }, + 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)); } - 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); + return result; + }, + getAstString, + 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'; } - this.popState('block-body'); - } else { - retArr.push('{\n'); - for (let i = 0; i < bNode.body.length; i++) { - this.astGeneric(bNode.body[i], retArr); + }, + warnDeprecated, + functionToIFunction, + 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); } - retArr.push('}\n'); - } - return retArr; - } - - astVariableDeclaration(varDecNode, retArr) { - if (varDecNode.kind === 'var' && this.warnVarUsage) { - this.varWarn(); - } - retArr.push(`${varDecNode.kind} `); - const { declarations } = varDecNode; - for (let i = 0; i < declarations.length; i++) { - if (i > 0) { - retArr.push(','); + 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); } - this.astGeneric(declarations[i], 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') { - this.astGeneric(ifNode.alternate, retArr); - } else { - retArr.push(' {\n'); - this.astGeneric(ifNode.alternate, retArr); - retArr.push('\n}\n'); + 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, + erectMemoryOptimized3DFloat, + 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 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'); + 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; } - continue; + yResults[y] = xResults; } - 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'); + 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; } - } - retArr.push('\n}'); - } - - astThisExpression(tNode, retArr) { - retArr.push('_this'); - return retArr; - } + 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 = parse(source); + const functionDependencies = []; + 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); + case 'FunctionDeclaration': + return `function ${ast.id.name}(${ast.params.map(flatten).join(', ')}) ${ flatten(ast.body) }`; + case 'BlockStatement': { + const result = []; + for (let i = 0; i < ast.body.length; i++) { + result.push(flatten(ast.body[i]), ';\n'); + } + return `{\n${result.join('')}}`; + } + case 'VariableDeclaration': + switch (ast.declarations[0].id.type) { + case 'ObjectPattern': { + const source = flatten(ast.declarations[0].init); + const properties = ast.declarations.map(declaration => declaration.id.properties.map(flatten))[0]; + if (/this/.test(source)) { + const result = []; + const lookups = properties.map(thisLookup); + for (let i = 0; i < lookups.length; i++) { + const lookup = lookups[i]; + if (lookup === null) continue; + const property = properties[i]; + result.push(`${ast.kind} ${ property } = ${ lookup };\n`); + } + return result.join(''); + } + return `${ast.kind} { ${properties} } = ${source}`; + } + case 'ArrayPattern': + return `${ast.kind} [ ${ ast.declarations.map(declaration => flatten(declaration.id)).join(', ') } ] = ${flatten(ast.declarations[0].init)}`; + } + if (doNotDefine && doNotDefine.indexOf(ast.declarations[0].id.name) !== -1) { + return ''; + } + return `${ast.kind} ${ast.declarations[0].id.name} = ${flatten(ast.declarations[0].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 '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; + } + flattenedFunctionDependencies.push(utils$1.flattenFunctionToString(functionDependency, settings) + ';\n'); + } + return flattenedFunctionDependencies.join('') + result; + } + return result; + }, + }; - 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'); + 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 (!isFunctionString(source)) { + throw new Error('source not a function string'); + } + } + this.useLegacyEncoder = false; + this.fallbackRequested = false; + this.onRequestFallback = null; + this.argumentNames = typeof source === 'string' ? getArgumentNamesFromString(source) : null; + this.argumentTypes = null; + this.argumentSizes = null; + this.argumentBitRatios = null; + this.kernelArguments = null; + this.kernelConstants = 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 = 'balanced'; + this.plugins = null; + this.returnType = null; + this.leadingReturnStatement = null; + this.followingReturnStatement = null; + this.optimizeFloatMemory = null; + this.strictIntegers = false; + this.fixIntegerDivisionAccuracy = null; + this.warnVarUsage = true; + } + 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 'z': - retArr.push('outputZ'); + case 'functions': + if (typeof settings.functions[0] === 'function') { + this.functions = settings.functions.map(source => functionToIFunction(source)); + continue; + } break; - default: - throw this.astErrorOutput('Unexpected expression', mNode); + case 'graphical': + if (settings[p] && !settings.hasOwnProperty('precision')) { + this.precision = 'unsigned'; + } + this[p] = settings[p]; + continue; } - 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; + 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 }`); + } + setupArguments(args) { + this.kernelArguments = []; + if (!this.argumentTypes) { + if (!this.argumentTypes) { + this.argumentTypes = []; + for (let i = 0; i < args.length; i++) { + const argType = getVariableType(args[i], this.strictIntegers); + const type = argType === 'Integer' ? 'Number' : argType; + this.argumentTypes.push(type); + this.kernelArguments.push({ + type + }); + } } - 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; + } else { + for (let i = 0; i < this.argumentTypes.length; i++) { + this.kernelArguments.push({ + type: this.argumentTypes[i] + }); } - 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; - 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; + } + 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`); } } - - const markupName = `${origin}_${name}`; - - switch (type) { - case 'Array(2)': - case 'Array(3)': - case 'Array(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(']'); + 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 = getVariableType(this.constants[name], this.strictIntegers); + this.constantTypes[name] = type; + this.kernelConstants.push({ + name, + type + }); } 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(']'); + this.kernelConstants.push({ + name, + type: this.constantTypes[name] + }); } - } else if (yProperty) { - if (isInput) { - retArr.push('[('); - this.astGeneric(yProperty, retArr); - retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`); - this.astGeneric(xProperty, retArr); - retArr.push(']'); + this.constantBitRatios[name] = this.getBitRatio(this.constants[name]); + } + } + } + setOptimizeFloatMemory(flag) { + this.optimizeFloatMemory = flag; + return this; + } + setOutput(output) { + if (output.hasOwnProperty('x')) { + if (output.hasOwnProperty('y')) { + if (output.hasOwnProperty('z')) { + this.output = [output.x, output.y, output.z]; } else { - retArr.push('['); - this.astGeneric(yProperty, retArr); - retArr.push(']'); - retArr.push('['); - this.astGeneric(xProperty, retArr); - retArr.push(']'); + this.output = [output.x, output.y]; } - } else if (typeof xProperty !== 'undefined') { - retArr.push('['); - this.astGeneric(xProperty, retArr); - retArr.push(']'); + } else { + this.output = [output.x]; } + } else { + this.output = output; + } + return this; } - return retArr; - } - - astCallExpression(ast, retArr) { - if (ast.type !== 'CallExpression') { - throw this.astErrorOutput('Unknown CallExpression', ast); + setDebug(flag) { + this.debug = flag; + return this; } - let functionName = this.astMemberExpressionUnroll(ast.callee); - - if (this.calledFunctions.indexOf(functionName) < 0) { - this.calledFunctions.push(functionName); + setGraphical(flag) { + this.graphical = flag; + this.precision = 'unsigned'; + return this; } - - const isMathFunction = this.isAstMathFunction(ast); - - if (this.onFunctionCall) { - this.onFunctionCall(this.name, functionName, ast.arguments); + setLoopMaxIterations(max) { + this.loopMaxIterations = max; + return this; } - - 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); + setConstants(constants) { + this.constants = constants; + return this; + } + setConstantTypes(constantTypes) { + this.constantTypes = constantTypes; + return this; + } + setFunctions(functions) { + if (typeof functions[0] === 'function') { + this.functions = functions.map(source => functionToIFunction(source)); + } else { + this.functions = functions; } - - if (i > 0) { - retArr.push(', '); + return this; + } + setNativeFunctions(nativeFunctions) { + this.nativeFunctions = nativeFunctions; + return this; + } + setInjectedNative(injectedNative) { + this.injectedNative = injectedNative; + return this; + } + setPipeline(flag) { + this.pipeline = flag; + return this; + } + setPrecision(flag) { + this.precision = flag; + return this; + } + setOutputToTexture(flag) { + 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) { + 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) { + this.warnVarUsage = flag; + return this; + } + getCanvas() { + warnDeprecated('method', 'getCanvas'); + return this.canvas; + } + getWebGl() { + 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) { + const argumentIndex = this.argumentNames.indexOf(p); + if (argumentIndex === -1) throw new Error(`unable to find argument ${ p }`); + this.argumentTypes[argumentIndex] = argumentTypes[p]; + } } - this.astGeneric(argument, retArr); + return this; } - retArr.push(')'); - - return retArr; - } - - astArrayExpression(arrNode, retArr) { - const arrLen = arrNode.elements.length; - - retArr.push('new Float32Array(['); - for (let i = 0; i < arrLen; ++i) { - if (i > 0) { - retArr.push(', '); + setTactic(tactic) { + this.tactic = tactic; + return this; + } + requestFallback(args) { + if (!this.onRequestFallback) { + throw new Error(`"onRequestFallback" not defined on ${ this.constructor.name }`); } - const subNode = arrNode.elements[i]; - this.astGeneric(subNode, retArr) + this.fallbackRequested = true; + return this.onRequestFallback(args); } - retArr.push('])'); - - 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)': - results.push(`${name}:new ${constant.constructor.name}(${JSON.stringify(Array.from(constant))})`); - break; + validateSettings() { + throw new Error(`"validateSettings" not defined on ${ this.constructor.name }`); } - } - 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; + addSubKernel(subKernel) { + if (this.subKernels === null) { + this.subKernels = []; } - }); - - 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'; + 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() { + throw new Error(`"getPixels" called on ${ this.constructor.name }`); + } + checkOutput() { + if (!this.output || !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`); } - return JSON.stringify(cpuKernel[propertyName]); - }, - findDependency: () => { - return null; } - }); - - thisProperties.push( - ' _imageData,', - ' _colorData,', - ` color: ${colorFn},`, - ); - - beforeReturn.push( - ` kernel.getPixels = ${getPixelsFn};` - ); + } + toJSON() { + const settings = { + output: this.output, + threadDim: this.threadDim, + 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, + }; + return { + settings + }; + } } - 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'; + 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, + warnVarUsage, + } = 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 triggerTrackArgumentSynonym = (functionName, argumentName, calleeFunctionName, argumentIndex) => { + functionBuilder.trackArgumentSynonym(functionName, argumentName, calleeFunctionName, argumentIndex); + }; + const lookupArgumentSynonym = (originFunctionName, functionName, argumentName) => { + return functionBuilder.lookupArgumentSynonym(originFunctionName, functionName, argumentName); + }; + const onFunctionCall = (functionName, calleeFunctionName, args) => { + functionBuilder.trackFunctionCall(functionName, calleeFunctionName, args); + }; + const onNestedFunction = (ast, returnType) => { + const argumentNames = []; + for (let i = 0; i < ast.params.length; i++) { + argumentNames.push(ast.params[i].name); } + const nestedFunction = new FunctionNode(null, Object.assign({}, nodeOptions, { + returnType: null, + ast, + name: ast.id.name, + argumentNames, + lookupReturnType, + lookupFunctionArgumentTypes, + lookupFunctionArgumentName, + lookupFunctionArgumentBitRatio, + needsArgumentType, + assignArgumentType, + triggerImplyArgumentType, + triggerTrackArgumentSynonym, + lookupArgumentSynonym, + onFunctionCall, + warnVarUsage, + })); + nestedFunction.traceFunctionAST(ast); + functionBuilder.addFunctionNode(nestedFunction); + }; + const nodeOptions = Object.assign({ + isRootKernel: false, + onNestedFunction, + lookupReturnType, + lookupFunctionArgumentTypes, + lookupFunctionArgumentName, + lookupFunctionArgumentBitRatio, + needsArgumentType, + assignArgumentType, + triggerImplyArgumentType, + triggerTrackArgumentSynonym, + lookupArgumentSynonym, + 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, + triggerTrackArgumentSynonym, + lookupArgumentSynonym, + onFunctionCall, + })); } - }); - 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'); + 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, + })); + }); } - }); - 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)': - 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":112}],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() { - return null; - } - - static combineKernels(combinedKernel) { - return combinedKernel; - } - - constructor(source, settings) { - super(source, settings); - this.mergeSettings(source.settings || settings); - - this._imageData = null; - this._colorData = null; - this._kernelString = null; - 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); + const functionBuilder = new FunctionBuilder({ + kernel, + rootNode, + functionNodes, + nativeFunctions, + subKernelNodes + }); + return functionBuilder; } - } - - 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'); + 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.argumentChain = []; + this.functionNodeDependencies = {}; + this.functionCalls = {}; + if (this.rootNode) { + this.functionMap['kernel'] = this.rootNode; } - - 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.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); + } } } - - if (this.graphical) { - if (this.output.length !== 2) { - throw new Error('Output must have 2 dimensions on graphical mode'); + addFunctionNode(functionNode) { + if (!functionNode.name) throw new Error('functionNode.name needs set'); + this.functionMap[functionNode.name] = functionNode; + if (functionNode.isRootKernel) { + this.rootNode = functionNode; } } - - 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`); + traceFunctionCalls(functionName, retList) { + functionName = functionName || 'kernel'; + retList = retList || []; + if (this.nativeFunctionNames.indexOf(functionName) > -1) { + if (retList.indexOf(functionName) === -1) { + retList.push(functionName); + } + return retList; } - this.followingReturnStatement = followingReturnStatement.join(''); + 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; } - const functionBuilder = FunctionBuilder.fromKernel(this, CPUFunctionNode); - this.translatedSources = functionBuilder.getPrototypes('kernel'); - if (!this.graphical && !this.returnType) { - this.returnType = functionBuilder.getKernelResultType(); + getPrototypeString(functionName) { + return this.getPrototypes(functionName).join('\n'); } - } - - build() { - 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'); + getPrototypes(functionName) { + if (this.rootNode) { + this.rootNode.toString(); } - 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); + if (functionName) { + return this.getPrototypesFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse()); + } + return this.getPrototypesFromFunctionNames(Object.keys(this.functionMap)); } - - const kernelString = this.getKernelString(); - this.kernelString = kernelString; - - if (this.debug) { - console.log('Function output:'); - console.log(kernelString); + 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'); } - - try { - this.run = new Function([], kernelString).bind(this)(); - } catch (e) { - console.error('An error occurred compiling the javascript: ', e); + 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; } - } - - color(r, g, b, a) { - if (typeof a === 'undefined') { - a = 1; + 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`); + } + }); } - - 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._processConstants() } - return (${ this.argumentNames.map(argumentName => 'user_' + argumentName).join(', ') }) => { - ${ 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 'HTMLImage': - 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`); + 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; } - return result.join(''); - } - - _processArguments() { - const result = []; - for (let i = 0; i < this.argumentTypes.length; i++) { - const variableName = `user_${this.argumentNames[i]}`; - switch (this.argumentTypes[i]) { - case 'HTMLImage': - 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}); + getString(functionName) { + if (functionName) { + return this.getStringFromFunctionNames(this.traceFunctionCalls(functionName).reverse()); } - }`); - break; + 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; } - 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; - ctx.drawImage(media, 0, 0, width, height); - const 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; + _getFunction(functionName) { + if (!this._isFunction(functionName)) ; + 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; } - 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]); + _isNativeFunction(functionName) { + return Boolean(this._getNativeFunction(functionName)); } - return imagesArray; - } - - _resultKernelBody(kernelString) { - switch (this.output.length) { - case 1: - return this._resultKernel1DLoop(kernelString) + this._kernelOutput(); - case 2: - return this._resultKernel2DLoop(kernelString) + this._kernelOutput(); - case 3: - return this._resultKernel3DLoop(kernelString) + this._kernelOutput(); - default: - throw new Error('unsupported size kernel'); + _lookupNativeFunctionReturnType(functionName) { + let nativeFunction = this._getNativeFunction(functionName); + if (nativeFunction) { + return nativeFunction.returnType; + } + throw new Error(`Native function ${ functionName } not found`); } - } - - _graphicalKernelBody(kernelThreadString) { - switch (this.output.length) { - case 2: - return this._graphicalKernel2DLoop(kernelThreadString) + this._graphicalOutput(); - default: - throw new Error('unsupported size kernel'); + lookupFunctionArgumentTypes(functionName) { + if (this._isNativeFunction(functionName)) { + return this._getNativeFunction(functionName).argumentTypes; + } else if (this._isFunction(functionName)) { + return this._getFunction(functionName).argumentTypes; + } + return null; } - } - - _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'; + 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]; + } else { + throw new Error('argument bit ratio not found'); } - throw new Error(`unhandled returnType ${ this.returnType }`); + } else { + const node = this._getFunction(functionName); + const argumentSynonym = node.argumentSynonym[node.synonymIndex]; + if (!argumentSynonym) { + throw new Error('argument synonym not found'); + } + return this.lookupFunctionArgumentBitRatio(argumentSynonym.functionName, argumentSynonym.argumentName); + } + } + 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; + } + } + trackArgumentSynonym(functionName, argumentName, calleeFunctionName, argumentIndex) { + if (!this._isFunction(calleeFunctionName)) return; + const node = this._getFunction(calleeFunctionName); + if (!node.argumentSynonym) { + node.argumentSynonym = {}; + } + const calleeArgumentName = node.argumentNames[argumentIndex]; + if (!node.argumentSynonym[calleeArgumentName]) { + node.argumentSynonym[calleeArgumentName] = {}; + } + node.synonymIndex++; + node.argumentSynonym[node.synonymIndex] = { + functionName, + argumentName, + calleeArgumentName, + calleeFunctionName, + }; } - } - - _resultKernel1DLoop(kernelString) { - const { - output - } = this; - 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 } - }`; - } - - _resultKernel2DLoop(kernelString) { - const { - output - } = this; - 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 } + lookupArgumentSynonym(originFunctionName, functionName, argumentName) { + if (originFunctionName === functionName) return argumentName; + if (!this._isFunction(functionName)) return null; + const node = this._getFunction(functionName); + const argumentSynonym = node.argumentSynonym[node.synonymUseIndex]; + if (!argumentSynonym) return null; + if (argumentSynonym.calleeArgumentName !== argumentName) return null; + node.synonymUseIndex++; + if (originFunctionName !== functionName) { + return this.lookupArgumentSynonym(originFunctionName, argumentSynonym.functionName, argumentSynonym.argumentName); } - }`; - } - - _graphicalKernel2DLoop(kernelString) { - const { - output - } = this; - const constructorString = this._getKernelResultTypeConstructorString(); - return ` const outputX = _this.output[0]; - const outputY = _this.output[1]; - ${ 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; - ${ 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 } + return argumentSynonym.argumentName; + } + trackFunctionCall(functionName, calleeFunctionName, args) { + if (!this.functionNodeDependencies[functionName]) { + this.functionNodeDependencies[functionName] = new Set(); + this.functionCalls[functionName] = []; } - }`; - } - - _resultKernel3DLoop(kernelString) { - const { - output - } = this; - 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 } + 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; } } - }`; - } - - _kernelOutput() { - if (!this.subKernels) { - return '\n return result;'; + if (!called) { + throw new Error(`SubKernel ${ subKernelNode.name } never called by kernel`); + } + return subKernelNode.returnType || subKernelNode.getType(subKernelNode.getJsAST()); } - 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; + 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; } } - 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); + class FunctionTracer { + constructor(ast) { + this.runningContexts = []; + this.contexts = []; + this.functionCalls = []; + this.declarations = []; + this.identifiers = []; + this.functions = []; + this.returnStatements = []; + this.inLoopInit = false; + this.scan(ast); } - } -} - -module.exports = { - CPUKernel -}; -},{"../../utils":112,"../function-builder":9,"../kernel":35,"./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, - warnVarUsage, - } = kernel; - - const argumentTypes = new Array(kernelArguments.length); - const constantTypes = {}; - - for (let i = 0; i < kernelArguments.length; i++) { - argumentTypes[i] = kernelArguments[i].type; + get currentContext() { + return this.runningContexts.length > 0 ? this.runningContexts[this.runningContexts.length - 1] : null; } - - for (let i = 0; i < kernelConstants.length; i++) { - const kernelConstant = kernelConstants[i]; - constantTypes[kernelConstant.name] = kernelConstant.type; + newContext(run) { + const newContext = Object.assign({}, this.currentContext); + this.contexts.push(newContext); + this.runningContexts.push(newContext); + run(); + this.runningContexts.pop(); } - - 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, returnType) => { - const argumentNames = []; - for (let i = 0; i < ast.params.length; i++) { - argumentNames.push(ast.params[i].name); + scan(ast) { + if (Array.isArray(ast)) { + for (let i = 0; i < ast.length; i++) { + this.scan(ast[i]); + } + return; + } + switch (ast.type) { + case 'Program': + 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': + case 'UnaryExpression': + this.scan(ast.argument); + break; + case 'VariableDeclaration': + this.scan(ast.declarations); + break; + case 'VariableDeclarator': + const { currentContext } = this; + const declaration = { + ast: ast, + context: currentContext, + name: ast.id.name, + origin: 'declaration', + forceInteger: this.inLoopInit, + assignable: !this.inLoopInit && !currentContext.hasOwnProperty(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': + this.newContext(() => { + this.inLoopInit = true; + this.scan(ast.init); + this.inLoopInit = false; + this.scan(ast.test); + this.scan(ast.update); + this.newContext(() => { + this.scan(ast.body); + }); + }); + break; + case 'DoWhileStatement': + case 'WhileStatement': + this.newContext(() => { + this.scan(ast.body); + this.scan(ast.test); + }); + break; + case 'Identifier': + this.identifiers.push({ + context: this.currentContext, + ast, + }); + break; + case 'ReturnStatement': + this.returnStatements.push(ast); + this.scan(ast.argument); + break; + case 'MemberExpression': + this.scan(ast.object); + this.scan(ast.property); + break; + case 'ExpressionStatement': + this.scan(ast.expression); + 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': + this.scan(ast.left); + this.scan(ast.right); + break; + case 'Literal': + case 'DebuggerStatement': + case 'EmptyStatement': + case 'BreakStatement': + case 'ContinueStatement': + break; + default: + throw new Error(`unhandled type "${ast.type}"`); } - const nestedFunction = new FunctionNode(null, Object.assign({}, nodeOptions, { - returnType: null, - ast, - name: ast.id.name, - argumentNames, - lookupReturnType, - lookupFunctionArgumentTypes, - lookupFunctionArgumentName, - lookupFunctionArgumentBitRatio, - needsArgumentType, - assignArgumentType, - triggerImplyArgumentType, - triggerImplyArgumentBitRatio, - onFunctionCall, - warnVarUsage, - })); - 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.argumentChain = []; - 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]; + class FunctionNode { + constructor(source, settings) { + if (!source && !settings.ast) { + throw new Error('source parameter is missing'); } - } - - if (this.subKernelNodes) { - for (let i = 0; i < this.subKernelNodes.length; i++) { - this.functionMap[this.subKernelNodes[i].name] = this.subKernelNodes[i]; + settings = settings || {}; + this.source = source; + this.ast = null; + this.name = typeof source === 'string' ? settings.isRootKernel ? + 'kernel' : + (settings.name || getFunctionNameFromString(source)) : null; + this.calledFunctions = []; + this.constants = {}; + this.constantTypes = {}; + this.constantBitRatios = {}; + this.isRootKernel = false; + this.isSubKernel = false; + this.debug = null; + this.declarations = 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' ? 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; + this.warnVarUsage = true; + 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 = {}; } - - if (this.nativeFunctions) { - for (let i = 0; i < this.nativeFunctions.length; i++) { - const nativeFunction = this.nativeFunctions[i]; - this.nativeFunctionNames.push(nativeFunction.name); + validate() { + if (typeof this.source !== 'string' && !this.ast) { + throw new Error('this.source not a string'); + } + if (!this.ast && !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'); } } - } - - addFunctionNode(functionNode) { - if (!functionNode.name) throw new Error('functionNode.name needs set'); - this.functionMap[functionNode.name] = functionNode; - if (functionNode.isRootKernel) { - this.rootNode = functionNode; + isIdentifierConstant(name) { + if (!this.constants) return false; + return this.constants.hasOwnProperty(name); } - } - - traceFunctionCalls(functionName, retList) { - functionName = functionName || 'kernel'; - retList = retList || []; - - if (this.nativeFunctionNames.indexOf(functionName) > -1) { - if (retList.indexOf(functionName) === -1) { - retList.push(functionName); - } - return retList; + isInput(argumentName) { + return this.argumentTypes[this.argumentNames.indexOf(argumentName)] === 'Input'; } - - 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); + 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(); } - - return retList; - } - - getPrototypeString(functionName) { - return this.getPrototypes(functionName).join('\n'); - } - - getPrototypes(functionName) { - if (this.rootNode) { - this.rootNode.toString(); + isState(state) { + return this.state === state; } - if (functionName) { - return this.getPrototypesFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse()); + get state() { + return this.states[this.states.length - 1]; } - 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()); + astMemberExpressionUnroll(ast) { + if (ast.type === 'Identifier') { + return ast.name; + } else if (ast.type === 'ThisExpression') { + return 'this'; } - } - 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; + if (ast.type === 'MemberExpression') { + if (ast.object && ast.property) { + if (ast.object.hasOwnProperty('name') && ast.object.name[0] === '_') { + return this.astMemberExpressionUnroll(ast.property); + } + return ( + this.astMemberExpressionUnroll(ast.object) + + '.' + + this.astMemberExpressionUnroll(ast.property) + ); + } } - const node = this.functionMap[functionName]; - if (node) { - ret.push(node.toString()); + 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); } - 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`); + getJsAST(inParser) { + if (this.ast) { + return this.ast; } - }); - } - - 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()); + if (typeof this.source === 'object') { + this.traceFunctionAST(this.source); + return this.ast = this.source; + } + const parser = inParser && inParser.hasOwnProperty('parse') ? inParser.parse : parse; + if (inParser === null) { + throw new Error('Missing JS to AST parser'); + } + const ast = Object.freeze(parser(`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.declarations = []; + this.functions = functions; + for (let i = 0; i < declarations.length; i++) { + const declaration = declarations[i]; + const { ast, context, name, origin, forceInteger, assignable } = declaration; + const { init } = ast; + const dependencies = this.getDependencies(init); + let valueType = null; + if (forceInteger) { + 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; } - - throw new Error('circlical logic detected!'); } } - this.lookupChain.push({ - name: requestingNode.name, + this.declarations.push({ + valueType, + dependencies, + isSafe: this.isSafeDependencies(dependencies), ast, - requestingNode + name, + context, + origin, + assignable, }); - 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.declarations = 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; - this.warnVarUsage = true; - - if (settings) { - for (const p in settings) { - if (!settings.hasOwnProperty(p)) continue; - if (!this.hasOwnProperty(p)) continue; - this[p] = settings[p]; + for (let i = 0; i < functions.length; i++) { + this.onNestedFunction(functions[i]); } } - - 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[0] === '_') { - return this.astMemberExpressionUnroll(ast.property); + getDeclaration(ast) { + for (let i = 0; i < this.identifiers.length; i++) { + const identifier = this.identifiers[i]; + if (ast === identifier.ast && identifier.context.hasOwnProperty(ast.name)) { + for (let j = 0; j < this.declarations.length; j++) { + const declaration = this.declarations[j]; + if (declaration.name === ast.name && declaration.context[ast.name] === identifier.context[ast.name]) { + return declaration; + } + } } - - return ( - this.astMemberExpressionUnroll(ast.object) + - '.' + - this.astMemberExpressionUnroll(ast.property) - ); } + return null; } - - 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]); + getVariableType(ast) { + if (ast.type !== 'Identifier') { + throw new Error(`ast of ${ast.type} not "Identifier"`); } - } - - 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.declarations = []; - this.functions = functions; - for (let i = 0; i < declarations.length; i++) { - const declaration = declarations[i]; - const { ast, context, name, origin, forceInteger, assignable } = declaration; - const { init } = ast; - const dependencies = this.getDependencies(init); - let valueType = null; - - if (forceInteger) { - valueType = 'Integer'; + let type = null; + const argumentIndex = this.argumentNames.indexOf(ast.name); + if (argumentIndex === -1) { + const declaration = this.getDeclaration(ast); + if (declaration) { + return declaration.valueType; + } } 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; - } + const argumentType = this.argumentTypes[argumentIndex]; + if (argumentType) { + type = argumentType; } } - this.declarations.push({ - valueType, - dependencies, - isSafe: this.isSafeDependencies(dependencies), - ast, - name, - context, - origin, - assignable, - }); - } - - for (let i = 0; i < functions.length; i++) { - this.onNestedFunction(functions[i]); - } - } - - getDeclaration(ast) { - for (let i = 0; i < this.identifiers.length; i++) { - const identifier = this.identifiers[i]; - if (ast === identifier.ast && identifier.context.hasOwnProperty(ast.name)) { - for (let j = 0; j < this.declarations.length; j++) { - const declaration = this.declarations[j]; - if (declaration.name === ast.name && declaration.context[ast.name] === identifier.context[ast.name]) { - return declaration; - } - } + if (!type && this.strictTypingChecking) { + throw new Error(`Declaration of ${name} not found`); } + return type; } - 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; + getLookupType(type) { + if (!typeLookupMap.hasOwnProperty(type)) { + throw new Error(`unknown typeLookupMap ${ type }`); } - } else { - const argumentType = this.argumentTypes[argumentIndex]; - if (argumentType) { - type = argumentType; + 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`); } - if (!type && this.strictTypingChecking) { - throw new Error(`Declaration of ${name} not found`); + toString() { + if (this._string) return this._string; + return this._string = this.astGeneric(this.getJsAST(), []).join('').trim(); } - return type; - } - - getLookupType(type) { - if (!typeLookupMap.hasOwnProperty(type)) { - throw new Error(`unknown typeLookupMap ${ type }`); + 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 + }; } - return typeLookupMap[type]; - } - - getConstantType(constantName) { - if (this.constantTypes[constantName]) { - const type = this.constantTypes[constantName]; - if (type === 'Float') { - return 'Number'; - } else { - return type; + getType(ast) { + if (Array.isArray(ast)) { + return this.getType(ast[ast.length - 1]); } - } - 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': - return `Array(${ ast.elements.length })`; - case 'Literal': - const literalKey = `${ast.start},${ast.end}`; - 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)) { + switch (ast.type) { + case 'BlockStatement': + return this.getType(ast.body); + case 'ArrayExpression': + return `Array(${ ast.elements.length })`; + case 'Literal': + const literalKey = `${ast.start},${ast.end}`; + 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'; } - 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; + 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); + } + 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('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 'BinaryExpression': - switch (ast.operator) { - case '%': - case '/': - if (this.fixIntegerDivisionAccuracy) { - return 'Number'; - } else { - break; + throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast); + 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'; + } } - case '>': - case '<': - return 'Boolean'; - case '&': - case '|': - case '^': - case '<<': - case '>>': - case '>>>': - return 'Integer'; + 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; } - 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'; + 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') { + const type = this.getVariableType(ast); + if (!type) { + throw this.astErrorOutput(`Unable to find identifier valueType`, ast); + } + return type; } } - 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') { - const type = this.getVariableType(ast); - if (!type) { - throw this.astErrorOutput(`Unable to find identifier valueType`, ast); - } - return type; + const origin = this.findIdentifierOrigin(ast); + if (origin && origin.init) { + return this.getType(origin.init); } - } - 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 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'; } - return 'Number'; - } - if (this.isAstVariable(ast)) { - const variableSignature = this.getVariableSignature(ast); - switch (variableSignature) { - case 'value[]': - return this.getLookupType(this.getVariableType(ast.object)); - case 'value[][]': - return this.getLookupType(this.getVariableType(ast.object.object)); - case 'value[][][]': - return this.getLookupType(this.getVariableType(ast.object.object.object)); - case 'value[][][][]': - return this.getLookupType(this.getVariableType(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()[]': - return this.getLookupType(this.getType(ast.object)); - case 'fn()[][]': - return this.getLookupType(this.getType(ast.object)); - case 'fn()[][][]': - return this.getLookupType(this.getType(ast.object)); - case 'value.value': - if (this.isAstMathVariable(ast)) { - return 'Number'; - } - switch (ast.property.name) { - case 'r': - return this.getLookupType(this.getVariableType(ast.object)); - case 'g': - return this.getLookupType(this.getVariableType(ast.object)); - case 'b': - return this.getLookupType(this.getVariableType(ast.object)); - case 'a': - return this.getLookupType(this.getVariableType(ast.object)); - } - case '[][]': - return 'Number'; + if (this.isAstVariable(ast)) { + const variableSignature = this.getVariableSignature(ast); + switch (variableSignature) { + case 'value[]': + return this.getLookupType(this.getVariableType(ast.object)); + case 'value[][]': + return this.getLookupType(this.getVariableType(ast.object.object)); + case 'value[][][]': + return this.getLookupType(this.getVariableType(ast.object.object.object)); + case 'value[][][][]': + return this.getLookupType(this.getVariableType(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()[]': + return this.getLookupType(this.getType(ast.object)); + case 'fn()[][]': + return this.getLookupType(this.getType(ast.object)); + case 'fn()[][][]': + return this.getLookupType(this.getType(ast.object)); + case 'value.value': + if (this.isAstMathVariable(ast)) { + return 'Number'; + } + switch (ast.property.name) { + case 'r': + return this.getLookupType(this.getVariableType(ast.object)); + case 'g': + return this.getLookupType(this.getVariableType(ast.object)); + case 'b': + return this.getLookupType(this.getVariableType(ast.object)); + case 'a': + return this.getLookupType(this.getVariableType(ast.object)); + } + case '[][]': + return 'Number'; + } + throw this.astErrorOutput('Unhandled getType MemberExpression', ast); } 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); - default: - throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast); - } - } - - 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', - 'asin', - 'atan', - 'atan2', - 'ceil', - 'cos', - 'exp', - 'floor', - 'log', - 'log2', - 'max', - 'min', - 'pow', - 'random', - 'round', - 'sign', - 'sin', - 'sqrt', - 'tan', - ]; - 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); + 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); + default: + throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast); } - 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); + 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', + 'asin', + 'atan', + 'atan2', + 'ceil', + 'cos', + 'exp', + 'floor', + 'log', + 'log2', + 'max', + 'min', + 'pow', + 'random', + 'round', + 'sign', + 'sin', + 'sqrt', + 'tan', + ]; + 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; - 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) { + } + 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': + 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({ - name: ast.name, origin: 'declaration', - isSafe: isNotSafe ? false : this.isSafeDependencies(declaration.dependencies), + isSafe: true, }); - } else if (this.argumentNames.indexOf(ast.name) > -1) { + return dependencies; + case 'CallExpression': dependencies.push({ - name: ast.name, - origin: 'argument', - isSafe: false, + origin: 'function', + isSafe: true, }); - } 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': - 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); + 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.xProperty) { - this.getDependencies(details.xProperty, dependencies, isNotSafe); + 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; } - if (details.yProperty) { - this.getDependencies(details.yProperty, dependencies, isNotSafe); + default: + throw this.astErrorOutput(`Unhandled type ${ ast.type } in getDependencies`, ast); + } + return dependencies; + } + getVariableSignature(ast) { + 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('.value'); + } else if ( + ast.property.name === 'constants' || + ast.property.name === 'thread' || + ast.property.name === 'output' + ) { + signature.unshift('.' + ast.property.name); + } else { + signature.unshift('.value'); } - if (details.zProperty) { - this.getDependencies(details.zProperty, dependencies, isNotSafe); + } else if (ast.name) { + signature.unshift('value'); + } else if (ast.callee && ast.callee.name) { + signature.unshift('fn()'); + } else if (ast.elements) { + signature.unshift('[]'); + } else { + signature.unshift('unknown'); + } + ast = ast.object; + } + const signatureString = signature.join(''); + 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 dependencies; + return retArr; } - default: - throw this.astErrorOutput(`Unhandled type ${ ast.type } in getDependencies`, ast); + 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); + } } - return dependencies; - } - - getVariableSignature(ast) { - 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('.value'); - } else if ( - ast.property.name === 'constants' || - ast.property.name === 'thread' || - ast.property.name === 'output' - ) { - signature.unshift('.' + ast.property.name); - } else { - signature.unshift('.value'); - } - } else if (ast.name) { - signature.unshift('value'); - } else if (ast.callee && ast.callee.name) { - signature.unshift('fn()'); - } else if (ast.elements) { - signature.unshift('[]'); - } else { - signature.unshift('unknown'); + astErrorOutput(error, ast) { + if (typeof this.source !== 'string') { + return new Error(error); } - ast = ast.object; + const debugString = 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 }`); } - - const signatureString = signature.join(''); - 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; + astDebuggerStatement(arrNode, retArr) { + return retArr; } - 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); - } + 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; } - - 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); + return this.astFunction(ast, retArr); + } + astFunctionExpression(ast, retArr) { + if (this.isChildFunction(ast)) { + return retArr; } - - throw this.astErrorOutput('Unknown ast type : ' + ast.type, ast); + return this.astFunction(ast, retArr); } - } - astErrorOutput(error, ast) { - if (typeof this.source !== 'string') { - return new Error(error); + isChildFunction(ast) { + for (let i = 0; i < this.functions.length; i++) { + if (this.functions[i] === ast) { + return true; + } + } + return false; } - - 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)) { + astReturnStatement(ast, retArr) { return retArr; } - return this.astFunction(ast, retArr); - } - astFunctionExpression(ast, retArr) { - if (this.isChildFunction(ast)) { + astLiteral(ast, retArr) { + this.literalTypes[`${ast.start},${ast.end}`] = 'Number'; 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; - } + astBinaryExpression(ast, retArr) { + return retArr; } - return false; - } - astReturnStatement(ast, retArr) { - return retArr; - } - astLiteral(ast, retArr) { - this.literalTypes[`${ast.start},${ast.end}`] = '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; - } - astVariableDeclaration(varDecNode, retArr) { - const declarations = varDecNode.declarations; - if (!declarations || !declarations[0] || !declarations[0].init) { - throw this.astErrorOutput('Unexpected expression', varDecNode); + astIdentifierExpression(ast, retArr) { + return retArr; } - const result = []; - const firstDeclaration = declarations[0]; - const init = firstDeclaration.init; - let type = this.isState('in-for-loop-init') ? 'Integer' : this.getType(init); - if (type === 'LiteralInteger') { - type = 'Number'; - } - const markupType = typeMap[type]; - if (!markupType) { - throw this.astErrorOutput(`Markup type ${ markupType } not handled`, varDecNode); - } - let dependencies = this.getDependencies(firstDeclaration.init); - throw new Error('remove me'); - this.declarations[firstDeclaration.id.name] = Object.freeze({ - type, - dependencies, - isSafe: dependencies.every(dependency => dependency.isSafe) - }); - const initResult = [`${type} user_${firstDeclaration.id.name}=`]; - this.astGeneric(init, initResult); - result.push(initResult.join('')); - - for (let i = 1; i < declarations.length; i++) { - const declaration = declarations[i]; - dependencies = this.getDependencies(declaration); - throw new Error('Remove me'); - this.declarations[declaration.id.name] = Object.freeze({ - type, - dependencies, - isSafe: false - }); - this.astGeneric(declaration, result); + astAssignmentExpression(ast, retArr) { + return retArr; } - - retArr.push(retArr, result.join(',')); - retArr.push(';'); - return retArr; - } - astVariableDeclarator(iVarDecNode, retArr) { - this.astGeneric(iVarDecNode.id, retArr); - if (iVarDecNode.init !== null) { - retArr.push('='); - this.astGeneric(iVarDecNode.init, retArr); + astExpressionStatement(esNode, retArr) { + this.astGeneric(esNode.expression, retArr); + retArr.push(';'); + return retArr; } - return retArr; - } - astThisExpression(ast, retArr) { - return retArr; - } - astSequenceExpression(sNode, retArr) { - for (let i = 0; i < sNode.expressions.length; i++) { - if (i > 0) { - retArr.push(','); - } - this.astGeneric(sNode.expressions, retArr); + astEmptyStatement(eNode, retArr) { + return retArr; } - return retArr; - } - astUnaryExpression(uNode, retArr) { - const unaryResult = this.checkAndUpconvertBitwiseUnary(uNode, retArr); - if (unaryResult) { + astBlockStatement(ast, retArr) { return retArr; } - - if (uNode.prefix) { - retArr.push(uNode.operator); - this.astGeneric(uNode.argument, retArr); - } else { - this.astGeneric(uNode.argument, retArr); - retArr.push(uNode.operator); + astIfStatement(ast, retArr) { + return retArr; } - - 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); + astSwitchStatement(ast, retArr) { + return retArr; } - - 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); + 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; + } + astVariableDeclaration(varDecNode, retArr) { + const declarations = varDecNode.declarations; + if (!declarations || !declarations[0] || !declarations[0].init) { + throw this.astErrorOutput('Unexpected expression', varDecNode); + } + const result = []; + const firstDeclaration = declarations[0]; + const init = firstDeclaration.init; + let type = this.isState('in-for-loop-init') ? 'Integer' : this.getType(init); + if (type === 'LiteralInteger') { + type = 'Number'; + } + const markupType = typeMap[type]; + if (!markupType) { + throw this.astErrorOutput(`Markup type ${ markupType } not handled`, varDecNode); + } + let dependencies = this.getDependencies(firstDeclaration.init); + throw new Error('remove me'); + this.declarations[firstDeclaration.id.name] = Object.freeze({ + type, + dependencies, + isSafe: dependencies.every(dependency => dependency.isSafe) + }); + const initResult = [`${type} user_${firstDeclaration.id.name}=`]; + this.astGeneric(init, initResult); + result.push(initResult.join('')); + for (let i = 1; i < declarations.length; i++) { + const declaration = declarations[i]; + dependencies = this.getDependencies(declaration); + throw new Error('Remove me'); + this.declarations[declaration.id.name] = Object.freeze({ + type, + dependencies, + isSafe: false + }); + this.astGeneric(declaration, result); + } + retArr.push(retArr, result.join(',')); + retArr.push(';'); + 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) { + for (let i = 0; i < sNode.expressions.length; i++) { + if (i > 0) { + retArr.push(','); } - if (this.isAstMathVariable(ast)) { - name = ast.property.name; + this.astGeneric(sNode.expressions, retArr); + } + 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 { - name, - origin: 'Math', - type: 'Number', signature: variableSignature, + type: 'Integer', + name: ast.property.name }; - } - 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') { + case 'value[]': + if (typeof ast.object.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); - } + name = ast.object.name; return { name, - type, - origin: 'constants', + origin: 'user', signature: variableSignature, + type: this.getVariableType(ast.object), + xProperty: ast.property }; - case 'this.constants.value[]': - if (typeof ast.object.property.name !== 'string') { + case 'value[][]': + if (typeof ast.object.object.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); - } + name = ast.object.object.name; return { name, - type, - origin: 'constants', + origin: 'user', signature: variableSignature, + type: this.getVariableType(ast.object.object), + yProperty: ast.object.property, xProperty: ast.property, }; - case 'this.constants.value[][]': { - if (typeof ast.object.object.property.name !== 'string') { + case 'value[][][]': + if (typeof ast.object.object.object.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); - } + name = ast.object.object.object.name; return { name, - type, - origin: 'constants', - signature: variableSignature, - yProperty: ast.object.property, - xProperty: ast.property, + origin: 'user', + signature: variableSignature, + type: this.getVariableType(ast.object.object.object), + zProperty: ast.object.object.property, + yProperty: ast.object.property, + xProperty: ast.property, }; - } - case 'this.constants.value[][][]': { - if (typeof ast.object.object.object.property.name !== 'string') { + case 'value[][][][]': + if (typeof ast.object.object.object.object.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); - } + name = ast.object.object.object.object.name; return { name, - type, - origin: 'constants', - signature: variableSignature, - zProperty: ast.object.object.property, - yProperty: ast.object.property, - xProperty: ast.property, - }; - } - case 'fn()[]': - case '[][]': - return { - signature: variableSignature, - property: ast.property, + origin: 'user', + signature: variableSignature, + type: this.getVariableType(ast.object.object.object.object), + zProperty: ast.object.object.property, + yProperty: ast.object.property, + xProperty: 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; + 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 '[][]': + return { + signature: variableSignature, + property: ast.property, + }; + default: + throw this.astErrorOutput('Unexpected expression', ast); } - 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]); + } + 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; } - 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); + 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; } - 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]; - } - - varWarn() { - console.warn('var declarations are deprecated, weird things happen when falling back to CPU because var scope differs in javascript than in most languages. Use const or let'); - } -} - -const typeLookupMap = { - 'Number': 'Number', - 'Float': 'Float', - 'Integer': 'Integer', - 'Array': 'Number', - 'Array(2)': 'Number', - 'Array(3)': 'Number', - 'Array(4)': 'Number', - 'Array2D': 'Number', - 'Array3D': 'Number', - 'Input': 'Number', - 'HTMLImage': '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":112,"./function-tracer":11,"acorn":1}],11:[function(require,module,exports){ -class FunctionTracer { - constructor(ast) { - this.runningContexts = []; - this.contexts = []; - this.functionCalls = []; - this.declarations = []; - this.identifiers = []; - this.functions = []; - this.returnStatements = []; - this.inLoopInit = false; - this.scan(ast); - } - - get currentContext() { - return this.runningContexts.length > 0 ? this.runningContexts[this.runningContexts.length - 1] : null; - } - - newContext(run) { - const newContext = Object.assign({}, this.currentContext); - this.contexts.push(newContext); - this.runningContexts.push(newContext); - run(); - this.runningContexts.pop(); - } - - 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.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': - case 'UnaryExpression': - this.scan(ast.argument); - break; - case 'VariableDeclaration': - this.scan(ast.declarations); - break; - case 'VariableDeclarator': - const { currentContext } = this; - const declaration = { - ast: ast, - context: currentContext, - name: ast.id.name, - origin: 'declaration', - forceInteger: this.inLoopInit, - assignable: !this.inLoopInit && !currentContext.hasOwnProperty(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': - this.newContext(() => { - this.inLoopInit = true; - this.scan(ast.init); - this.inLoopInit = false; - this.scan(ast.test); - this.scan(ast.update); - this.newContext(() => { - this.scan(ast.body); - }); - }); - break; - case 'DoWhileStatement': - case 'WhileStatement': - this.newContext(() => { - this.scan(ast.body); - this.scan(ast.test); - }); - break; - case 'Identifier': - this.identifiers.push({ - context: this.currentContext, - ast, - }); - break; - case 'ReturnStatement': - this.returnStatements.push(ast); - this.scan(ast.argument); - break; - case 'MemberExpression': - this.scan(ast.object); - this.scan(ast.property); - break; - case 'ExpressionStatement': - this.scan(ast.expression); - 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, -}; -},{}],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.*/'); -} + 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]; + } + varWarn() { + console.warn('var declarations are deprecated, weird things happen when falling back to CPU because var scope differs in javascript than in most languages. Use const or let'); + } + } + const typeLookupMap = { + 'Number': 'Number', + 'Float': 'Float', + 'Integer': 'Integer', + 'Array': 'Number', + 'Array(2)': 'Number', + 'Array(3)': 'Number', + 'Array(4)': 'Number', + 'Array2D': 'Number', + 'Array3D': 'Number', + 'Input': 'Number', + 'HTMLImage': '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)', + }; -function glKernelString(Kernel, args, originKernel, setupContextString, destroyContextString) { - 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;'); + 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); } - return; + retArr.push(') {\n'); } - if (targetName) { - postResult.push(` return ${getRenderString(targetName, kernel)};`); - } else { - postResult.push(` return null;`); + for (let i = 0; i < ast.body.body.length; ++i) { + this.astGeneric(ast.body.body[i], retArr); + retArr.push('\n'); } - }, - onUnrecognizedArgumentLookup: (argument) => { - const argumentName = findKernelValue(argument, kernel.kernelArguments, [], context, uploadedValues); - if (argumentName) { - return argumentName; + if (!this.isRootKernel) { + retArr.push('}\n'); } - const constantName = findKernelValue(argument, kernel.kernelConstants, constants ? Object.keys(constants).map(key => constants[key]) : [], context, uploadedValues); - if (constantName) { - return constantName; + return retArr; + } + astReturnStatement(ast, retArr) { + const type = this.returnType || this.getType(ast.argument); + if (!this.returnType) { + this.returnType = type; } - return null; + 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; } - }); - 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, - } = originKernel; - const kernel = new Kernel(source, { - canvas, - context, - checkContext: false, - output, - pipeline, - graphical, - loopMaxIterations, - constants, - optimizeFloatMemory, - precision, - fixIntegerDivisionAccuracy, - functions, - nativeFunctions, - subKernels, - immutable, - argumentTypes, - constantTypes, - }); - 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 '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}`); + astLiteral(ast, retArr) { + if (isNaN(ast.value)) { + throw this.astErrorOutput( + 'Non-numeric literal not supported : ' + ast.value, + ast + ); + } + retArr.push(ast.value); + return retArr; } - }); - 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 results = kernel.renderKernels(); - const textureName = context.getContextVariableName(kernel.outputTexture); - result.push(` return { - result: { - texture: ${ textureName }, - type: '${ results.result.type }', - toArray: ${ getToArrayString(results.result, textureName) } - },`); - const { subKernels, subKernelOutputTextures } = kernel; - for (let i = 0; i < subKernels.length; i++) { - const texture = subKernelOutputTextures[i]; - const subKernel = subKernels[i]; - const subKernelResult = results[subKernel.property]; - const subKernelTextureName = context.getContextVariableName(texture); - result.push(` - ${subKernel.property}: { - texture: ${ subKernelTextureName }, - type: '${ subKernelResult.type }', - toArray: ${ getToArrayString(subKernelResult, subKernelTextureName) } - },`); + astBinaryExpression(ast, retArr) { + retArr.push('('); + this.astGeneric(ast.left, retArr); + retArr.push(ast.operator); + this.astGeneric(ast.right, retArr); + retArr.push(')'); + return retArr; } - result.push(` };`); - } - 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; + astIdentifierExpression(idtNode, retArr) { + if (idtNode.type !== 'Identifier') { + throw this.astErrorOutput( + 'IdentifierExpression - not an Identifier', + idtNode + ); } - if (kernel.hasOwnProperty(property)) { - return JSON.stringify(kernel[property]); + 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); + } } - throw new Error(`unhandled thisLookup ${ property }`); + return retArr; } - }); -} - -function getToArrayString(kernelResult, textureName) { - 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') { - return `${useFunctionKeyword ? 'function ' : ''}${kernelResult[name].toString()}`; + 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 { - throw new Error('unhandled fromObject'); + isSafe = false; } - }, - thisLookup: (property) => { - if (property === 'texture') { - return textureName; + if (forNode.test) { + this.astGeneric(forNode.test, testArr); + } else { + isSafe = false; } - if (kernelResult.hasOwnProperty(property)) { - return JSON.stringify(kernelResult[property]); + if (forNode.update) { + this.astGeneric(forNode.update, updateArr); + } else { + isSafe = false; } - throw new Error(`unhandled thisLookup ${ property }`); - } - }); - return `() => { - ${flattenedFunctions} - return toArray(); - }`; -} - -function findKernelValue(argument, kernelValues, values, context, uploadedValues) { - if (argument === 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') 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; - } - return null; - } - - 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":112,"gl-wiretap":3}],13:[function(require,module,exports){ -const { Kernel } = require('../kernel'); -const { Texture } = require('../../texture'); -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 get testCanvas() { - throw new Error(`"testCanvas" not defined on ${ this.name }`); - } - - static get testContext() { - throw new Error(`"testContext" not defined on ${ this.name }`); - } - - static get features() { - throw new Error(`"features" not defined on ${ this.name }`); - } - - static setupFeatureChecks() { - throw new Error(`"setupFeatureChecks" not defined on ${ this.name }`); - } - - 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; + if (forNode.body) { + this.pushState('loop-body'); + this.astGeneric(forNode.body, bodyArr); + this.popState('loop-body'); } - - else if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '/') { - states.push('COMMENT'); - i += 2; - continue; - } else if (state === 'COMMENT' && char === '\n') { - states.pop(); - i++; - continue; + if (isSafe === null) { + isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test); } - - else if (state === null && char === '(') { - states.push('FUNCTION_ARGUMENTS'); - i++; - continue; - } else if (state === 'FUNCTION_ARGUMENTS') { - if (char === ')') { - states.pop(); - break; + 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'); } - 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; + 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'); } - - 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]); - } + return retArr; + } + astWhileStatement(whileNode, retArr) { + if (whileNode.type !== 'WhileStatement') { + throw this.astErrorOutput( + 'Invalid while statement', + whileNode + ); } - - i++; + 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; } - if (states.length > 0) { - throw new Error('GLSL function was not parsable'); + 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; } - 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); + astAssignmentExpression(assNode, retArr) { + const declaration = this.getDeclaration(assNode.left); + if (declaration && !declaration.assignable) { + throw new 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; } - - 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]); - }); + 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; } - } - - 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.renderStrategy = null; - this.compiledFragmentShader = null; - this.compiledVertexShader = 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}]`); + astVariableDeclaration(varDecNode, retArr) { + if (varDecNode.kind === 'var' && this.warnVarUsage) { + this.varWarn(); + } + retArr.push(`${varDecNode.kind} `); + const { declarations } = varDecNode; + for (let i = 0; i < declarations.length; i++) { + if (i > 0) { + retArr.push(','); + } + this.astGeneric(declarations[i], retArr); + } + if (!this.isState('in-for-loop-init')) { + retArr.push(';'); + } + return retArr; } - } - - 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; + 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') { + this.astGeneric(ifNode.alternate, retArr); + } else { + retArr.push(' {\n'); + this.astGeneric(ifNode.alternate, retArr); + retArr.push('\n}\n'); + } + } + return retArr; } - 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; + 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; } - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': + 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; + default: + throw this.astErrorOutput('Unexpected expression', mNode); + } + if (!mNode.computed) { + switch (type) { case 'Number': case 'Integer': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureUnsigned3D; - this.renderStrategy = renderStrategy.PackedPixelTo3DFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureUnsigned2D; - this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; - return null; + 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 '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 { - this.TextureConstructor = GLTextureUnsigned; - this.renderStrategy = renderStrategy.PackedPixelToFloat; - return null; + retArr.push('['); + this.astGeneric(zProperty, retArr); + retArr.push(']'); + retArr.push('['); + this.astGeneric(yProperty, retArr); + retArr.push(']'); + retArr.push('['); + this.astGeneric(xProperty, retArr); + retArr.push(']'); } - break; - 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.renderStrategy = renderStrategy.PackedPixelTo3DFloat; - this.formatValues = utils.erect3DPackedFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureUnsigned2D; - this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; - this.formatValues = utils.erect2DPackedFloat; - return null; + } 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 { - this.TextureConstructor = GLTextureUnsigned; - this.renderStrategy = renderStrategy.PackedPixelToFloat; - this.formatValues = utils.erectPackedFloat; - return null; + retArr.push('['); + this.astGeneric(yProperty, retArr); + retArr.push(']'); + retArr.push('['); + this.astGeneric(xProperty, retArr); + retArr.push(']'); } - - break; - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - return this.requestFallback(args); - } + } else if (typeof xProperty !== 'undefined') { + retArr.push('['); + this.astGeneric(xProperty, retArr); + retArr.push(']'); + } } - } else if (this.precision === 'single') { - this.renderRawOutput = this.readFloatPixelsToFloat32Array; - this.transferValues = this.readFloatPixelsToFloat32Array; - if (this.pipeline) { - this.renderStrategy = renderStrategy.FloatTexture; - 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; - } - } - break; - 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; - } - break; - 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; - } - break; - 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; - } - } + return retArr; + } + astCallExpression(ast, retArr) { + if (ast.type !== 'CallExpression') { + throw this.astErrorOutput('Unknown CallExpression', ast); } - this.renderOutput = this.renderValues; - if (this.subKernels !== null) { - this.renderKernels = this.renderKernelsToArrays; + let functionName = this.astMemberExpressionUnroll(ast.callee); + if (this.calledFunctions.indexOf(functionName) < 0) { + this.calledFunctions.push(functionName); } - if (this.optimizeFloatMemory) { - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureMemoryOptimized3D; - this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized3DFloat; - this.formatValues = utils.erectMemoryOptimized3DFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureMemoryOptimized2D; - this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized2DFloat; - this.formatValues = utils.erectMemoryOptimized2DFloat; - return null; - } else { - this.TextureConstructor = GLTextureMemoryOptimized; - this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimizedFloat; - this.formatValues = utils.erectMemoryOptimizedFloat; - return null; - } - break; - case 'Array(2)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray2Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; - this.formatValues = utils.erect3DArray2; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray2Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; - this.formatValues = utils.erect2DArray2; - return null; - } else { - this.TextureConstructor = GLTextureArray2Float; - this.renderStrategy = renderStrategy.FloatPixelToArray2; - this.formatValues = utils.erectArray2; - return null; - } - break; - case 'Array(3)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray3Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; - this.formatValues = utils.erect3DArray3; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray3Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; - this.formatValues = utils.erect2DArray3; - return null; - } else { - this.TextureConstructor = GLTextureArray3Float; - this.renderStrategy = renderStrategy.FloatPixelToArray3; - this.formatValues = utils.erectArray3; - return null; - } - break; - case 'Array(4)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray4Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; - this.formatValues = utils.erect3DArray4; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray4Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; - this.formatValues = utils.erect2DArray4; - return null; - } else { - this.TextureConstructor = GLTextureArray4Float; - this.renderStrategy = renderStrategy.FloatPixelToArray4; - this.formatValues = utils.erectArray4; - return null; - } + 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); } - } else { - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureFloat3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DFloat; - this.formatValues = utils.erect3DFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureFloat2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DFloat; - this.formatValues = utils.erect2DFloat; - return null; - } else { - this.TextureConstructor = GLTextureFloat; - this.renderStrategy = renderStrategy.FloatPixelToFloat; - this.formatValues = utils.erectFloat; - return null; - } - break; - case 'Array(2)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray2Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; - this.formatValues = utils.erect3DArray2; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray2Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; - this.formatValues = utils.erect2DArray2; - return null; - } else { - this.TextureConstructor = GLTextureArray2Float; - this.renderStrategy = renderStrategy.FloatPixelToArray2; - this.formatValues = utils.erectArray2; - return null; - } - break; - case 'Array(3)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray3Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; - this.formatValues = utils.erect3DArray3; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray3Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; - this.formatValues = utils.erect2DArray3; - return null; - } else { - this.TextureConstructor = GLTextureArray3Float; - this.renderStrategy = renderStrategy.FloatPixelToArray3; - this.formatValues = utils.erectArray3; - return null; - } - break; - case 'Array(4)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray4Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; - this.formatValues = utils.erect3DArray4; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray4Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; - this.formatValues = utils.erect2DArray4; - return null; - } else { - this.TextureConstructor = GLTextureArray4Float; - this.renderStrategy = renderStrategy.FloatPixelToArray4; - this.formatValues = utils.erectArray4; - return null; - } + if (i > 0) { + retArr.push(', '); } + this.astGeneric(argument, retArr); } - } else { - throw new Error(`unhandled precision of "${this.precision}"`); + retArr.push(')'); + return retArr; } - - 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 }`); + astArrayExpression(arrNode, retArr) { + 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); + } + retArr.push('])'); + return retArr; } - } - - 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(); + astDebuggerStatement(arrNode, retArr) { + retArr.push('debugger;'); + return retArr; } } - 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() { - switch (this.tactic) { - case 'speed': - return 'precision lowp float;\n'; - case 'performance': - return 'precision highp float;\n'; - case 'balanced': - default: - return 'precision mediump float;\n'; + 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)': + results.push(`${name}:new ${constant.constructor.name}(${JSON.stringify(Array.from(constant))})`); + break; + } } + return `{ ${ results.join() } }`; } - - getIntTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp int;\n'; - case 'performance': - return 'precision highp int;\n'; - case 'balanced': - default: - return 'precision mediump int;\n'; + 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$1.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$1.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$1.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$1.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)': + 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; +}`; } - getSampler2DTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp sampler2D;\n'; - case 'performance': - return 'precision highp sampler2D;\n'; - case 'balanced': - default: - return 'precision mediump sampler2D;\n'; + class CPUKernel extends Kernel { + static getFeatures() { + return this.features; } - } - - getSampler2DArrayTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp sampler2DArray;\n'; - case 'performance': - return 'precision highp sampler2DArray;\n'; - case 'balanced': - default: - return 'precision mediump sampler2DArray;\n'; + static get features() { + return Object.freeze({ + kernelMap: true, + isIntegerDivisionAccurate: true + }); } - } - - renderTexture() { - return new this.TextureConstructor({ - texture: this.outputTexture, - size: this.texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }); - } - 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; - } - - readMemoryOptimizedFloatPixelsToFloat32Array() { - 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] = new this.TextureConstructor({ - texture: this.subKernelOutputTextures[i], - size: this.texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }).toArray(); + static get isSupported() { + return true; } - return result; - } - - renderKernelsToTextures() { - const result = { - result: this.renderOutput(), - }; - for (let i = 0; i < this.subKernels.length; i++) { - result[this.subKernels[i].property] = new this.TextureConstructor({ - texture: this.subKernelOutputTextures[i], - size: this.texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }); + static isContextMatch(context) { + return false; } - return result; - } - - setOutput(output) { - super.setOutput(output); - if (this.program) { - this.threadDim = [this.output[0], this.output[1] || 1, this.output[2] || 1]; - this.texSize = utils.getKernelTextureSize({ - optimizeFloatMemory: this.optimizeFloatMemory, - precision: this.precision, - }, this.output); - const { context: gl } = this; - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - this.updateMaxTexSize(); - this.framebuffer.width = this.texSize[0]; - this.framebuffer.height = this.texSize[1]; - this.context.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); - this.canvas.width = this.maxTexSize[0]; - this.canvas.height = this.maxTexSize[1]; - this._setupOutputTexture(); - if (this.subKernels && this.subKernels.length > 0) { - this._setupSubOutputTextures(); + static get mode() { + return 'cpu'; + } + static nativeFunctionArguments() { + return null; + } + static nativeFunctionReturnType() { + return null; + } + static combineKernels(combinedKernel) { + return combinedKernel; + } + constructor(source, settings) { + super(source, settings); + this.mergeSettings(source.settings || settings); + this._imageData = null; + this._colorData = null; + this._kernelString = null; + 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); } } - return this; - } - renderValues() { - return this.formatValues( - this.transferValues(), - this.output[0], - this.output[1], - this.output[2] - ); - } -} - -const renderStrategy = Object.freeze({ - PackedPixelToUint8Array: Symbol('PackedPixelToUint8Array'), - PackedPixelToFloat: Symbol('PackedPixelToFloat'), - PackedPixelTo2DFloat: Symbol('PackedPixelTo2DFloat'), - PackedPixelTo3DFloat: Symbol('PackedPixelTo3DFloat'), - PackedTexture: Symbol('PackedTexture'), - FloatPixelToFloat32Array: Symbol('FloatPixelToFloat32Array'), - FloatPixelToFloat: Symbol('FloatPixelToFloat'), - FloatPixelTo2DFloat: Symbol('FloatPixelTo2DFloat'), - FloatPixelTo3DFloat: Symbol('FloatPixelTo3DFloat'), - FloatPixelToArray2: Symbol('FloatPixelToArray2'), - FloatPixelTo2DArray2: Symbol('FloatPixelTo2DArray2'), - FloatPixelTo3DArray2: Symbol('FloatPixelTo3DArray2'), - FloatPixelToArray3: Symbol('FloatPixelToArray3'), - FloatPixelTo2DArray3: Symbol('FloatPixelTo2DArray3'), - FloatPixelTo3DArray3: Symbol('FloatPixelTo3DArray3'), - FloatPixelToArray4: Symbol('FloatPixelToArray4'), - FloatPixelTo2DArray4: Symbol('FloatPixelTo2DArray4'), - FloatPixelTo3DArray4: Symbol('FloatPixelTo3DArray4'), - FloatTexture: Symbol('FloatTexture'), - MemoryOptimizedFloatPixelToMemoryOptimizedFloat: Symbol('MemoryOptimizedFloatPixelToFloat'), - MemoryOptimizedFloatPixelToMemoryOptimized2DFloat: Symbol('MemoryOptimizedFloatPixelTo2DFloat'), - MemoryOptimizedFloatPixelToMemoryOptimized3DFloat: Symbol('MemoryOptimizedFloatPixelTo3DFloat'), -}); - -const typeMap = { - int: 'Integer', - float: 'Number', - vec2: 'Array(2)', - vec3: 'Array(3)', - vec4: 'Array(4)', -}; - -module.exports = { - GLKernel, - renderStrategy -}; -},{"../../texture":111,"../../utils":112,"../kernel":35,"./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":29,"./texture/memory-optimized-2d":27,"./texture/memory-optimized-3d":28,"./texture/unsigned":32,"./texture/unsigned-2d":30,"./texture/unsigned-3d":31}],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":112,"./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":112,"./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":112,"./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":112,"./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":112,"./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":112,"./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":112,"./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":112,"./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":112,"./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":112,"./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":112,"./float":25}],25:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { Texture } = require('../../../texture'); - -class GLTextureFloat extends Texture { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(1)'; - } - renderRawOutput() { - const { context: gl } = this; - const framebuffer = gl.createFramebuffer(); - gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); - gl.framebufferTexture2D( - gl.FRAMEBUFFER, - gl.COLOR_ATTACHMENT0, - gl.TEXTURE_2D, - this.texture, - 0 - ); - const result = new Float32Array(this.size[0] * this.size[1] * 4); - gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.FLOAT, result); - return result; - } - renderValues() { - return this.renderRawOutput(); - } - toArray() { - return utils.erectFloat(this.renderValues(), this.output[0]); - } -} - -module.exports = { - GLTextureFloat -}; -},{"../../../texture":111,"../../../utils":112}],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":32}],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":112,"./float":25}],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":112,"./float":25}],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":112,"./float":25}],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":112,"./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":112,"./unsigned":32}],32:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { Texture } = require('../../../texture'); - -class GLTextureUnsigned extends Texture { - constructor(settings) { - super(settings); - this.type = 'NumberTexture'; - } - renderRawOutput() { - const { context: gl } = this; - const framebuffer = gl.createFramebuffer(); - gl.bindFramebuffer(gl.FRAMEBUFFER, 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() { - return new Float32Array(this.renderRawOutput().buffer); - } - toArray() { - return utils.erectPackedFloat(this.renderValues(), this.output[0]); - } -} - -module.exports = { - GLTextureUnsigned -}; -},{"../../../texture":111,"../../../utils":112}],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'), - }; - features = this.getFeatures(); - } catch (e) { - console.warn(e); + initContext() { + if (!this.canvas) return null; + return this.canvas.getContext('2d'); } - } - - static isContextMatch(context) { - try { - return context.getParameter(context.RENDERER) === 'ANGLE'; - } catch (e) { - return false; + 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$1.getVariableType(args[0], this.strictIntegers); + if (argType === 'Array') { + this.output = utils$1.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() { + 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); + } + } + 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._processConstants() } + return (${ this.argumentNames.map(argumentName => 'user_' + argumentName).join(', ') }) => { + ${ 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 'HTMLImage': + 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(''); + } + _processArguments() { + const result = []; + for (let i = 0; i < this.argumentTypes.length; i++) { + const variableName = `user_${this.argumentNames[i]}`; + switch (this.argumentTypes[i]) { + case 'HTMLImage': + 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; + ctx.drawImage(media, 0, 0, width, height); + const 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$1.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; + } + _resultKernelBody(kernelString) { + switch (this.output.length) { + case 1: + return this._resultKernel1DLoop(kernelString) + this._kernelOutput(); + case 2: + return this._resultKernel2DLoop(kernelString) + this._kernelOutput(); + case 3: + return this._resultKernel3DLoop(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 }`); + } + } + _resultKernel1DLoop(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 } + }`; + } + _resultKernel2DLoop(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 } + } + }`; + } + _graphicalKernel2DLoop(kernelString) { + const constructorString = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const outputY = _this.output[1]; + ${ 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; + ${ 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 } + } + }`; + } + _resultKernel3DLoop(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 } + } + } + }`; + } + _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); + } } } - static getFeatures() { - const isDrawBuffers = this.getIsDrawBuffers(); - return Object.freeze({ - isFloatRead: this.getIsFloatRead(), - isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), - isTextureFloat: this.getIsTextureFloat(), - isDrawBuffers, - kernelMap: isDrawBuffers, - channelCount: this.getChannelCount(), - maxTextureSize: this.getMaxTextureSize(), - }); - } - - 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; + class GLTextureFloat extends Texture { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(1)'; + } + renderRawOutput() { + const { context: gl } = this; + const framebuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_2D, + this.texture, + 0 + ); + const result = new Float32Array(this.size[0] * this.size[1] * 4); + gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.FLOAT, result); + return result; + } + renderValues() { + return this.renderRawOutput(); + } + toArray() { + return utils$1.erectFloat(this.renderValues(), this.output[0]); + } } - initCanvas() { - return {}; + class GLTextureArray2Float extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(2)'; + } + toArray() { + return utils$1.erectArray2(this.renderValues(), this.output[0], this.output[1]); + } } - initContext() { - const context = getContext(2, 2, { - preserveDrawingBuffer: true - }); - return context; + class GLTextureArray2Float2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(2)'; + } + toArray() { + return utils$1.erect2DArray2(this.renderValues(), this.output[0], this.output[1]); + } } - 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'), - }; + class GLTextureArray2Float3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(2)'; + } + toArray() { + return utils$1.erect3DArray2(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } } - build() { - super.build.apply(this, arguments); - if (!this.fallbackRequested) { - this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0], this.maxTexSize[1]); + class GLTextureArray3Float extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(3)'; + } + toArray() { + return utils$1.erectArray3(this.renderValues(), this.output[0]); } } - 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; + class GLTextureArray3Float2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(3)'; + } + toArray() { + return utils$1.erect2DArray3(this.renderValues(), this.output[0], this.output[1]); + } } - static destroyContext(context) { - const extension = context.getExtension('STACKGL_destroy_context'); - if (extension && extension.destroy) { - extension.destroy(); + class GLTextureArray3Float3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(3)'; + } + toArray() { + return utils$1.erect3DArray3(this.renderValues(), this.output[0], this.output[1], this.output[2]); } } - 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); + class GLTextureArray4Float extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return utils$1.erectArray4(this.renderValues(), this.output[0]); + } } - 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]); + class GLTextureArray4Float2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return utils$1.erect2DArray4(this.renderValues(), this.output[0], this.output[1]); } } -} -module.exports = { - HeadlessGLKernel -}; -},{"../gl/kernel-string":12,"../web-gl/kernel":68,"gl":2}],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'); + class GLTextureArray4Float3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return utils$1.erect3DArray4(this.renderValues(), this.output[0], this.output[1], this.output[2]); } - if (!type) { - throw new Error('type not set'); - } - if (!origin) { - throw new Error('origin not set'); - } - if (!tactic) { - throw new Error('tactic 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.id = `${this.origin}_${name}`; - 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; } - getSource() { - throw new Error(`"getSource" not defined on ${ this.constructor.name }`); + class GLTextureFloat2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(1)'; + } + toArray() { + return utils$1.erect2DFloat(this.renderValues(), this.output[0], this.output[1]); + } } - updateValue(value) { - throw new Error(`"updateValue" not defined on ${ this.constructor.name }`); + class GLTextureFloat3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(1)'; + } + toArray() { + return utils$1.erect3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } } -} - -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 }`); + class GLTextureMemoryOptimized extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'MemoryOptimizedNumberTexture'; + } + toArray() { + return utils$1.erectMemoryOptimizedFloat(this.renderValues(), this.output[0]); + } } - static isContextMatch(context) { - throw new Error(`"isContextMatch" not implemented on ${ this.name }`); + class GLTextureMemoryOptimized2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'MemoryOptimizedNumberTexture'; + } + toArray() { + return utils$1.erectMemoryOptimized2DFloat(this.renderValues(), this.output[0], this.output[1]); + } } - static getFeatures() { - throw new Error(`"getFeatures" not implemented on ${ this.name }`); + class GLTextureMemoryOptimized3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'MemoryOptimizedNumberTexture'; + } + toArray() { + return utils$1.erectMemoryOptimized3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } } - static destroyContext(context) { - throw new Error(`"destroyContext" called on ${ this.name }`); + class GLTextureUnsigned extends Texture { + constructor(settings) { + super(settings); + this.type = 'NumberTexture'; + } + renderRawOutput() { + const { context: gl } = this; + const framebuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, 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() { + return new Float32Array(this.renderRawOutput().buffer); + } + toArray() { + return utils$1.erectPackedFloat(this.renderValues(), this.output[0]); + } } - static nativeFunctionArguments() { - throw new Error(`"nativeFunctionArguments" called on ${ this.name }`); + class GLTextureUnsigned2D extends GLTextureUnsigned { + constructor(settings) { + super(settings); + this.type = 'NumberTexture'; + } + toArray() { + return utils$1.erect2DPackedFloat(this.renderValues(), this.output[0], this.output[1]); + } } - static nativeFunctionReturnType() { - throw new Error(`"nativeFunctionReturnType" called on ${ this.name }`); + class GLTextureUnsigned3D extends GLTextureUnsigned { + constructor(settings) { + super(settings); + this.type = 'NumberTexture'; + } + toArray() { + return utils$1.erect3DPackedFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } } - static combineKernels() { - throw new Error(`"combineKernels" called on ${ this.name }`); + class GLTextureGraphical extends GLTextureUnsigned { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return this.renderValues(); + } } - 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'); - } + class GLKernel extends Kernel { + static get mode() { + return 'gpu'; } - 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 = 'balanced'; - - this.plugins = null; - - this.returnType = null; - this.leadingReturnStatement = null; - this.followingReturnStatement = null; - this.optimizeFloatMemory = null; - this.strictIntegers = false; - this.fixIntegerDivisionAccuracy = null; - this.warnVarUsage = true; - } - - 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; + 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 get testCanvas() { + throw new Error(`"testCanvas" not defined on ${ this.name }`); + } + static get testContext() { + throw new Error(`"testContext" not defined on ${ this.name }`); + } + static get features() { + throw new Error(`"features" not defined on ${ this.name }`); + } + static setupFeatureChecks() { + throw new Error(`"setupFeatureChecks" not defined on ${ this.name }`); + } + setFixIntegerDivisionAccuracy(fix) { + this.fixIntegerDivisionAccuracy = fix; + return this; + } + setPrecision(flag) { + this.precision = flag; + return this; + } + setFloatTextures(flag) { + utils$1.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; } - break; - case 'functions': - if (typeof settings.functions[0] === 'function') { - this.functions = settings.functions.map(source => utils.functionToIFunction(source)); + 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; } - break; - case 'graphical': - if (settings[p] && !settings.hasOwnProperty('precision')) { - this.precision = 'unsigned'; + } + 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$1[argumentType]); } - this[p] = settings[p]; - 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 }`); - } - - 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 - }); } + i++; } - } else { - for (let i = 0; i < this.argumentTypes.length; i++) { - this.kernelArguments.push({ - type: this.argumentTypes[i] - }); + if (states.length > 0) { + throw new Error('GLSL function was not parsable'); } + return { + argumentNames, + argumentTypes, + }; } - - 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]); - } + static nativeFunctionReturnType(source) { + return typeMap$1[source.match(/int|float|vec[2-4]/)[0]]; } - } - - setOptimizeFloatMemory(flag) { - this.optimizeFloatMemory = flag; - return this; - } - - 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]; - } + 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 { - this.output = [output.x]; + 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); } - } else { - this.output = 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) { - if (typeof functions[0] === 'function') { - this.functions = functions.map(source => utils.functionToIFunction(source)); - } else { - this.functions = functions; - } - return this; - } - - setNativeFunctions(nativeFunctions) { - this.nativeFunctions = nativeFunctions; - return this; - } - - setInjectedNative(injectedNative) { - this.injectedNative = injectedNative; - return this; - } - - setPipeline(flag) { - this.pipeline = flag; - return this; - } - - setPrecision(flag) { - this.precision = 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) { - this.warnVarUsage = flag; - 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) { - const argumentIndex = this.argumentNames.indexOf(p); - if (argumentIndex === -1) throw new Error(`unable to find argument ${ p }`); - this.argumentTypes[argumentIndex] = argumentTypes[p]; + 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$1.splitArray(result, lastKernel.output[0]); + } else if (lastKernel.output.length === 3) { + const cube = utils$1.splitArray(result, lastKernel.output[0] * lastKernel.output[1]); + return cube.map(function(x) { + return utils$1.splitArray(x, lastKernel.output[0]); + }); } } - 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() { - 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`); + 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.renderStrategy = null; + this.compiledFragmentShader = null; + this.compiledVertexShader = 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; } - } - } - - toJSON() { - const settings = { - output: this.output, - threadDim: this.threadDim, - 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, - }; - return { - settings - }; - } -} - -module.exports = { - Kernel -}; -},{"../input":108,"../utils":112}],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; - -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); -} - -__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'); -const jsMathPrefix = 'Math.'; -const localPrefix = 'this.'; - -class WebGLFunctionNode extends FunctionNode { - constructor(source, settings) { - super(source, settings); - if (settings && settings.hasOwnProperty('fixIntegerDivisionAccuracy')) { - this.fixIntegerDivisionAccuracy = settings.fixIntegerDivisionAccuracy; - } - } - - astFunction(ast, retArr) { - if (this.isRootKernel) { - retArr.push('void'); - } else { - let lastReturn = null; - if (!this.returnType) { - const lastReturn = this.findLastReturn(); - if (lastReturn) { - this.returnType = this.getType(ast.body); - if (this.returnType === 'LiteralInteger') { - this.returnType = 'Number'; + 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; + this.renderStrategy = renderStrategy.PackedPixelTo3DFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureUnsigned2D; + this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; + return null; + } else { + this.TextureConstructor = GLTextureUnsigned; + this.renderStrategy = renderStrategy.PackedPixelToFloat; + return null; + } + break; + 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.renderStrategy = renderStrategy.PackedPixelTo3DFloat; + this.formatValues = utils$1.erect3DPackedFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureUnsigned2D; + this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; + this.formatValues = utils$1.erect2DPackedFloat; + return null; + } else { + this.TextureConstructor = GLTextureUnsigned; + this.renderStrategy = renderStrategy.PackedPixelToFloat; + this.formatValues = utils$1.erectPackedFloat; + return null; + } + break; + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + return this.requestFallback(args); } } - } - - 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'; + } else if (this.precision === 'single') { + this.renderRawOutput = this.readFloatPixelsToFloat32Array; + this.transferValues = this.readFloatPixelsToFloat32Array; + if (this.pipeline) { + this.renderStrategy = renderStrategy.FloatTexture; + 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; + } + } + break; + 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; + } + break; + 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; + } + break; + 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; + } + } } - const type = typeMap[argumentType]; - if (!type) { - throw this.astErrorOutput('Unexpected expression', ast); + this.renderOutput = this.renderValues; + if (this.subKernels !== null) { + this.renderKernels = this.renderKernelsToArrays; } - - if (type === 'sampler2D' || type === 'sampler2DArray') { - retArr.push(`${type} user_${argumentName},ivec2 user_${argumentName}Size,ivec3 user_${argumentName}Dim`); + if (this.optimizeFloatMemory) { + switch (this.returnType) { + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureMemoryOptimized3D; + this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized3DFloat; + this.formatValues = utils$1.erectMemoryOptimized3DFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureMemoryOptimized2D; + this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized2DFloat; + this.formatValues = utils$1.erectMemoryOptimized2DFloat; + return null; + } else { + this.TextureConstructor = GLTextureMemoryOptimized; + this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimizedFloat; + this.formatValues = utils$1.erectMemoryOptimizedFloat; + return null; + } + break; + case 'Array(2)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray2Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; + this.formatValues = utils$1.erect3DArray2; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray2Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; + this.formatValues = utils$1.erect2DArray2; + return null; + } else { + this.TextureConstructor = GLTextureArray2Float; + this.renderStrategy = renderStrategy.FloatPixelToArray2; + this.formatValues = utils$1.erectArray2; + return null; + } + break; + case 'Array(3)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray3Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; + this.formatValues = utils$1.erect3DArray3; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray3Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; + this.formatValues = utils$1.erect2DArray3; + return null; + } else { + this.TextureConstructor = GLTextureArray3Float; + this.renderStrategy = renderStrategy.FloatPixelToArray3; + this.formatValues = utils$1.erectArray3; + return null; + } + break; + case 'Array(4)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray4Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; + this.formatValues = utils$1.erect3DArray4; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray4Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; + this.formatValues = utils$1.erect2DArray4; + return null; + } else { + this.TextureConstructor = GLTextureArray4Float; + this.renderStrategy = renderStrategy.FloatPixelToArray4; + this.formatValues = utils$1.erectArray4; + return null; + } + } } else { - retArr.push(`${type} user_${argumentName}`); + switch (this.returnType) { + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureFloat3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DFloat; + this.formatValues = utils$1.erect3DFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureFloat2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DFloat; + this.formatValues = utils$1.erect2DFloat; + return null; + } else { + this.TextureConstructor = GLTextureFloat; + this.renderStrategy = renderStrategy.FloatPixelToFloat; + this.formatValues = utils$1.erectFloat; + return null; + } + break; + case 'Array(2)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray2Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; + this.formatValues = utils$1.erect3DArray2; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray2Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; + this.formatValues = utils$1.erect2DArray2; + return null; + } else { + this.TextureConstructor = GLTextureArray2Float; + this.renderStrategy = renderStrategy.FloatPixelToArray2; + this.formatValues = utils$1.erectArray2; + return null; + } + break; + case 'Array(3)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray3Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; + this.formatValues = utils$1.erect3DArray3; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray3Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; + this.formatValues = utils$1.erect2DArray3; + return null; + } else { + this.TextureConstructor = GLTextureArray3Float; + this.renderStrategy = renderStrategy.FloatPixelToArray3; + this.formatValues = utils$1.erectArray3; + return null; + } + break; + case 'Array(4)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray4Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; + this.formatValues = utils$1.erect3DArray4; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray4Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; + this.formatValues = utils$1.erect2DArray4; + return null; + } else { + this.TextureConstructor = GLTextureArray4Float; + this.renderStrategy = renderStrategy.FloatPixelToArray4; + this.formatValues = utils$1.erectArray4; + return null; + } + } } + } else { + throw new Error(`unhandled precision of "${this.precision}"`); } + throw new Error(`unhandled return type "${this.returnType}"`); } - - retArr.push(') {\n'); - - for (let i = 0; i < ast.body.body.length; ++i) { - this.astGeneric(ast.body.body[i], retArr); - retArr.push('\n'); + getKernelString() { + throw new Error(`abstract method call`); } - - 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; + 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 }`); } } - - 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 'Input': - this.astGeneric(ast.argument, result); - break; - default: - throw this.astErrorOutput(`unhandled return type ${this.returnType}`, ast); + getMainResultKernelNumberTexture() { + throw new Error(`abstract method call`); } - - 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('') };`); + getMainResultSubKernelNumberTexture() { + throw new Error(`abstract method call`); } - return retArr; - } - - astLiteral(ast, retArr) { - if (isNaN(ast.value)) { - throw this.astErrorOutput( - 'Non-numeric literal not supported : ' + ast.value, - ast - ); + getMainResultKernelArray2Texture() { + throw new Error(`abstract method call`); } - - const key = `${ast.start},${ast.end}`; - if (Number.isInteger(ast.value)) { - if (this.isState('in-for-loop-init') || 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`); + 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 { - this.literalTypes[key] = 'Number'; - retArr.push(`${ast.value}.0`); + return this.getMainResultPackedPixels(); } - } 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; + getMainResultNumberTexture() { + return utils$1.linesToString(this.getMainResultKernelNumberTexture()) + + utils$1.linesToString(this.getMainResultSubKernelNumberTexture()); } - - if (this.fixIntegerDivisionAccuracy && ast.operator === '/') { - retArr.push('div_with_int_check('); - 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; + getMainResultArray2Texture() { + return utils$1.linesToString(this.getMainResultKernelArray2Texture()) + + utils$1.linesToString(this.getMainResultSubKernelArray2Texture()); + } + getMainResultArray3Texture() { + return utils$1.linesToString(this.getMainResultKernelArray3Texture()) + + utils$1.linesToString(this.getMainResultSubKernelArray3Texture()); + } + getMainResultArray4Texture() { + return utils$1.linesToString(this.getMainResultKernelArray4Texture()) + + utils$1.linesToString(this.getMainResultSubKernelArray4Texture()); + } + getFloatTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp float;\n'; + case 'performance': + return 'precision highp float;\n'; + case 'balanced': default: - this.astGeneric(ast.left, retArr); + return 'precision mediump float;\n'; } - retArr.push(', '); - switch (this.getType(ast.right)) { + } + getIntTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp int;\n'; + case 'performance': + return 'precision highp int;\n'; + case 'balanced': + default: + return 'precision mediump int;\n'; + } + } + getSampler2DTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp sampler2D;\n'; + case 'performance': + return 'precision highp sampler2D;\n'; + case 'balanced': + default: + return 'precision mediump sampler2D;\n'; + } + } + getSampler2DArrayTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp sampler2DArray;\n'; + case 'performance': + return 'precision highp sampler2DArray;\n'; + case 'balanced': + default: + return 'precision mediump sampler2DArray;\n'; + } + } + renderTexture() { + return new this.TextureConstructor({ + texture: this.outputTexture, + size: this.texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }); + } + 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; + } + readMemoryOptimizedFloatPixelsToFloat32Array() { + 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$1.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] = new this.TextureConstructor({ + texture: this.subKernelOutputTextures[i], + size: this.texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }).toArray(); + } + return result; + } + renderKernelsToTextures() { + const result = { + result: this.renderOutput(), + }; + for (let i = 0; i < this.subKernels.length; i++) { + result[this.subKernels[i].property] = new this.TextureConstructor({ + texture: this.subKernelOutputTextures[i], + size: this.texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }); + } + return result; + } + setOutput(output) { + super.setOutput(output); + if (this.program) { + this.threadDim = [this.output[0], this.output[1] || 1, this.output[2] || 1]; + this.texSize = utils$1.getKernelTextureSize({ + optimizeFloatMemory: this.optimizeFloatMemory, + precision: this.precision, + }, this.output); + const { context: gl } = this; + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + this.updateMaxTexSize(); + this.framebuffer.width = this.texSize[0]; + this.framebuffer.height = this.texSize[1]; + this.context.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); + this.canvas.width = this.maxTexSize[0]; + this.canvas.height = this.maxTexSize[1]; + this._setupOutputTexture(); + if (this.subKernels && this.subKernels.length > 0) { + this._setupSubOutputTextures(); + } + } + return this; + } + renderValues() { + return this.formatValues( + this.transferValues(), + this.output[0], + this.output[1], + this.output[2] + ); + } + } + const renderStrategy = Object.freeze({ + PackedPixelToUint8Array: Symbol('PackedPixelToUint8Array'), + PackedPixelToFloat: Symbol('PackedPixelToFloat'), + PackedPixelTo2DFloat: Symbol('PackedPixelTo2DFloat'), + PackedPixelTo3DFloat: Symbol('PackedPixelTo3DFloat'), + PackedTexture: Symbol('PackedTexture'), + FloatPixelToFloat32Array: Symbol('FloatPixelToFloat32Array'), + FloatPixelToFloat: Symbol('FloatPixelToFloat'), + FloatPixelTo2DFloat: Symbol('FloatPixelTo2DFloat'), + FloatPixelTo3DFloat: Symbol('FloatPixelTo3DFloat'), + FloatPixelToArray2: Symbol('FloatPixelToArray2'), + FloatPixelTo2DArray2: Symbol('FloatPixelTo2DArray2'), + FloatPixelTo3DArray2: Symbol('FloatPixelTo3DArray2'), + FloatPixelToArray3: Symbol('FloatPixelToArray3'), + FloatPixelTo2DArray3: Symbol('FloatPixelTo2DArray3'), + FloatPixelTo3DArray3: Symbol('FloatPixelTo3DArray3'), + FloatPixelToArray4: Symbol('FloatPixelToArray4'), + FloatPixelTo2DArray4: Symbol('FloatPixelTo2DArray4'), + FloatPixelTo3DArray4: Symbol('FloatPixelTo3DArray4'), + FloatTexture: Symbol('FloatTexture'), + MemoryOptimizedFloatPixelToMemoryOptimizedFloat: Symbol('MemoryOptimizedFloatPixelToFloat'), + MemoryOptimizedFloatPixelToMemoryOptimized2DFloat: Symbol('MemoryOptimizedFloatPixelTo2DFloat'), + MemoryOptimizedFloatPixelToMemoryOptimized3DFloat: Symbol('MemoryOptimizedFloatPixelTo3DFloat'), + }); + const typeMap$1 = { + int: 'Integer', + float: 'Number', + vec2: 'Array(2)', + vec3: 'Array(3)', + vec4: 'Array(4)', + }; + + class WebGLFunctionNode extends FunctionNode { + constructor(source, settings) { + super(source, settings); + if (settings && settings.hasOwnProperty('fixIntegerDivisionAccuracy')) { + this.fixIntegerDivisionAccuracy = settings.fixIntegerDivisionAccuracy; + } + } + 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$2[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$2[argumentType]; + if (!type) { + throw this.astErrorOutput('Unexpected expression', ast); + } + retArr.push(type); + 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'); + } + 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': - this.castValueToFloat(ast.right, retArr); + 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 'LiteralInteger': - this.castLiteralToFloat(ast.right, retArr); + case 'Array(4)': + case 'Array(3)': + case 'Array(2)': + case 'Input': + this.astGeneric(ast.argument, result); break; default: - this.astGeneric(ast.right, retArr); + 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('') };`); } - 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': + astLiteral(ast, retArr) { + if (isNaN(ast.value)) { + throw this.astErrorOutput( + 'Non-numeric literal not supported : ' + ast.value, + ast + ); + } + const key = `${ast.start},${ast.end}`; + if (Number.isInteger(ast.value)) { + if (this.isState('in-for-loop-init') || 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('div_with_int_check('); this.pushState('building-float'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.astGeneric(ast.right, retArr); + 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'); - break; - case 'LiteralInteger & LiteralInteger': - if (this.isState('casting-to-integer') || this.isState('building-integer')) { + 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'); - } else { + break; + case 'Number & Float': + case 'Float & Number': + case 'Float & Float': + case 'Number & Number': this.pushState('building-float'); - this.castLiteralToFloat(ast.left, retArr); + this.astGeneric(ast.left, retArr); retArr.push(operatorMap[ast.operator] || ast.operator); - this.castLiteralToFloat(ast.right, retArr); + this.astGeneric(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); + 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; } - } - 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('')); + 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 { - throw this.astErrorOutput(`Unhandled binary expression with literal`, ast); + retArr.push('int('); + this.astGeneric(ast.right, retArr); + retArr.push(')'); } - } 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': - if (this.isState('in-for-loop-test')) { + this.popState('casting-to-integer'); + this.popState('building-integer'); + break; + case 'Integer & LiteralInteger': this.pushState('building-integer'); - retArr.push('int('); this.astGeneric(ast.left, retArr); - retArr.push(')'); retArr.push(operatorMap[ast.operator] || ast.operator); this.castLiteralToInteger(ast.right, retArr); this.popState('building-integer'); - } else { + break; + case 'Number & Integer': this.pushState('building-float'); this.astGeneric(ast.left, retArr); retArr.push(operatorMap[ast.operator] || ast.operator); - this.castLiteralToFloat(ast.right, retArr); + this.castValueToFloat(ast.right, retArr); this.popState('building-float'); - } - break; - case 'LiteralInteger & Float': - case 'LiteralInteger & Number': - if (this.isState('in-for-loop-test') || this.isState('in-for-loop-init') || this.isState('casting-to-integer')) { + break; + case 'Float & LiteralInteger': + case 'Number & LiteralInteger': + if (this.isState('in-for-loop-test')) { + this.pushState('building-integer'); + retArr.push('int('); + this.astGeneric(ast.left, retArr); + retArr.push(')'); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToInteger(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.castLiteralToFloat(ast.right, retArr); + this.popState('building-float'); + } + break; + case 'LiteralInteger & Float': + case 'LiteralInteger & Number': + if (this.isState('in-for-loop-test') || this.isState('in-for-loop-init') || 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.castValueToInteger(ast.right, retArr); + this.astGeneric(ast.right, retArr); this.popState('building-integer'); - } else { - this.pushState('building-float'); + break; + case 'Boolean & Boolean': + this.pushState('building-boolean'); 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 = { - '%': 'mod', - '**': '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); - - if (idtNode.name === 'Infinity') { - retArr.push('3.402823466e+38'); - } else if (type === 'Boolean') { - if (this.argumentNames.indexOf(idtNode.name) > -1) { - retArr.push(`bool(user_${idtNode.name})`); - } else { - retArr.push(`user_${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); - const { declarations } = forNode.init; - for (let i = 0; i < declarations.length; i++) { - if (declarations[i].init && declarations[i].init.type !== 'Literal') { - isSafe = false; - } - } - if (isSafe) { - 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.pushState('in-for-loop-test'); - this.astGeneric(forNode.test, testArr); - this.popState('in-for-loop-test'); - } 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 (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} 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; - } - switch (property) { - case 'r': - retArr.push(`user_${ name }.r`); - return retArr; - case 'g': - retArr.push(`user_${ name }.g`); - return retArr; - case 'b': - retArr.push(`user_${ name }.b`); - return retArr; - case 'a': - retArr.push(`user_${ name }.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_${ name }`); - return retArr; - } - } - case 'this.constants.value[]': - case 'this.constants.value[][]': - case 'this.constants.value[][][]': - case 'this.constants.value[][][][]': + this.popState('building-boolean'); break; - case 'fn()[]': - this.astCallExpression(mNode.object, retArr); - retArr.push('['); - retArr.push(this.memberExpressionPropertyMarkup(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}_${name}`); - return retArr; - } - } - - const markupName = `${origin}_${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 'HTMLImage': - 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; - 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); - } - - if (functionName === 'atan2') { - functionName = 'atan'; - } - - 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 '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') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast); - this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i); - retArr.push(`user_${argument.name}`); - continue; - } - break; - case 'HTMLImage': - 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); - retArr.push(`user_${argument.name},user_${argument.name}Size,user_${argument.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 arrLen = arrNode.elements.length; - - retArr.push('vec' + arrLen + '('); - for (let i = 0; i < arrLen; ++i) { - if (i > 0) { - retArr.push(', '); - } - const subNode = arrNode.elements[i]; - 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', - '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', - 'HTMLImage': 'sampler2D', - 'HTMLImageArray': 'sampler2DArray', -}; - -const operatorMap = { - '===': '==', - '!==': '!=' -}; - -module.exports = { - WebGLFunctionNode -}; -},{"../../utils":112,"../function-node":10}],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 { WebGLKernelValueSingleArray2 } = require('./kernel-value/single-array2'); -const { WebGLKernelValueSingleArray3 } = require('./kernel-value/single-array3'); -const { WebGLKernelValueSingleArray4 } = require('./kernel-value/single-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)': false, - 'Array(3)': false, - 'Array(4)': false, - '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, - 'HTMLImage': WebGLKernelValueDynamicHTMLImage, - 'HTMLImageArray': false, - 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGLKernelValueBoolean, - 'Float': WebGLKernelValueFloat, - 'Integer': WebGLKernelValueInteger, - 'Array': WebGLKernelValueUnsignedArray, - 'Array(2)': false, - 'Array(3)': false, - 'Array(4)': false, - '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, - 'HTMLImage': WebGLKernelValueHTMLImage, - 'HTMLImageArray': false, - 'HTMLVideo': WebGLKernelValueHTMLVideo, - } - }, - single: { - dynamic: { - 'Boolean': WebGLKernelValueBoolean, - 'Integer': WebGLKernelValueInteger, - 'Float': WebGLKernelValueFloat, - 'Array': WebGLKernelValueDynamicSingleArray, - 'Array(2)': WebGLKernelValueSingleArray2, - 'Array(3)': WebGLKernelValueSingleArray3, - 'Array(4)': WebGLKernelValueSingleArray4, - '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, - 'HTMLImage': WebGLKernelValueDynamicHTMLImage, - 'HTMLImageArray': false, - 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGLKernelValueBoolean, - 'Float': WebGLKernelValueFloat, - 'Integer': WebGLKernelValueInteger, - 'Array': WebGLKernelValueSingleArray, - 'Array(2)': WebGLKernelValueSingleArray2, - 'Array(3)': WebGLKernelValueSingleArray3, - 'Array(4)': WebGLKernelValueSingleArray4, - '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, - 'HTMLImage': 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/boolean":39,"./kernel-value/dynamic-html-image":40,"./kernel-value/dynamic-html-video":41,"./kernel-value/dynamic-memory-optimized-number-texture":42,"./kernel-value/dynamic-number-texture":43,"./kernel-value/dynamic-single-array":44,"./kernel-value/dynamic-single-array1d-i":45,"./kernel-value/dynamic-single-array2d-i":46,"./kernel-value/dynamic-single-array3d-i":47,"./kernel-value/dynamic-single-input":48,"./kernel-value/dynamic-unsigned-array":49,"./kernel-value/dynamic-unsigned-input":50,"./kernel-value/float":51,"./kernel-value/html-image":52,"./kernel-value/html-video":53,"./kernel-value/integer":55,"./kernel-value/memory-optimized-number-texture":56,"./kernel-value/number-texture":57,"./kernel-value/single-array":58,"./kernel-value/single-array1d-i":59,"./kernel-value/single-array2":60,"./kernel-value/single-array2d-i":61,"./kernel-value/single-array3":62,"./kernel-value/single-array3d-i":63,"./kernel-value/single-array4":64,"./kernel-value/single-input":65,"./kernel-value/unsigned-array":66,"./kernel-value/unsigned-input":67}],39:[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":112,"./index":54}],40:[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":112,"./html-image":52}],41:[function(require,module,exports){ -const { WebGLKernelValueDynamicHTMLImage } = require('./dynamic-html-image'); - -class WebGLKernelValueDynamicHTMLVideo extends WebGLKernelValueDynamicHTMLImage {} - -module.exports = { - WebGLKernelValueDynamicHTMLVideo -}; -},{"./dynamic-html-image":40}],42:[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.checkSize(inputTexture.size[0], inputTexture.size[1]); - this.dimensions = inputTexture.dimensions; - 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":112,"./memory-optimized-number-texture":56}],43:[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":112,"./number-texture":57}],44:[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.bitRatio, this.textureSize[1] * this.bitRatio); - 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":112,"./single-array":58}],45:[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":112,"./single-array1d-i":59}],46:[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":112,"./single-array2d-i":61}],47:[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":112,"./single-array3d-i":63}],48:[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.bitRatio, this.textureSize[1] * this.bitRatio); - 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":112,"./single-input":65}],49:[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] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - 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":112,"./unsigned-array":66}],50:[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] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - 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":112,"./unsigned-input":67}],51:[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":112,"./index":54}],52:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueHTMLImage extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - const { width, height } = value; - this.checkSize(width, height); - this.dimensions = [width, height, 1]; - this.requestTexture(); - 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(); - return; - } - 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); - 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":112,"./index":54}],53:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueHTMLImage } = require('./html-image'); - -class WebGLKernelValueHTMLVideo extends WebGLKernelValueHTMLImage {} - -module.exports = { - WebGLKernelValueHTMLVideo -}; -},{"../../../utils":112,"./html-image":52}],54:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { Input } = require('../../../input'); -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; - } - - 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 width of ${width} larger than maximum size of ${maxTextureSize} for your GPU`); - } else { - throw new Error(`Argument height of ${height} larger than maximum size of ${maxTextureSize} for your GPU`); - } - } - } - - requestTexture() { - this.texture = this.onRequestTexture(); - this.setupTexture(); - } - - setupTexture() { - this.contextHandle = this.onRequestContextHandle(); - this.index = this.onRequestIndex(); - this.dimensionsId = this.id + 'Dim'; - this.sizeId = this.id + 'Size'; - } - - 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; - } - formatArrayTransfer(value, length, Type) { - if (utils.isArray(value[0]) || this.optimizeFloatMemory) { - const valuesFlat = new Float32Array(length); - utils.flattenTo(value, valuesFlat); - return valuesFlat; - } else { - switch (value.constructor) { - case Uint8ClampedArray: - case Uint8Array: - case Int8Array: - case Uint16Array: - case Int16Array: - case Float32Array: - case Int32Array: { - const valuesFlat = new(Type || value.constructor)(length); - utils.flattenTo(value, valuesFlat); - return valuesFlat; - } - default: { - const valuesFlat = new Float32Array(length); - utils.flattenTo(value, valuesFlat); - return valuesFlat; - } - } - } - } - - 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; - } - } - - getStringValueHandler() { - throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`); - } - - getVariablePrecisionString() { - switch (this.tactic) { - case 'speed': - return 'lowp'; - case 'performance': - return 'highp'; - case 'balanced': - default: - return 'mediump'; - } - } -} - -module.exports = { - WebGLKernelValue -}; -},{"../../../input":108,"../../../utils":112,"../../kernel-value":34}],55:[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":112,"./index":54}],56:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueMemoryOptimizedNumberTexture extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - const [width, height] = value.size; - this.checkSize(width, height); - this.setupTexture(); - this.dimensions = value.dimensions; - this.textureSize = value.size; - this.uploadValue = value.texture; - this.forceUploadEachRun = true; - } - - 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(); - return; - } - if (this.checkContext && inputTexture.context !== this.context) { - throw new Error(`Value ${this.name} (${this.type }) must be from same context`); - } - const { context: gl } = this; - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueMemoryOptimizedNumberTexture -}; -},{"../../../utils":112,"./index":54}],57:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueNumberTexture extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - const [width, height] = value.size; - this.checkSize(width, height); - this.setupTexture(); - const { size: textureSize, dimensions } = value; - this.bitRatio = this.getBitRatio(value); - this.dimensions = dimensions; - this.textureSize = textureSize; - this.uploadValue = value.texture; - this.forceUploadEachRun = true; - } - - 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(); - return; - } - if (this.checkContext && inputTexture.context !== this.context) { - throw new Error(`Value ${this.name} (${this.type}) must be from same context`); - } - const { context: gl } = this; - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueNumberTexture -}; -},{"../../../utils":112,"./index":54}],58:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - 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.bitRatio, this.textureSize[1] * this.bitRatio); - 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(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - 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); - 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":112,"./index":54}],59:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray1DI extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - 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.bitRatio, this.textureSize[1] * this.bitRatio); - 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(); - return; - } - const { context: gl } = this; - utils.flatten2dArrayTo(value, this.uploadValue); - 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); - 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":112,"./index":54}],60:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray2 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 = { - WebGLKernelValueSingleArray2 -}; -},{"../../../utils":112,"./index":54}],61:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray2DI extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - 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.bitRatio, this.textureSize[1] * this.bitRatio); - 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(); - return; - } - const { context: gl } = this; - utils.flatten3dArrayTo(value, this.uploadValue); - 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); - 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":112,"./index":54}],62:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray3 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 = { - WebGLKernelValueSingleArray3 -}; -},{"../../../utils":112,"./index":54}],63:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray3DI extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - 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.bitRatio, this.textureSize[1] * this.bitRatio); - 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(); - return; - } - const { context: gl } = this; - utils.flatten4dArrayTo(value, this.uploadValue); - 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); - 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":112,"./index":54}],64:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray4 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 = { - WebGLKernelValueSingleArray4 -}; -},{"../../../utils":112,"./index":54}],65:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleInput extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - 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.bitRatio, this.textureSize[1] * this.bitRatio); - 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(); - return; - } - const { context: gl } = this; - utils.flattenTo(input.value, this.uploadValue); - 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); - 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":112,"./index":54}],66:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueUnsignedArray extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - 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] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - 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(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.preUploadValue); - 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); - 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":112,"./index":54}],67:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueUnsignedInput extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - 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] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - 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(); - return; - } - const { context: gl } = this; - utils.flattenTo(input.value, this.preUploadValue); - 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); - 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":112,"./index":54}],68:[function(require,module,exports){ -const { GLKernel } = require('../gl/kernel'); -const { FunctionBuilder } = require('../function-builder'); -const { WebGLFunctionNode } = require('./function-node'); -const { utils } = require('../../utils'); -const triangleNoise = require('../../plugins/triangle-noise'); -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 = [triangleNoise]; -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 getFeatures() { - const isDrawBuffers = this.getIsDrawBuffers(); - return Object.freeze({ - isFloatRead: this.getIsFloatRead(), - isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), - isTextureFloat: this.getIsTextureFloat(), - isDrawBuffers, - kernelMap: isDrawBuffers, - channelCount: this.getChannelCount(), - maxTextureSize: this.getMaxTextureSize(), - }); - } - - 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.subKernelOutputTextures = null; - this.kernelArguments = null; - this.argumentTextureCount = 0; - this.constantTextureCount = 0; - this.compiledFragmentShader = null; - this.compiledVertexShader = null; - this.fragShader = null; - this.vertShader = null; - this.drawBuffersMap = null; - this.outputTexture = null; - - this.maxTexSize = null; - this.switchingKernels = false; - this.onRequestSwitchKernel = 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); - 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); + 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; } - - if (this.graphical) { - if (this.output.length !== 2) { - throw new Error('Output must have 2 dimensions on graphical mode'); + checkAndUpconvertOperator(ast, retArr) { + const bitwiseResult = this.checkAndUpconvertBitwiseOperators(ast, retArr); + if (bitwiseResult) { + return bitwiseResult; } - - if (this.precision === 'precision') { - this.precision = 'unsigned'; - console.warn('Cannot use graphical mode and single precision at the same time'); + const upconvertableOperators = { + '%': 'mod', + '**': '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); } - - 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]]; + 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.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]; - } - } - - _oldtranslateSource() { - const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { - fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy - }); - - const translatedSource = functionBuilder.getPrototypeString('kernel'); - - if (!this.returnType) { - this.returnType = functionBuilder.getKernelResultType(); + retArr.push(')'); + return retArr; } - - let requiredChannels = 0; - const returnTypes = functionBuilder.getReturnTypes(); - for (let i = 0; i < returnTypes.length; i++) { - switch (returnTypes[i]) { + 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 'Integer': - requiredChannels++; + case 'Float': + this.castValueToInteger(ast.right, retArr); break; - case 'Array(2)': - requiredChannels += 2; + case 'LiteralInteger': + this.castLiteralToInteger(ast.right, retArr); break; - case 'Array(3)': - requiredChannels += 3; + 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 'Array(4)': - requiredChannels += 4; + case 'LiteralInteger': + this.castLiteralToInteger(ast.argument, retArr); break; + default: + this.astGeneric(ast.argument, retArr); } + retArr.push(')'); + return retArr; } - - if (features && requiredChannels > features.channelCount) { - throw new Error('Too many channels!'); + castLiteralToInteger(ast, retArr) { + this.pushState('casting-to-integer'); + this.astGeneric(ast, retArr); + this.popState('casting-to-integer'); + return retArr; } - - return this.translatedSource = translatedSource; - } - - setupArguments(args) { - this.kernelArguments = []; - this.argumentTextureCount = 0; - const needsArgumentTypes = this.argumentTypes === null; - if (needsArgumentTypes) { - this.argumentTypes = []; + castLiteralToFloat(ast, retArr) { + this.pushState('casting-to-float'); + this.astGeneric(ast, retArr); + this.popState('casting-to-float'); + return retArr; } - 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'); + castValueToInteger(ast, retArr) { + this.pushState('casting-to-integer'); + retArr.push('int('); + this.astGeneric(ast, retArr); + retArr.push(')'); + this.popState('casting-to-integer'); + return retArr; } - - const { context: gl } = this; - let textureIndexes = 0; - 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); + 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 kernelArgument = new KernelValue(value, { - name, - type, - tactic: this.tactic, - origin: 'user', - context: gl, - checkContext: this.checkContext, - kernel: this, - strictIntegers: this.strictIntegers, - onRequestTexture: () => { - return this.context.createTexture(); - }, - onRequestIndex: () => { - return textureIndexes++; - }, - onUpdateValueMismatch: () => { - this.switchingKernels = true; - }, - onRequestContextHandle: () => { - return gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount++; + const type = this.getType(idtNode); + if (idtNode.name === 'Infinity') { + retArr.push('3.402823466e+38'); + } else if (type === 'Boolean') { + if (this.argumentNames.indexOf(idtNode.name) > -1) { + retArr.push(`bool(user_${idtNode.name})`); + } else { + retArr.push(`user_${idtNode.name}`); } - }); - this.kernelArguments.push(kernelArgument); - this.argumentSizes.push(kernelArgument.textureSize); - this.argumentBitRatios[index] = kernelArgument.bitRatio; - } - } - - setupConstants(args) { - const { context: gl } = this; - this.kernelConstants = []; - this.forceUploadKernelConstants = []; - let needsConstantTypes = this.constantTypes === null; - if (needsConstantTypes) { - this.constantTypes = {}; + } else { + retArr.push(`user_${idtNode.name}`); + } + return retArr; } - 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; + 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); + const { declarations } = forNode.init; + for (let i = 0; i < declarations.length; i++) { + if (declarations[i].init && declarations[i].init.type !== 'Literal') { + isSafe = false; + } + } + if (isSafe) { + for (let i = 0; i < initArr.length; i++) { + if (initArr[i].includes && initArr[i].includes(',')) { + isSafe = false; + } + } + } + this.popState('in-for-loop-init'); } else { - type = this.constantTypes[name]; + isSafe = false; } - const KernelValue = this.constructor.lookupKernelValueType(type, 'static', this.precision, value); - if (KernelValue === null) { - return this.requestFallback(args); + if (forNode.test) { + this.pushState('in-for-loop-test'); + this.astGeneric(forNode.test, testArr); + this.popState('in-for-loop-test'); + } else { + isSafe = false; } - 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.context.createTexture(); - }, - onRequestIndex: () => { - return textureIndexes++; - }, - onRequestContextHandle: () => { - return gl.TEXTURE0 + this.constantTextureCount++; - } - }); - this.constantBitRatios[name] = kernelValue.bitRatio; - this.kernelConstants.push(kernelValue); - if (kernelValue.forceUploadEachRun) { - this.forceUploadKernelConstants.push(kernelValue); + if (forNode.update) { + this.astGeneric(forNode.update, updateArr); + } else { + isSafe = false; } - } - } - - build() { - 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]; - - 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]); - } - - if (!this.immutable) { - this._setupOutputTexture(); - if ( - this.subKernels !== null && - this.subKernels.length > 0 - ) { - this._setupSubOutputTextures(); + if (forNode.body) { + this.pushState('loop-body'); + this.astGeneric(forNode.body, bodyArr); + this.popState('loop-body'); } - } - } - - translateSource() { - const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { - fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy - }); - this.translatedSource = functionBuilder.getPrototypeString('kernel'); - 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); - } + if (isSafe === null) { + isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test); } - } - } - - run() { - const { kernelArguments, forceUploadKernelConstants } = this; - const texSize = this.texSize; - const gl = this.context; - - 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]); - - this.switchingKernels = false; - 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 (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'); } - } - } - - if (this.graphical) { - if (this.pipeline) { - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - if (!this.outputTexture || this.immutable) { - this._setupOutputTexture(); + retArr.push(`for (int ${iVariableName}=0;${iVariableName} 0) { + retArr.push(`if (!${testArr.join('')}) break;\n`); } - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - return new this.TextureConstructor({ - texture: this.outputTexture, - size: texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }); + retArr.push(bodyArr.join('')); + retArr.push(`\n${updateArr.join('')};`); + retArr.push('}\n'); } - 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._setupOutputTexture(); + return retArr; } - - if (this.subKernels !== null) { - if (this.immutable) { - this._setupSubOutputTextures(); + astWhileStatement(whileNode, retArr) { + if (whileNode.type !== 'WhileStatement') { + throw this.astErrorOutput('Invalid while statement', whileNode); } - this.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(this.drawBuffersMap); + const iVariableName = this.getInternalVariableName('safeI'); + retArr.push(`for (int ${iVariableName}=0;${iVariableName} 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 div_with_int_check(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; -}` : - ''; - } - - _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) { - result.push(this.kernelConstants[i++].getSource(this.constants[name])); + if (cases.length === 1 && !cases[0].test) { + this.astGeneric(cases[0].consequent, retArr); + return retArr; } - } - return result.join(''); - } - - getKernelString() { - let kernelResultDeclaration; - switch (this.returnType) { - case 'Array(2)': - kernelResultDeclaration = 'vec2 kernelResult'; - break; - case 'Array(3)': - kernelResultDeclaration = 'vec3 kernelResult'; - break; - case 'Array(4)': - kernelResultDeclaration = 'vec4 kernelResult'; - break; - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - kernelResultDeclaration = 'float kernelResult'; - break; - default: - if (this.graphical) { - kernelResultDeclaration = 'float kernelResult'; + 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 { - throw new Error(`unrecognized output type "${ this.returnType }"`); + 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; } - - const result = []; - const subKernels = this.subKernels; - if (subKernels !== null) { - result.push( - kernelResultDeclaration - ); - switch (this.returnType) { + 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; + } + switch (property) { + case 'r': + retArr.push(`user_${ name }.r`); + return retArr; + case 'g': + retArr.push(`user_${ name }.g`); + return retArr; + case 'b': + retArr.push(`user_${ name }.b`); + return retArr; + case 'a': + retArr.push(`user_${ name }.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_${ 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 '[][]': + 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}_${name}`); + return retArr; + } + } + const markupName = `${origin}_${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 'HTMLImage': + 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': - 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 }` + 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 'Array(4)': - for (let i = 0; i < subKernels.length; i++) { - result.push( - `vec4 subKernelResult_${ subKernels[i].name }` - ); - } + case 'MemoryOptimizedNumberTexture': + retArr.push(`getMemoryOptimized32(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); break; + default: + throw new Error(`unhandled member expression "${ type }"`); } - } else { - result.push( - kernelResultDeclaration - ); - } - - 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 retArr; } - } - - 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}))` - ); + 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 { - result.push( - ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})` - ); + functionName = ast.callee.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'); + if (!functionName) { + throw this.astErrorOutput(`Unhandled function, couldn't find name`, ast); + } + if (functionName === 'atan2') { + functionName = 'atan'; + } + 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; } } - 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}`, - ); + 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 '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') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast); + this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i); + retArr.push(`user_${argument.name}`); + continue; + } + break; + case 'HTMLImage': + 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); + retArr.push(`user_${argument.name},user_${argument.name}Size,user_${argument.name}Dim`); + continue; + } + break; + } + throw this.astErrorOutput(`Unhandled argument combination of ${ argumentType } and ${ targetType } for argument named "${ argument.name }"`, ast); + } } + retArr.push(')'); + return retArr; } - } - - 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})`, - ); + astArrayExpression(arrNode, retArr) { + const arrLen = arrNode.elements.length; + retArr.push('vec' + arrLen + '('); + for (let i = 0; i < arrLen; ++i) { + if (i > 0) { + retArr.push(', '); + } + const subNode = arrNode.elements[i]; + this.astGeneric(subNode, retArr); + } + retArr.push(')'); + return retArr; + } + memberExpressionXYZ(x, y, z, retArr) { + if (z) { + retArr.push(this.memberExpressionPropertyMarkup(z), ', '); } else { - result.push( - ` gl_FragData[${i + 1}][0] = subKernelResult_${subKernel.name}`, - ); + retArr.push('0, '); + } + if (y) { + retArr.push(this.memberExpressionPropertyMarkup(y), ', '); + } else { + retArr.push('0, '); } + retArr.push(this.memberExpressionPropertyMarkup(x)); + return retArr; } - return result; - } - - getMainResultKernelArray2Texture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' gl_FragData[0][0] = kernelResult[0]', - ' gl_FragData[0][1] = kernelResult[1]', - ]; - } + 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$2 = { + 'Array': 'sampler2D', + 'Array(2)': 'vec2', + 'Array(3)': 'vec3', + 'Array(4)': 'vec4', + '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', + 'HTMLImage': 'sampler2D', + 'HTMLImageArray': 'sampler2DArray', + }; + const operatorMap = { + '===': '==', + '!==': '!=' + }; - 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; - } + const source = ` + +uniform highp float triangle_noise_seed; +highp float triangle_noise_shift = 0.000001; + +//https://www.shadertoy.com/view/4t2SDh +//note: uniformly distributed, normalized rand, [0;1[ +float nrand( vec2 n ) +{ + return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453); +} +//note: remaps v to [0;1] in interval [a;b] +float remap( float a, float b, float v ) +{ + return clamp( (v-a) / (b-a), 0.0, 1.0 ); +} + +float n4rand( vec2 n ) +{ + float t = fract( triangle_noise_seed + triangle_noise_shift ); + float nrnd0 = nrand( n + 0.07*t ); + float nrnd1 = nrand( n + 0.11*t ); + float nrnd2 = nrand( n + 0.13*t ); + float nrnd3 = nrand( n + 0.17*t ); + float result = (nrnd0+nrnd1+nrnd2+nrnd3) / 4.0; + triangle_noise_shift = result + 0.000001; + return result; +}`; + const name$1 = 'triangle-noise-noise'; + const functionMatch = 'Math.random()'; + const functionReplace = 'n4rand(vTexCoord)'; + const functionReturnType = 'Number'; + const onBeforeRun = (kernel) => { + kernel.setUniform1f('triangle_noise_seed', Math.random()); + }; + var triangleNoise = { + name: name$1, + onBeforeRun, + functionMatch, + functionReplace, + functionReturnType, + source + }; - 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]', - ]; - } + const fragmentShader = `__HEADER__; +__FLOAT_TACTIC_DECLARATION__; +__INT_TACTIC_DECLARATION__; +__SAMPLER_2D_TACTIC_DECLARATION__; + +const int LOOP_MAX = __LOOP_MAX__; + +__PLUGINS__; +__CONSTANTS__; + +varying vec2 vTexCoord; + +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); +} + +__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__; +}`; - 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; - } + 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; +}`; - getMainResultKernelArray4Texture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' gl_FragData[0] = kernelResult', - ]; + function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; } - 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}`, - ); + var glWiretap_1 = createCommonjsModule(function (module) { + 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; } - 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; + entityNames[gl[property]] = property; + return gl[property]; } - return this.compiledFragmentShader = this.replaceArtifacts(this.constructor.fragmentShader, this._getFragShaderArtifactMap(args)); - } - - getVertexShader(args) { - if (this.compiledVertexShader !== null) { - return this.compiledVertexShader; + function toString() { + return recording.join('\n'); } - 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.outputTexture) { - this.context.deleteTexture(this.outputTexture); + function reset() { + while (recording.length > 0) { + recording.pop(); + } } - if (this.buffer) { - this.context.deleteBuffer(this.buffer); + function insertVariable(name, value) { + variables[name] = value; } - if (this.framebuffer) { - this.context.deleteFramebuffer(this.framebuffer); + function getEntity(value) { + const name = entityNames[value]; + if (name) { + return contextName + '.' + name; + } + return value; } - if (this.vertShader) { - this.context.deleteShader(this.vertShader); + function setIndent(spaces) { + indent = ' '.repeat(spaces); } - if (this.fragShader) { - this.context.deleteShader(this.fragShader); + function addVariable(value, source) { + const variableName = `${contextName}Variable${contextVariables.length}`; + recording.push(`${indent}const ${variableName} = ${source};`); + contextVariables.push(value); + return variableName; } - if (this.program) { - this.context.deleteProgram(this.program); + 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}})();`); } - - const keys = Object.keys(this.textureCache); - - for (let i = 0; i < keys.length; i++) { - const name = keys[i]; - this.context.deleteTexture(this.textureCache[name]); + function methodCallToString(method, args) { + return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`; } - - if (this.subKernelOutputTextures) { - for (let i = 0; i < this.subKernelOutputTextures.length; i++) { - this.context.deleteTexture(this.subKernelOutputTextures[i]); + function getVariableName(value) { + if (variables) { + for (const name in variables) { + if (variables[name] === value) { + return name; + } + } } + return null; } - if (removeCanvasReferences) { - const idx = canvases.indexOf(this.canvas); - if (idx >= 0) { - canvases[idx] = null; - maxTexSizes[idx] = null; + function getContextVariableName(value) { + const i = contextVariables.indexOf(value); + if (i !== -1) { + return `${contextName}Variable${i}`; } - } - this.destroyExtensions(); - delete this.context; - delete this.canvas; - } - - 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 null; } } - - toJSON() { - const json = super.toJSON(); - json.functionNodes = FunctionBuilder.fromKernel(this, WebGLFunctionNode).toJSON(); - return json; - } -} - -module.exports = { - WebGLKernel -}; -},{"../../plugins/triangle-noise":110,"../../utils":112,"../function-builder":9,"../gl/kernel":13,"../gl/kernel-string":12,"./fragment-shader":36,"./function-node":37,"./kernel-value-maps":38,"./vertex-shader":69}],69:[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 -}; -},{}],70:[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; - -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; + 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]; } - } - 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; + function getExtensionEntity(value) { + if (extensionEntityNames.hasOwnProperty(value)) { + return `${contextName}.${extensionEntityNames[value]}`; + } + return getEntity(value); } - } - 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; + function methodCallToString(method, args) { + return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`; } - } - 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; + function addVariable(value, source) { + const variableName = `${contextName}Variable${contextVariables.length}`; + contextVariables.push(value); + recording.push(`${indent}const ${variableName} = ${source};`); + return variableName; } - 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; + 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; } - maxBytes *= 2; } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; + function argumentToString(arg, options) { + const { contextName, contextVariables, getEntity, addVariable, onUnrecognizedArgumentLookup } = options; + if (typeof arg === 'undefined') { + return 'undefined'; } - 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); + if (arg === null) { + return 'null'; } - } -} - -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); -} - -__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 -}; -},{}],71:[function(require,module,exports){ -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 i = contextVariables.indexOf(arg); + if (i > -1) { + return `${contextName}Variable${i}`; } - - const type = this.getType(idtNode); - - if (idtNode.name === 'Infinity') { - retArr.push('intBitsToFloat(2139095039)'); - } else if (type === 'Boolean') { - if (this.argumentNames.indexOf(idtNode.name) > -1) { - retArr.push(`bool(user_${idtNode.name})`); - } else { - retArr.push(`user_${idtNode.name}`); - } - } else { - retArr.push(`user_${idtNode.name}`); + 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}`); } - - return retArr; - } -} - -module.exports = { - WebGL2FunctionNode -}; -},{"../web-gl/function-node":37}],72:[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 { WebGL2KernelValueSingleArray2 } = require('./kernel-value/single-array2'); -const { WebGL2KernelValueSingleArray3 } = require('./kernel-value/single-array3'); -const { WebGL2KernelValueSingleArray4 } = require('./kernel-value/single-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)': false, - 'Array(3)': false, - 'Array(4)': false, - '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, - 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, - 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, - 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGL2KernelValueBoolean, - 'Float': WebGL2KernelValueFloat, - 'Integer': WebGL2KernelValueInteger, - 'Array': WebGL2KernelValueUnsignedArray, - 'Array(2)': false, - 'Array(3)': false, - 'Array(4)': false, - '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, - 'HTMLImage': WebGL2KernelValueHTMLImage, - 'HTMLImageArray': WebGL2KernelValueHTMLImageArray, - 'HTMLVideo': WebGL2KernelValueHTMLVideo, - } - }, - single: { - dynamic: { - 'Boolean': WebGL2KernelValueBoolean, - 'Integer': WebGL2KernelValueInteger, - 'Float': WebGL2KernelValueFloat, - 'Array': WebGL2KernelValueDynamicSingleArray, - 'Array(2)': WebGL2KernelValueSingleArray2, - 'Array(3)': WebGL2KernelValueSingleArray3, - 'Array(4)': WebGL2KernelValueSingleArray4, - '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, - 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, - 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, - 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGL2KernelValueBoolean, - 'Float': WebGL2KernelValueFloat, - 'Integer': WebGL2KernelValueInteger, - 'Array': WebGL2KernelValueSingleArray, - 'Array(2)': WebGL2KernelValueSingleArray2, - 'Array(3)': WebGL2KernelValueSingleArray3, - 'Array(4)': WebGL2KernelValueSingleArray4, - '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, - 'HTMLImage': 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/boolean":73,"./kernel-value/dynamic-html-image":75,"./kernel-value/dynamic-html-image-array":74,"./kernel-value/dynamic-html-video":76,"./kernel-value/dynamic-memory-optimized-number-texture":77,"./kernel-value/dynamic-number-texture":78,"./kernel-value/dynamic-single-array":79,"./kernel-value/dynamic-single-array1d-i":80,"./kernel-value/dynamic-single-array2d-i":81,"./kernel-value/dynamic-single-array3d-i":82,"./kernel-value/dynamic-single-input":83,"./kernel-value/dynamic-unsigned-array":84,"./kernel-value/dynamic-unsigned-input":85,"./kernel-value/float":86,"./kernel-value/html-image":88,"./kernel-value/html-image-array":87,"./kernel-value/html-video":89,"./kernel-value/integer":90,"./kernel-value/memory-optimized-number-texture":91,"./kernel-value/number-texture":92,"./kernel-value/single-array":93,"./kernel-value/single-array1d-i":94,"./kernel-value/single-array2":95,"./kernel-value/single-array2d-i":96,"./kernel-value/single-array3":97,"./kernel-value/single-array3d-i":98,"./kernel-value/single-array4":99,"./kernel-value/single-input":100,"./kernel-value/unsigned-array":101,"./kernel-value/unsigned-input":102}],73:[function(require,module,exports){ -const { WebGLKernelValueBoolean } = require('../../web-gl/kernel-value/boolean'); - -class WebGL2KernelValueBoolean extends WebGLKernelValueBoolean {} - -module.exports = { - WebGL2KernelValueBoolean -}; -},{"../../web-gl/kernel-value/boolean":39}],74:[function(require,module,exports){ -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 -}; -},{"./html-image-array":87}],75:[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":112,"../../web-gl/kernel-value/dynamic-html-image":40}],76:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueDynamicHTMLImage } = require('./dynamic-html-image'); - -class WebGL2KernelValueDynamicHTMLVideo extends WebGL2KernelValueDynamicHTMLImage {} - -module.exports = { - WebGL2KernelValueDynamicHTMLVideo -}; -},{"../../../utils":112,"./dynamic-html-image":75}],77:[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":112,"../../web-gl/kernel-value/dynamic-memory-optimized-number-texture":42}],78:[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":112,"../../web-gl/kernel-value/dynamic-number-texture":43}],79:[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.bitRatio, this.textureSize[1] * this.bitRatio); - 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":112,"../../web-gl2/kernel-value/single-array":93}],80:[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":112,"../../web-gl2/kernel-value/single-array1d-i":94}],81:[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":112,"../../web-gl2/kernel-value/single-array2d-i":96}],82:[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":112,"../../web-gl2/kernel-value/single-array3d-i":98}],83:[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.bitRatio, this.textureSize[1] * this.bitRatio); - 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":112,"../../web-gl2/kernel-value/single-input":100}],84:[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":112,"../../web-gl/kernel-value/dynamic-unsigned-array":49}],85:[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":112,"../../web-gl/kernel-value/dynamic-unsigned-input":50}],86:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueFloat } = require('../../web-gl/kernel-value/float'); - -class WebGL2KernelValueFloat extends WebGLKernelValueFloat {} - -module.exports = { - WebGL2KernelValueFloat -}; -},{"../../../utils":112,"../../web-gl/kernel-value/float":51}],87:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('../../web-gl/kernel-value/index'); - -class WebGL2KernelValueHTMLImageArray extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.checkSize(value[0].width, value[0].height); - this.requestTexture(); - this.dimensions = [value[0].width, value[0].height, value.length]; - this.textureSize = [value[0].width, value[0].height]; + function trackablePrimitive(value) { + return new value.constructor(value); } - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName};\n`; + { + module.exports = { glWiretap, glExtensionWiretap }; } - 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]})`, - ]); + if (typeof window !== 'undefined') { + glWiretap.glExtensionWiretap = glExtensionWiretap; + window.glWiretap = glWiretap; } - - updateValue(images) { - 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); - 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] + }); + var glWiretap_2 = glWiretap_1.glWiretap; + var glWiretap_3 = glWiretap_1.glExtensionWiretap; + + function toStringWithoutUtils(fn) { + return fn.toString() + .replace('=>', '') + .replace(/^function /, '') + .replace(/utils[.]/g, '/*utils.*/'); + } + function glKernelString(Kernel, args, originKernel, setupContextString, destroyContextString) { + 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 postResult = []; + const context = glWiretap_2(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); + if (argumentName) { + return argumentName; + } + const constantName = findKernelValue(argument, kernel.kernelConstants, constants ? Object.keys(constants).map(key => constants[key]) : [], context); + 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, + } = originKernel; + const kernel = new Kernel(source, { + canvas, + context, + checkContext: false, + output, + pipeline, + graphical, + loopMaxIterations, + constants, + optimizeFloatMemory, + precision, + fixIntegerDivisionAccuracy, + functions, + nativeFunctions, + subKernels, + immutable, + argumentTypes, + constantTypes, + }); + 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 '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$1.flattenTo)}`); + result.push(`function ${toStringWithoutUtils(utils$1.flatten2dArrayTo)}`); + result.push(`function ${toStringWithoutUtils(utils$1.flatten3dArrayTo)}`); + result.push(`function ${toStringWithoutUtils(utils$1.flatten4dArrayTo)}`); + result.push(`function ${toStringWithoutUtils(utils$1.isArray)}`); + if (kernel.renderOutput !== kernel.renderTexture && kernel.formatValues) { + result.push( + ` const renderOutput = function ${toStringWithoutUtils(kernel.formatValues)};` ); } - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGL2KernelValueHTMLImageArray -}; -},{"../../../utils":112,"../../web-gl/kernel-value/index":54}],88:[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":112,"../../web-gl/kernel-value/html-image":52}],89:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueHTMLImage } = require('./html-image'); - -class WebGL2KernelValueHTMLVideo extends WebGL2KernelValueHTMLImage {} - -module.exports = { - WebGL2KernelValueHTMLVideo -}; -},{"../../../utils":112,"./html-image":88}],90:[function(require,module,exports){ -const { utils } = require('../../../utils'); -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`; + 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 results = kernel.renderKernels(); + const textureName = context.getContextVariableName(kernel.outputTexture); + result.push(` return { + result: { + texture: ${ textureName }, + type: '${ results.result.type }', + toArray: ${ getToArrayString(results.result, textureName) } + },`); + const { subKernels, subKernelOutputTextures } = kernel; + for (let i = 0; i < subKernels.length; i++) { + const texture = subKernelOutputTextures[i]; + const subKernel = subKernels[i]; + const subKernelResult = results[subKernel.property]; + const subKernelTextureName = context.getContextVariableName(texture); + result.push(` + ${subKernel.property}: { + texture: ${ subKernelTextureName }, + type: '${ subKernelResult.type }', + toArray: ${ getToArrayString(subKernelResult, subKernelTextureName) } + },`); + } + result.push(` };`); + } + result.push(` ${destroyContextString ? '\n' + destroyContextString + ' ': ''}`); + result.push(postResult.join('\n')); + result.push(' };'); + if (kernel.graphical) { + result.push(getGetPixelsString(kernel)); + result.push(` innerKernel.getPixels = getPixels;`); } - 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 -}; -},{"../../../utils":112,"../../web-gl/kernel-value/integer":55}],91:[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":112,"../../web-gl/kernel-value/memory-optimized-number-texture":56}],92:[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":112,"../../web-gl/kernel-value/number-texture":57}],93:[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(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - 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); - 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":112,"../../web-gl/kernel-value/single-array":58}],94:[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(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - 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); - 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":112,"../../web-gl/kernel-value/single-array1d-i":59}],95:[function(require,module,exports){ -const { WebGLKernelValueSingleArray2 } = require('../../web-gl/kernel-value/single-array2'); - -class WebGL2KernelValueSingleArray2 extends WebGLKernelValueSingleArray2 {} - -module.exports = { - WebGL2KernelValueSingleArray2 -}; -},{"../../web-gl/kernel-value/single-array2":60}],96:[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(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - 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); - 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":112,"../../web-gl/kernel-value/single-array2d-i":61}],97:[function(require,module,exports){ -const { WebGLKernelValueSingleArray3 } = require('../../web-gl/kernel-value/single-array3'); - -class WebGL2KernelValueSingleArray3 extends WebGLKernelValueSingleArray3 {} - -module.exports = { - WebGL2KernelValueSingleArray3 -}; -},{"../../web-gl/kernel-value/single-array3":62}],98:[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(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - 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); - 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":112,"../../web-gl/kernel-value/single-array3d-i":63}],99:[function(require,module,exports){ -const { WebGLKernelValueSingleArray4 } = require('../../web-gl/kernel-value/single-array4'); - -class WebGL2KernelValueSingleArray4 extends WebGLKernelValueSingleArray4 {} - -module.exports = { - WebGL2KernelValueSingleArray4 -}; -},{"../../web-gl/kernel-value/single-array4":64}],100:[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.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); - 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":112,"../../web-gl/kernel-value/single-input":65}],101:[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":112,"../../web-gl/kernel-value/unsigned-array":66}],102:[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]})`, - ]); + 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')} +}`; } -} - -module.exports = { - WebGL2KernelValueUnsignedInput -}; -},{"../../../utils":112,"../../web-gl/kernel-value/unsigned-input":67}],103:[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; + 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]})`; } - 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; + if (kernel.output[1]) { + return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]})`; } - return false; + return `renderOutput(${readBackValue}, ${kernel.output[0]})`; } - - static getFeatures() { - return Object.freeze({ - isFloatRead: this.getIsFloatRead(), - isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), - kernelMap: true, - isTextureFloat: true, - channelCount: this.getChannelCount(), - maxTextureSize: this.getMaxTextureSize(), + function getGetPixelsString(kernel) { + const getPixels = kernel.getPixels.toString(); + const useFunctionKeyword = !/^function/.test(getPixels); + return utils$1.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ getPixels }`, { + findDependency: (object, name) => { + if (object === 'utils') { + return `const ${name} = ${utils$1[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 }`); + } }); } - - static getIsTextureFloat() { - return true; + function getToArrayString(kernelResult, textureName) { + const toArray = kernelResult.toArray.toString(); + const useFunctionKeyword = !/^function/.test(toArray); + const flattenedFunctions = utils$1.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ toArray }`, { + findDependency: (object, name) => { + if (object === 'utils') { + return `const ${name} = ${utils$1[name].toString()};`; + } else if (object === 'this') { + return `${useFunctionKeyword ? 'function ' : ''}${kernelResult[name].toString()}`; + } else { + throw new Error('unhandled fromObject'); + } + }, + thisLookup: (property) => { + if (property === 'texture') { + return textureName; + } + if (kernelResult.hasOwnProperty(property)) { + return JSON.stringify(kernelResult[property]); + } + throw new Error(`unhandled thisLookup ${ property }`); + } + }); + return `() => { + ${flattenedFunctions} + return toArray(); + }`; } - - static getIsIntegerDivisionAccurate() { - return super.getIsIntegerDivisionAccurate(); + function findKernelValue(argument, kernelValues, values, context, uploadedValues) { + if (argument === 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') 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; + } + return null; + } + 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; } - static getChannelCount() { - return testContext.getParameter(testContext.MAX_DRAW_BUFFERS); + 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 (!tactic) { + throw new Error('tactic 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.id = `${this.origin}_${name}`; + 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; + } + getSource() { + throw new Error(`"getSource" not defined on ${ this.constructor.name }`); + } + updateValue(value) { + throw new Error(`"updateValue" not defined on ${ this.constructor.name }`); + } + } + + 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; + } + 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 width of ${width} larger than maximum size of ${maxTextureSize} for your GPU`); + } else { + throw new Error(`Argument height of ${height} larger than maximum size of ${maxTextureSize} for your GPU`); + } + } + } + requestTexture() { + this.texture = this.onRequestTexture(); + this.setupTexture(); + } + setupTexture() { + this.contextHandle = this.onRequestContextHandle(); + this.index = this.onRequestIndex(); + this.dimensionsId = this.id + 'Dim'; + this.sizeId = this.id + 'Size'; + } + 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; + } + formatArrayTransfer(value, length, Type) { + if (utils$1.isArray(value[0]) || this.optimizeFloatMemory) { + const valuesFlat = new Float32Array(length); + utils$1.flattenTo(value, valuesFlat); + return valuesFlat; + } else { + switch (value.constructor) { + case Uint8ClampedArray: + case Uint8Array: + case Int8Array: + case Uint16Array: + case Int16Array: + case Float32Array: + case Int32Array: { + const valuesFlat = new(Type || value.constructor)(length); + utils$1.flattenTo(value, valuesFlat); + return valuesFlat; + } + default: { + const valuesFlat = new Float32Array(length); + utils$1.flattenTo(value, valuesFlat); + return valuesFlat; + } + } + } + } + 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; + } + } + getStringValueHandler() { + throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`); + } + getVariablePrecisionString() { + switch (this.tactic) { + case 'speed': + return 'lowp'; + case 'performance': + return 'highp'; + case 'balanced': + default: + return 'mediump'; + } + } } - static getMaxTextureSize() { - return testContext.getParameter(testContext.MAX_TEXTURE_SIZE); + 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); + } } - static lookupKernelValueType(type, dynamic, precision, value) { - return lookupKernelValueType(type, dynamic, precision, value); + 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); + } } - static get testCanvas() { - return testCanvas; + 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); + } } - static get testContext() { - return testContext; + class WebGLKernelValueHTMLImage extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + const { width, height } = value; + this.checkSize(width, height); + this.dimensions = [width, height, 1]; + this.requestTexture(); + this.textureSize = [width, height]; + this.uploadValue = value; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + getSource() { + return utils$1.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(); + return; + } + 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); + 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); + } + } + + class WebGLKernelValueDynamicHTMLImage extends WebGLKernelValueHTMLImage { + getSource() { + return utils$1.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); + } + } + + class WebGLKernelValueHTMLVideo extends WebGLKernelValueHTMLImage {} + + class WebGLKernelValueDynamicHTMLVideo extends WebGLKernelValueDynamicHTMLImage {} + + class WebGLKernelValueSingleInput extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + let [w, h, d] = value.size; + this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}.value, uploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.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(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(input.value, this.uploadValue); + 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); + 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); + } + } + + class WebGLKernelValueDynamicSingleInput extends WebGLKernelValueSingleInput { + getSource() { + return utils$1.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$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + class WebGLKernelValueUnsignedInput extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = this.getBitRatio(value); + const [w, h, d] = value.size; + this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); + this.textureSize = utils$1.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); + this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + this.TranserArrayType = this.getTransferArrayType(value.value); + this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength); + this.uploadValue = new Uint8Array(this.preUploadValue.buffer); + } + getStringValueHandler() { + return utils$1.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$1.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(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(input.value, this.preUploadValue); + 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); + 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); + } + } + + class WebGLKernelValueDynamicUnsignedInput extends WebGLKernelValueUnsignedInput { + getSource() { + return utils$1.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$1.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); + this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + 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); + } + } + + class WebGLKernelValueMemoryOptimizedNumberTexture extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + const [width, height] = value.size; + this.checkSize(width, height); + this.setupTexture(); + this.dimensions = value.dimensions; + this.textureSize = value.size; + this.uploadValue = value.texture; + this.forceUploadEachRun = true; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName}.texture;\n`; + } + getSource() { + return utils$1.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(); + return; + } + if (this.checkContext && inputTexture.context !== this.context) { + throw new Error(`Value ${this.name} (${this.type }) must be from same context`); + } + const { context: gl } = this; + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(inputTexture) { + this.checkSize(inputTexture.size[0], inputTexture.size[1]); + this.dimensions = inputTexture.dimensions; + this.textureSize = inputTexture.size; + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(inputTexture); + } + } + + class WebGLKernelValueNumberTexture extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + const [width, height] = value.size; + this.checkSize(width, height); + this.setupTexture(); + const { size: textureSize, dimensions } = value; + this.bitRatio = this.getBitRatio(value); + this.dimensions = dimensions; + this.textureSize = textureSize; + this.uploadValue = value.texture; + this.forceUploadEachRun = true; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName}.texture;\n`; + } + getSource() { + return utils$1.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(); + return; + } + if (this.checkContext && inputTexture.context !== this.context) { + throw new Error(`Value ${this.name} (${this.type}) must be from same context`); + } + const { context: gl } = this; + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicNumberTexture extends WebGLKernelValueNumberTexture { + getSource() { + return utils$1.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); + } + } + + class WebGLKernelValueSingleArray extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + this.dimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}, uploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.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(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(value, this.uploadValue); + 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); + 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); + } + } + + class WebGLKernelValueDynamicSingleArray extends WebGLKernelValueSingleArray { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.dimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + class WebGLKernelValueSingleArray1DI extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + this.setShape(value); + } + setShape(value) { + const valueDimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.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.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}, uploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.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(); + return; + } + const { context: gl } = this; + utils$1.flatten2dArrayTo(value, this.uploadValue); + 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); + 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); + } + } + + class WebGLKernelValueDynamicSingleArray1DI extends WebGLKernelValueSingleArray1DI { + getSource() { + return utils$1.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); + } + } + + class WebGLKernelValueSingleArray2DI extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + this.setShape(value); + } + setShape(value) { + const valueDimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.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.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}, uploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.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(); + return; + } + const { context: gl } = this; + utils$1.flatten3dArrayTo(value, this.uploadValue); + 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); + 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); + } + } + + class WebGLKernelValueDynamicSingleArray2DI extends WebGLKernelValueSingleArray2DI { + getSource() { + return utils$1.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); + } + } + + class WebGLKernelValueSingleArray3DI extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + this.setShape(value); + } + setShape(value) { + const valueDimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.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.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}, uploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.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(); + return; + } + const { context: gl } = this; + utils$1.flatten4dArrayTo(value, this.uploadValue); + 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); + 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); + } } - static get features() { - return features; + class WebGLKernelValueDynamicSingleArray3DI extends WebGLKernelValueSingleArray3DI { + getSource() { + return utils$1.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); + } } - static get fragmentShader() { - return fragmentShader; - } - static get vertexShader() { - return vertexShader; + class WebGLKernelValueSingleArray2 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); + } } - initContext() { - const settings = { - alpha: false, - depth: false, - antialias: false - }; - const context = this.canvas.getContext('webgl2', settings); - return context; + class WebGLKernelValueSingleArray3 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); + } } - 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'), - }; + class WebGLKernelValueSingleArray4 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); + } } - validateSettings(args) { - if (!this.validate) { - this.texSize = utils.getKernelTextureSize({ + class WebGLKernelValueUnsignedArray extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = this.getBitRatio(value); + this.dimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); + this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + this.TranserArrayType = this.getTransferArrayType(value); + this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength); + this.uploadValue = new Uint8Array(this.preUploadValue.buffer); + } + getStringValueHandler() { + return utils$1.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$1.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(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(value, this.preUploadValue); + 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); + 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); + } + } + + class WebGLKernelValueDynamicUnsignedArray extends WebGLKernelValueUnsignedArray { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.dimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); + this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + 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); + } + } + + const kernelValueMaps = { + unsigned: { + dynamic: { + 'Boolean': WebGLKernelValueBoolean, + 'Integer': WebGLKernelValueInteger, + 'Float': WebGLKernelValueFloat, + 'Array': WebGLKernelValueDynamicUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + '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': WebGLKernelValueMemoryOptimizedNumberTexture, + 'HTMLImage': WebGLKernelValueDynamicHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGLKernelValueBoolean, + 'Float': WebGLKernelValueFloat, + 'Integer': WebGLKernelValueInteger, + 'Array': WebGLKernelValueUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + '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': WebGLKernelValueDynamicMemoryOptimizedNumberTexture, + 'HTMLImage': WebGLKernelValueHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueHTMLVideo, + } + }, + single: { + dynamic: { + 'Boolean': WebGLKernelValueBoolean, + 'Integer': WebGLKernelValueInteger, + 'Float': WebGLKernelValueFloat, + 'Array': WebGLKernelValueDynamicSingleArray, + 'Array(2)': WebGLKernelValueSingleArray2, + 'Array(3)': WebGLKernelValueSingleArray3, + 'Array(4)': WebGLKernelValueSingleArray4, + '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, + 'HTMLImage': WebGLKernelValueDynamicHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGLKernelValueBoolean, + 'Float': WebGLKernelValueFloat, + 'Integer': WebGLKernelValueInteger, + 'Array': WebGLKernelValueSingleArray, + 'Array(2)': WebGLKernelValueSingleArray2, + 'Array(3)': WebGLKernelValueSingleArray3, + 'Array(4)': WebGLKernelValueSingleArray4, + '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, + 'HTMLImage': 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]; + } + + let isSupported = null; + let testCanvas = null; + let testContext = null; + let testExtensions = null; + let features = null; + const plugins$1 = [triangleNoise]; + 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 getFeatures() { + const isDrawBuffers = this.getIsDrawBuffers(); + return Object.freeze({ + isFloatRead: this.getIsFloatRead(), + isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), + isTextureFloat: this.getIsTextureFloat(), + isDrawBuffers, + kernelMap: isDrawBuffers, + channelCount: this.getChannelCount(), + }); + } + 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 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$1.systemEndianness(); + this.extensions = {}; + this.subKernelOutputTextures = null; + this.kernelArguments = null; + this.argumentTextureCount = 0; + this.constantTextureCount = 0; + this.compiledFragmentShader = null; + this.compiledVertexShader = null; + this.fragShader = null; + this.vertShader = null; + this.drawBuffersMap = null; + this.outputTexture = null; + this.maxTexSize = null; + this.switchingKernels = false; + this.onRequestSwitchKernel = 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$1.length; i++) { + const plugin = plugins$1[i]; + if (source.match(plugin.functionMatch)) { + pluginsToUse.push(plugin); + } + } + } else if (typeof source === 'object') { + if (settings.pluginNames) { + for (let i = 0; i < plugins$1.length; i++) { + const plugin = plugins$1[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$1.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$1.getVariableType(args[0], this.strictIntegers); + if (argType === 'Array') { + this.output = utils$1.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'); + } + if (this.precision === 'precision') { + this.precision = 'unsigned'; + console.warn('Cannot use graphical mode and single precision at the same time'); + } + this.texSize = utils$1.clone(this.output); + return; + } else if (this.precision === null && features.isTextureFloat) { + this.precision = 'single'; + } + this.texSize = utils$1.getKernelTextureSize({ optimizeFloatMemory: this.optimizeFloatMemory, precision: this.precision, }, this.output); - return; + this.checkTextureSize(); } - - const features = this.constructor.features; - 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'; + 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]; + } } - - if (this.fixIntegerDivisionAccuracy === null) { - this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate; - } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) { - this.fixIntegerDivisionAccuracy = false; + _oldtranslateSource() { + const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { + fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy + }); + const translatedSource = functionBuilder.getPrototypeString('kernel'); + if (!this.returnType) { + this.returnType = functionBuilder.getKernelResultType(); + } + let requiredChannels = 0; + const returnTypes = functionBuilder.getReturnTypes(); + for (let i = 0; i < returnTypes.length; i++) { + switch (returnTypes[i]) { + case 'Float': + case 'Number': + case 'Integer': + requiredChannels++; + break; + case 'Array(2)': + requiredChannels += 2; + break; + case 'Array(3)': + requiredChannels += 3; + break; + case 'Array(4)': + requiredChannels += 4; + break; + } + } + if (features && requiredChannels > features.channelCount) { + throw new Error('Too many channels!'); + } + return this.translatedSource = translatedSource; } - - 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'); + setupArguments(args) { + this.kernelArguments = []; + this.argumentTextureCount = 0; + const needsArgumentTypes = this.argumentTypes === null; + if (needsArgumentTypes) { + this.argumentTypes = []; } - - 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); + 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; + for (let index = 0; index < args.length; index++) { + const value = args[index]; + const name = this.argumentNames[index]; + let type; + if (needsArgumentTypes) { + type = utils$1.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: () => { + return this.context.createTexture(); + }, + onRequestIndex: () => { + return textureIndexes++; + }, + onUpdateValueMismatch: () => { + this.switchingKernels = true; + }, + onRequestContextHandle: () => { + return gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount++; + } + }); + this.kernelArguments.push(kernelArgument); + this.argumentSizes.push(kernelArgument.textureSize); + this.argumentBitRatios[index] = kernelArgument.bitRatio; } } - - if (this.graphical) { - if (this.output.length !== 2) { - throw new Error('Output must have 2 dimensions on graphical mode'); + setupConstants(args) { + const { context: gl } = this; + this.kernelConstants = []; + this.forceUploadKernelConstants = []; + let needsConstantTypes = this.constantTypes === null; + if (needsConstantTypes) { + this.constantTypes = {}; } - - if (this.precision === 'single') { - console.warn('Cannot use graphical mode and single precision at the same time'); - this.precision = 'unsigned'; + this.constantBitRatios = {}; + let textureIndexes = 0; + for (const name in this.constants) { + const value = this.constants[name]; + let type; + if (needsConstantTypes) { + type = utils$1.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.context.createTexture(); + }, + onRequestIndex: () => { + return textureIndexes++; + }, + onRequestContextHandle: () => { + return gl.TEXTURE0 + this.constantTextureCount++; + } + }); + this.constantBitRatios[name] = kernelValue.bitRatio; + this.kernelConstants.push(kernelValue); + if (kernelValue.forceUploadEachRun) { + this.forceUploadKernelConstants.push(kernelValue); + } } - - 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'); - if (!this.graphical && !this.returnType) { - this.returnType = functionBuilder.getKernelResultType(); + build() { + 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]; + 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]); + } + if (!this.immutable) { + this._setupOutputTexture(); + if ( + this.subKernels !== null && + this.subKernels.length > 0 + ) { + this._setupSubOutputTextures(); + } + } } - - if (this.subKernels && this.subKernels.length > 0) { + translateSource() { + const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { + fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy + }); + this.translatedSource = functionBuilder.getPrototypeString('kernel'); + 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, forceUploadKernelConstants } = this; + const texSize = this.texSize; + const gl = this.context; + 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]); + this.switchingKernels = false; + 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.outputTexture || this.immutable) { + this._setupOutputTexture(); + } + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + return new this.TextureConstructor({ + texture: this.outputTexture, + size: texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }); + } + 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._setupOutputTexture(); + } + if (this.subKernels !== null) { + if (this.immutable) { + this._setupSubOutputTextures(); + } + this.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(this.drawBuffersMap); + } + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + } + getOutputTexture() { + return this.outputTexture; + } + _setupOutputTexture() { + const gl = this.context; + const texSize = this.texSize; + const texture = this.outputTexture = this.context.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); + if (this.precision === 'single') { + if (this.pipeline) { + switch (this.returnType) { + case 'Number': + case 'Float': + case 'Integer': + if (this.optimizeFloatMemory) { + 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.FLOAT, null); + } + break; + case 'Array(2)': + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + break; + case 'Array(3)': + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + break; + case 'Array(4)': + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + break; + default: + if (!this.graphical) { + throw new Error('Unhandled return type'); + } + } + } else { + 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, gl.TEXTURE_2D, texture, 0); + } + _setupSubOutputTextures() { + const gl = this.context; + const texSize = this.texSize; + this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; + this.subKernelOutputTextures = []; for (let i = 0; i < this.subKernels.length; i++) { - const subKernel = this.subKernels[i]; - if (!subKernel.returnType) { - subKernel.returnType = functionBuilder.getSubKernelResultType(i); + const texture = this.context.createTexture(); + this.subKernelOutputTextures.push(texture); + 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); } } - } - - run() { - const { kernelArguments, texSize, forceUploadKernelConstants } = this; - const gl = this.context; - - 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); + getTextureCache(name) { + if (this.textureCache.hasOwnProperty(name)) { + return this.textureCache[name]; + } + return this.textureCache[name] = this.context.createTexture(); } - - this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]); - - this.switchingKernels = false; - for (let i = 0; i < forceUploadKernelConstants.length; i++) { - const constant = forceUploadKernelConstants[i]; - constant.updateValue(this.constants[constant.name]); - if (this.switchingKernels) return; + detachTextureCache(name) { + delete this.textureCache[name]; } - for (let i = 0; i < kernelArguments.length; i++) { - kernelArguments[i].updateValue(arguments[i]); - if (this.switchingKernels) return; + 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); } - - if (this.plugins) { - for (let i = 0; i < this.plugins.length; i++) { - const plugin = this.plugins[i]; - if (plugin.onBeforeRun) { - plugin.onBeforeRun(this); + 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); } - - if (this.graphical) { - if (this.pipeline) { - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - if (!this.outputTexture || this.immutable) { - this._setupOutputTexture(); + setUniform2f(name, value1, value2) { + if (this.uniform2fCache.hasOwnProperty(name)) { + const cache = this.uniform2fCache[name]; + if ( + value1 === cache[0] && + value2 === cache[1] + ) { + return; } - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - return new this.TextureConstructor({ - texture: this.outputTexture, - size: texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context - }); } - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - 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); + } + 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); + } + 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); + } + 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); + } + 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$1.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 div_with_int_check(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; +}` : + ''; + } + _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(''); } - - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - if (this.immutable) { - this._setupOutputTexture(); + _getInjectedNative() { + return this.injectedNative || ''; } - - if (this.subKernels !== null) { - if (this.immutable) { - this._setupSubOutputTextures(); + _getMainConstantsString() { + const result = []; + const { constants } = this; + if (constants) { + let i = 0; + for (const name in constants) { + result.push(this.kernelConstants[i++].getSource(this.constants[name])); + } } - gl.drawBuffers(this.drawBuffersMap); + return result.join(''); } - - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - } - - drawBuffers() { - this.context.drawBuffers(this.drawBuffersMap); - } - - getOutputTexture() { - return this.outputTexture; - } - - _setupOutputTexture() { - const { texSize } = this; - const gl = this.context; - const texture = this.outputTexture = gl.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); - if (this.precision === 'single') { - if (this.pipeline) { + getKernelString() { + let kernelResultDeclaration; + switch (this.returnType) { + case 'Array(2)': + kernelResultDeclaration = 'vec2 kernelResult'; + break; + case 'Array(3)': + kernelResultDeclaration = 'vec3 kernelResult'; + break; + case 'Array(4)': + kernelResultDeclaration = 'vec4 kernelResult'; + break; + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + kernelResultDeclaration = 'float kernelResult'; + break; + default: + if (this.graphical) { + kernelResultDeclaration = 'float kernelResult'; + } else { + throw new Error(`unrecognized output type "${ this.returnType }"`); + } + } + const result = []; + const subKernels = this.subKernels; + if (subKernels !== null) { + result.push( + kernelResultDeclaration + ); switch (this.returnType) { case 'Number': case 'Float': case 'Integer': - if (this.optimizeFloatMemory) { - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); - } else { - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.R32F, texSize[0], texSize[1]); + 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)': - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RG32F, texSize[0], texSize[1]); + 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(3)': case 'Array(4)': - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); + for (let i = 0; i < subKernels.length; i++) { + result.push( + `vec4 subKernelResult_${ subKernels[i].name }` + ); + } break; - default: - throw new Error('Unhandled return type'); } } else { - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); + result.push( + kernelResultDeclaration + ); } - } else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + return utils$1.linesToString(result) + this.translatedSource; } - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); - } - - _setupSubOutputTextures() { - const { texSize } = this; - const gl = this.context; - this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; - this.subKernelOutputTextures = []; - for (let i = 0; i < this.subKernels.length; i++) { - const texture = this.context.createTexture(); - this.subKernelOutputTextures.push(texture); - 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.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); + getMainResultGraphical() { + return utils$1.linesToString([ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' gl_FragColor = actualColor', + ]); } - } - - _getHeaderString() { - return ''; - } - - _getTextureCoordinate() { - const subKernels = this.subKernels; - if (subKernels === null || subKernels.length < 1) { - switch (this.tactic) { - case 'speed': - return 'in lowp vec2 vTexCoord;\n'; - case 'performance': - return 'in highp vec2 vTexCoord;\n'; - case 'balanced': - default: - return 'in mediump vec2 vTexCoord;\n'; - } - } else { - switch (this.tactic) { - case 'speed': - return 'out lowp vec2 vTexCoord;\n'; - case 'performance': - return 'out highp vec2 vTexCoord;\n'; - case 'balanced': + getMainResultPackedPixels() { + switch (this.returnType) { + case 'LiteralInteger': + case 'Number': + case 'Integer': + case 'Float': + return this.getMainResultKernelPackedPixels() + + this.getMainResultSubKernelPackedPixels(); default: - return 'out mediump vec2 vTexCoord;\n'; + throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`); } } - } - - _getMainArgumentsString(args) { - const result = []; - const argumentNames = this.argumentNames; - for (let i = 0; i < argumentNames.length; i++) { - result.push(this.kernelArguments[i].getSource(args[i])); + getMainResultKernelPackedPixels() { + return utils$1.linesToString([ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ` gl_FragData[0] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)` + ]); } - return result.join(''); - } - - getKernelString() { - let kernelResultDeclaration; - switch (this.returnType) { - case 'Array(2)': - kernelResultDeclaration = 'vec2 kernelResult'; - break; - case 'Array(3)': - kernelResultDeclaration = 'vec3 kernelResult'; - break; - case 'Array(4)': - kernelResultDeclaration = 'vec4 kernelResult'; - break; - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - kernelResultDeclaration = 'float kernelResult'; - break; - default: - if (this.graphical) { - kernelResultDeclaration = 'float 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 { - throw new Error(`unrecognized output type "${ this.returnType }"`); + result.push( + ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})` + ); } + } + return utils$1.linesToString(result); } - - const result = []; - const subKernels = this.subKernels; - if (subKernels !== null) { - result.push( - kernelResultDeclaration, - 'layout(location = 0) out vec4 data0' - ); - 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 }` - ); + 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`); } - } else { + return utils$1.linesToString(result); + } + getMainResultKernelMemoryOptimizedFloats(result, channel) { result.push( - 'out vec4 data0', - kernelResultDeclaration + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ` gl_FragData[0].${channel} = kernelResult`, ); } - - 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})` - ); + 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}`, + ); + } } } - 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'); - } + 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}`, + ); } - break; - default: - throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`); + } + return result; } - - 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 { + 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( - ` data${i + 1}.${channel} = subKernelResult_${subKernel.name}`, + ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, + ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, ); } + return result; } - } - - 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 { + 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( - ` data${i + 1}[0] = subKernelResult_${subKernel.name}`, + ` 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; } - 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]`, - ); + getMainResultKernelArray4Texture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' gl_FragData[0] = kernelResult', + ]; } - 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}`, - ); + 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; } - 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(); - return json; - } -} - -module.exports = { - WebGL2Kernel -}; -},{"../../utils":112,"../function-builder":9,"../web-gl/kernel":68,"./fragment-shader":70,"./function-node":71,"./kernel-value-maps":72,"./vertex-shader":104}],104:[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 -}; -},{}],105:[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]; -} -module.exports = GPU; -},{"./index":107}],106:[function(require,module,exports){ -const { gpuMock } = require('gpu-mock.js'); -const { utils } = require('./utils'); -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]); + 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)); } - - if (settings.nativeFunctions) { - for (const p in settings.nativeFunctions) { - this.addNativeFunction(p, settings.nativeFunctions[p]); + getVertexShader(args) { + if (this.compiledVertexShader !== null) { + return this.compiledVertexShader; } + return this.compiledVertexShader = this.replaceArtifacts(this.constructor.vertexShader, this._getVertShaderArtifactMap(args)); } - } - - 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; - } + toString() { + const setupContextString = utils$1.linesToString([ + `const gl = context`, + ]); + return glKernelString(this.constructor, arguments, this, setupContextString); + } + destroy(removeCanvasReferences) { + if (this.outputTexture) { + this.context.deleteTexture(this.outputTexture); } - if (Kernel === null) { - throw new Error('unknown Context'); + if (this.buffer) { + this.context.deleteBuffer(this.buffer); } - } 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 (this.framebuffer) { + this.context.deleteFramebuffer(this.framebuffer); } - if (!Kernel) { - throw new Error(`A requested mode of "${this.mode}" and is not supported`); + if (this.vertShader) { + this.context.deleteShader(this.vertShader); } - } else { - for (let i = 0; i < kernelOrder.length; i++) { - if (kernelOrder[i].isSupported) { - Kernel = kernelOrder[i]; - break; + if (this.fragShader) { + this.context.deleteShader(this.fragShader); + } + if (this.program) { + this.context.deleteProgram(this.program); + } + const keys = Object.keys(this.textureCache); + for (let i = 0; i < keys.length; i++) { + const name = keys[i]; + this.context.deleteTexture(this.textureCache[name]); + } + if (this.subKernelOutputTextures) { + for (let i = 0; i < this.subKernelOutputTextures.length; i++) { + this.context.deleteTexture(this.subKernelOutputTextures[i]); } } - if (!Kernel) { - Kernel = CPUKernel; + 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.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'); - } - - if (this.mode === 'dev') { - const devKernel = gpuMock(source, upgradeDeprecatedCreateKernelSettings(settings)); - this.kernels.push(devKernel); - return devKernel; + 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; } - - 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]); + static destroyContext(context) { + const extension = context.getExtension('WEBGL_lose_context'); + if (extension) { + extension.loseContext(); + } } - - function onRequestFallback(args) { - 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, - warnVarUsage: kernelRun.warnVarUsage, - }); - fallbackKernel.build.apply(fallbackKernel, args); - const result = fallbackKernel.run.apply(fallbackKernel, args); - kernelRun.replaceKernel(fallbackKernel); - return result; + toJSON() { + const json = super.toJSON(); + json.functionNodes = FunctionBuilder.fromKernel(this, WebGLFunctionNode).toJSON(); + return json; } + } - function onRequestSwitchKernel(args, kernel) { - 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; - } - } + class WebGL2FunctionNode extends WebGLFunctionNode { + astIdentifierExpression(idtNode, retArr) { + if (idtNode.type !== 'Identifier') { + throw this.astErrorOutput( + 'IdentifierExpression - not an Identifier', + idtNode + ); } - const signature = argumentTypes.join(','); - const existingKernel = switchableKernels[signature]; - if (existingKernel) { - existingKernel.run.apply(existingKernel, args); - if (existingKernel.renderKernels) { - return existingKernel.renderKernels(); + const type = this.getType(idtNode); + if (idtNode.name === 'Infinity') { + retArr.push('intBitsToFloat(2139095039)'); + } else if (type === 'Boolean') { + if (this.argumentNames.indexOf(idtNode.name) > -1) { + retArr.push(`bool(user_${idtNode.name})`); } else { - return existingKernel.renderOutput(); + retArr.push(`user_${idtNode.name}`); } - } - - const newKernel = switchableKernels[signature] = new kernel.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: 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, - warnVarUsage: kernel.warnVarUsage, - returnType: kernel.returnType, - onRequestFallback, - onRequestSwitchKernel, - }); - newKernel.build.apply(newKernel, args); - newKernel.run.apply(newKernel, args); - kernelRun.replaceKernel(newKernel); - if (newKernel.renderKernels) { - return newKernel.renderKernels(); } else { - return newKernel.renderOutput(); - } - } - 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 kernelRun = kernelRunShortcut(new this.Kernel(source, mergedSettings)); - - if (!this.canvas) { - this.canvas = kernelRun.canvas; + retArr.push(`user_${idtNode.name}`); + } + return retArr; } + } - if (!this.context) { - this.context = kernelRun.context; - } + const fragmentShader$1 = `#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; + +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); +} + +__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__; +}`; - this.kernels.push(kernelRun); + const vertexShader$1 = `#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; +}`; - return kernelRun; - } + class WebGL2KernelValueBoolean extends WebGLKernelValueBoolean {} - 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]; - } + class WebGL2KernelValueFloat extends WebGLKernelValueFloat {} - 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}`); - } + 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`; } - - const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings); - if (settings && typeof settings.argumentTypes === 'object') { - settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]); + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform1i(this.id, this.uploadValue = value); } + } - 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, - }); - } + class WebGL2KernelValueHTMLImage extends WebGLKernelValueHTMLImage { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.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]})`, + ]); } - const kernel = this.createKernel(fn, settingsCopy); - - return kernel; } - 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); + class WebGL2KernelValueDynamicHTMLImage extends WebGLKernelValueDynamicHTMLImage { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); } + } - return function() { - const texture = combinedKernel.apply(this, arguments); - if (texture.toArray) { - return texture.toArray(); + class WebGL2KernelValueHTMLImageArray extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.checkSize(value[0].width, value[0].height); + this.requestTexture(); + this.dimensions = [value[0].width, value[0].height, value.length]; + this.textureSize = [value[0].width, value[0].height]; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.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.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + 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] + ); } - return texture; - }; + this.kernel.setUniform1i(this.id, this.index); + } } - addFunction(source, settings) { - this.functions.push(utils.functionToIFunction(source, settings)); - return this; + 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); + } } - addNativeFunction(name, source, settings) { - if (this.kernels.length > 0) { - throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.'); + class WebGL2KernelValueHTMLVideo extends WebGL2KernelValueHTMLImage {} + + class WebGL2KernelValueDynamicHTMLVideo extends WebGL2KernelValueDynamicHTMLImage {} + + class WebGL2KernelValueSingleInput extends WebGLKernelValueSingleInput { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.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$1.flattenTo(input.value, this.uploadValue); + 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); + 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); } - settings = settings || {}; - const { argumentTypes, argumentNames } = this.Kernel.nativeFunctionArguments(source) || {}; - this.nativeFunctions.push({ - name, - source, - settings, - argumentTypes, - argumentNames, - returnType: settings.returnType || this.Kernel.nativeFunctionReturnType(source), - }); - return this; } - injectNative(source) { - this.injectedNative = source; - return this; + class WebGL2KernelValueDynamicSingleInput extends WebGL2KernelValueSingleInput { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.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$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } } - destroy() { - if (!this.kernels) return; - setTimeout(() => { - 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); - } - } - }, 0); + class WebGL2KernelValueUnsignedInput extends WebGLKernelValueUnsignedInput { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.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]})`, + ]); + } } -} - -function upgradeDeprecatedCreateKernelSettings(settings) { - if (!settings) { - return {}; + class WebGL2KernelValueDynamicUnsignedInput extends WebGLKernelValueDynamicUnsignedInput { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } } - 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); + class WebGL2KernelValueMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture { + getSource() { + const { id, sizeId, textureSize, dimensionsId, dimensions } = this; + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform sampler2D ${id}`, + `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`, + `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`, + ]); + } } - return upgradedSettings; -} - -module.exports = { - GPU, - kernelOrder, - kernelTypes -}; -},{"./backend/cpu/kernel":8,"./backend/headless-gl/kernel":33,"./backend/web-gl/kernel":68,"./backend/web-gl2/kernel":103,"./kernel-run-shortcut":109,"./utils":112,"gpu-mock.js":4}],107:[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'); - -module.exports = { - alias, - CPUFunctionNode, - CPUKernel, - GPU, - FunctionBuilder, - FunctionNode, - HeadlessGLKernel, - Input, - input, - Texture, - utils, - - WebGL2FunctionNode, - WebGL2Kernel, - webGL2KernelValueMaps, - - WebGLFunctionNode, - WebGLKernel, - webGLKernelValueMaps, - - GLKernel, - Kernel, - FunctionTracer, -}; -},{"./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":33,"./backend/kernel":35,"./backend/web-gl/function-node":37,"./backend/web-gl/kernel":68,"./backend/web-gl/kernel-value-maps":38,"./backend/web-gl2/function-node":71,"./backend/web-gl2/kernel":103,"./backend/web-gl2/kernel-value-maps":72,"./gpu":106,"./input":108,"./texture":111,"./utils":112}],108:[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]); - } + class WebGL2KernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueDynamicMemoryOptimizedNumberTexture { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); } + } - 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}`); - } + class WebGL2KernelValueNumberTexture extends WebGLKernelValueNumberTexture { + getSource() { + const { id, sizeId, textureSize, dimensionsId, dimensions } = this; + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${id}`, + `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`, + `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`, + ]); } - } - 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; + class WebGL2KernelValueDynamicNumberTexture extends WebGLKernelValueDynamicNumberTexture { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); } } -} - -function input(value, size) { - return new Input(value, size); -} -module.exports = { - Input, - input -}; -},{"./utils":112}],109:[function(require,module,exports){ -const { utils } = require('./utils'); - -function kernelRunShortcut(kernel) { - let run = function() { - kernel.build.apply(kernel, arguments); - if (kernel.renderKernels) { - run = function() { - kernel.run.apply(kernel, arguments); - if (kernel.switchingKernels) { - kernel.switchingKernels = false; - return kernel.onRequestSwitchKernel(arguments, kernel); - } - return kernel.renderKernels(); - }; - } else if (kernel.renderOutput) { - run = function() { - kernel.run.apply(kernel, arguments); - if (kernel.switchingKernels) { - kernel.switchingKernels = false; - return kernel.onRequestSwitchKernel(arguments, kernel); - } - return kernel.renderOutput(); - }; - } else { - run = function() { - return kernel.run.apply(kernel, arguments); - }; + class WebGL2KernelValueSingleArray extends WebGLKernelValueSingleArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.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]})`, + ]); } - 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); + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; } - }); - }; - shortcut.replaceKernel = function(replacementKernel) { - kernel = replacementKernel; - bindKernelToShortcut(kernel, shortcut); - shortcut.kernel = kernel; - }; + const { context: gl } = this; + utils$1.flattenTo(value, this.uploadValue); + 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); + 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); + } + } - bindKernelToShortcut(kernel, shortcut); - shortcut.kernel = kernel; - return shortcut; -} + class WebGL2KernelValueDynamicSingleArray extends WebGL2KernelValueSingleArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.dimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } -function bindKernelToShortcut(kernel, shortcut) { - 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() { - kernel[property].apply(kernel, arguments); - return shortcut; - }; - } else { - if (property === 'toString') { - shortcut.toString = function() { - return kernel.toString.apply(kernel, arguments); - }; - } else { - shortcut[property] = kernel[property].bind(kernel); - } + class WebGL2KernelValueSingleArray1DI extends WebGLKernelValueSingleArray1DI { + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; } - } else { - shortcut.__defineGetter__(property, () => { - return kernel[property]; - }); - shortcut.__defineSetter__(property, (value) => { - kernel[property] = value; - }); + const { context: gl } = this; + utils$1.flattenTo(value, this.uploadValue); + 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); + 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 = { - kernelRunShortcut -}; -},{"./utils":112}],110:[function(require,module,exports){ -const source = ` - -uniform highp float triangle_noise_seed; -highp float triangle_noise_shift = 0.000001; - -//https://www.shadertoy.com/view/4t2SDh -//note: uniformly distributed, normalized rand, [0;1[ -float nrand( vec2 n ) -{ - return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453); -} -//note: remaps v to [0;1] in interval [a;b] -float remap( float a, float b, float v ) -{ - return clamp( (v-a) / (b-a), 0.0, 1.0 ); -} - -float n4rand( vec2 n ) -{ - float t = fract( triangle_noise_seed + triangle_noise_shift ); - float nrnd0 = nrand( n + 0.07*t ); - float nrnd1 = nrand( n + 0.11*t ); - float nrnd2 = nrand( n + 0.13*t ); - float nrnd3 = nrand( n + 0.17*t ); - float result = (nrnd0+nrnd1+nrnd2+nrnd3) / 4.0; - triangle_noise_shift = result + 0.000001; - return result; -}`; - -const name = 'triangle-noise-noise'; -const functionMatch = 'Math.random()'; - -const functionReplace = 'n4rand(vTexCoord)'; - -const functionReturnType = 'Number'; - -const onBeforeRun = (kernel) => { - kernel.setUniform1f('triangle_noise_seed', Math.random()); -}; - -module.exports = { - name, - onBeforeRun, - functionMatch, - functionReplace, - functionReturnType, - source -}; -},{}],111:[function(require,module,exports){ -class Texture { - constructor(settings) { - const { - texture, - size, - dimensions, - output, - context, - type = 'NumberTexture', - } = settings; - if (!output) throw new Error('settings property "output" required.'); - if (!context) throw new Error('settings property "context" required.'); - this.texture = texture; - this.size = size; - this.dimensions = dimensions; - this.output = output; - this.context = context; - this.kernel = null; - this.type = type; + class WebGL2KernelValueDynamicSingleArray1DI extends WebGL2KernelValueSingleArray1DI { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.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); + } } - toArray() { - throw new Error(`Not implemented on ${this.constructor.name}`); + class WebGL2KernelValueSingleArray2DI extends WebGLKernelValueSingleArray2DI { + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(value, this.uploadValue); + 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); + 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); + } } - delete() { - return this.context.deleteTexture(this.texture); + class WebGL2KernelValueDynamicSingleArray2DI extends WebGL2KernelValueSingleArray2DI { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.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 = { - Texture -}; -},{}],112:[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'); + class WebGL2KernelValueSingleArray3DI extends WebGLKernelValueSingleArray3DI { + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(value, this.uploadValue); + 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); + 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); + } + } + + class WebGL2KernelValueDynamicSingleArray3DI extends WebGL2KernelValueSingleArray3DI { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.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); + } + } + + class WebGL2KernelValueSingleArray2 extends WebGLKernelValueSingleArray2 {} + + class WebGL2KernelValueSingleArray3 extends WebGLKernelValueSingleArray3 {} + + class WebGL2KernelValueSingleArray4 extends WebGLKernelValueSingleArray4 {} + + class WebGL2KernelValueUnsignedArray extends WebGLKernelValueUnsignedArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.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]})`, + ]); + } + } + + class WebGL2KernelValueDynamicUnsignedArray extends WebGLKernelValueDynamicUnsignedArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + } + + const kernelValueMaps$1 = { + unsigned: { + dynamic: { + 'Boolean': WebGL2KernelValueBoolean, + 'Integer': WebGL2KernelValueInteger, + 'Float': WebGL2KernelValueFloat, + 'Array': WebGL2KernelValueDynamicUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + '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, + 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, + 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGL2KernelValueBoolean, + 'Float': WebGL2KernelValueFloat, + 'Integer': WebGL2KernelValueInteger, + 'Array': WebGL2KernelValueUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + '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, + 'HTMLImage': WebGL2KernelValueHTMLImage, + 'HTMLImageArray': WebGL2KernelValueHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueHTMLVideo, + } + }, + single: { + dynamic: { + 'Boolean': WebGL2KernelValueBoolean, + 'Integer': WebGL2KernelValueInteger, + 'Float': WebGL2KernelValueFloat, + 'Array': WebGL2KernelValueDynamicSingleArray, + 'Array(2)': WebGL2KernelValueSingleArray2, + 'Array(3)': WebGL2KernelValueSingleArray3, + 'Array(4)': WebGL2KernelValueSingleArray4, + '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, + 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, + 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGL2KernelValueBoolean, + 'Float': WebGL2KernelValueFloat, + 'Integer': WebGL2KernelValueInteger, + 'Array': WebGL2KernelValueSingleArray, + 'Array(2)': WebGL2KernelValueSingleArray2, + 'Array(3)': WebGL2KernelValueSingleArray3, + 'Array(4)': WebGL2KernelValueSingleArray4, + '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, + 'HTMLImage': WebGL2KernelValueHTMLImage, + 'HTMLImageArray': WebGL2KernelValueHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueHTMLVideo, + } + }, + }; + function lookupKernelValueType$1(type, dynamic, precision, value) { + if (!type) { + throw new Error('type missing'); } - return false; - }, - - getFunctionNameFromString(funcStr) { - return FUNCTION_NAME.exec(funcStr)[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 = []; + if (!dynamic) { + throw new Error('dynamic missing'); + } + if (!precision) { + throw new Error('precision missing'); + } + if (value.type) { + type = value.type; + } + const types = kernelValueMaps$1[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]; + } + + let isSupported$1 = null; + let testCanvas$1 = null; + let testContext$1 = null; + let testExtensions$1 = null; + let features$1 = null; + class WebGL2Kernel extends WebGLKernel { + static get isSupported() { + if (isSupported$1 !== null) { + return isSupported$1; + } + this.setupFeatureChecks(); + isSupported$1 = this.isContextMatch(testContext$1); + return isSupported$1; + } + static setupFeatureChecks() { + if (typeof document !== 'undefined') { + testCanvas$1 = document.createElement('canvas'); + } else if (typeof OffscreenCanvas !== 'undefined') { + testCanvas$1 = new OffscreenCanvas(0, 0); + } + if (!testCanvas$1) return; + testContext$1 = testCanvas$1.getContext('webgl2'); + if (!testContext$1 || !testContext$1.getExtension) return; + testExtensions$1 = { + EXT_color_buffer_float: testContext$1.getExtension('EXT_color_buffer_float'), + OES_texture_float_linear: testContext$1.getExtension('OES_texture_float_linear'), + }; + features$1 = this.getFeatures(); } - 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; + static isContextMatch(context) { + if (typeof WebGL2RenderingContext !== 'undefined') { + return context instanceof WebGL2RenderingContext; } + return false; } - - return temp; - }, - - isArray(array) { - return !isNaN(array.length); - }, - - getVariableType(value, strictIntegers) { - if (utils.isArray(value)) { - if (value[0].nodeName === 'IMG') { - return 'HTMLImageArray'; - } - return 'Array'; + static getFeatures() { + return Object.freeze({ + isFloatRead: this.getIsFloatRead(), + isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), + kernelMap: true, + isTextureFloat: true, + channelCount: this.getChannelCount(), + maxTextureSize: this.getMaxTextureSize(), + }); } - - 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'; + static getIsTextureFloat() { + return true; } - switch (value.nodeName) { - case 'IMG': - return 'HTMLImage'; - case 'VIDEO': - return 'HTMLVideo'; + static getIsIntegerDivisionAccurate() { + return super.getIsIntegerDivisionAccurate(); } - if (value.hasOwnProperty('type')) { - return value.type; + static getChannelCount() { + return testContext$1.getParameter(testContext$1.MAX_DRAW_BUFFERS); } - 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); + static getMaxTextureSize() { + return testContext$1.getParameter(testContext$1.MAX_TEXTURE_SIZE); } - if (h > 1 && w * h === texelCount) { - return new Int32Array([w, h]); + static lookupKernelValueType(type, dynamic, precision, value) { + return lookupKernelValueType$1(type, dynamic, precision, value); } - 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}`); + static get testCanvas() { + return testCanvas$1; } - - if (pad) { - ret = Array.from(ret); - while (ret.length < 3) { - ret.push(1); - } + static get testContext() { + return testContext$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; + static get features() { + return features$1; } - }, - - 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; + static get fragmentShader() { + return fragmentShader$1; + } + static get vertexShader() { + return vertexShader$1; + } + initContext() { + const settings = { + alpha: false, + depth: false, + antialias: false + }; + const context = this.canvas.getContext('webgl2', settings); + return context; + } + 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$1.getKernelTextureSize({ + optimizeFloatMemory: this.optimizeFloatMemory, + precision: this.precision, + }, this.output); + return; + } + const features = this.constructor.features; + 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$1.getVariableType(args[0], this.strictIntegers); + switch (argType) { + case 'Array': + this.output = utils$1.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$1.clone(this.output); + return; + } else if (!this.graphical && this.precision === null && features.isTextureFloat) { + this.precision = 'single'; } + this.texSize = utils$1.getKernelTextureSize({ + optimizeFloatMemory: this.optimizeFloatMemory, + precision: this.precision, + }, this.output); + this.checkTextureSize(); } - }, - - 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; + translateSource() { + const functionBuilder = FunctionBuilder.fromKernel(this, WebGL2FunctionNode, { + fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy + }); + this.translatedSource = functionBuilder.getPrototypeString('kernel'); + 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); + } } } } - }, - - 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); + run() { + const { kernelArguments, texSize, forceUploadKernelConstants } = this; + const gl = this.context; + 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]); + this.switchingKernels = false; + 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.outputTexture || this.immutable) { + this._setupOutputTexture(); + } + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + return new this.TextureConstructor({ + texture: this.outputTexture, + size: texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context + }); + } + 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._setupOutputTexture(); + } + if (this.subKernels !== null) { + if (this.immutable) { + this._setupSubOutputTextures(); + } + gl.drawBuffers(this.drawBuffersMap); + } + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + } + drawBuffers() { + this.context.drawBuffers(this.drawBuffersMap); + } + getOutputTexture() { + return this.outputTexture; + } + _setupOutputTexture() { + const { texSize } = this; + const gl = this.context; + const texture = this.outputTexture = gl.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); + if (this.precision === 'single') { + if (this.pipeline) { + switch (this.returnType) { + case 'Number': + case 'Float': + case 'Integer': + if (this.optimizeFloatMemory) { + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); + } else { + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.R32F, texSize[0], texSize[1]); + } + break; + case 'Array(2)': + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RG32F, texSize[0], texSize[1]); + break; + case 'Array(3)': + case 'Array(4)': + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); + break; + default: + throw new Error('Unhandled return type'); + } } else { - utils.flatten3dArrayTo(array, target); + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); } } else { - utils.flatten2dArrayTo(array, target); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); } - } 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)); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); } - 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]); + _setupSubOutputTextures() { + const { texSize } = this; + const gl = this.context; + this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; + this.subKernelOutputTextures = []; + for (let i = 0; i < this.subKernels.length; i++) { + const texture = this.context.createTexture(); + this.subKernelOutputTextures.push(texture); + 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.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); } - 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'; + _getHeaderString() { + return ''; } - }, - 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.`); + _getTextureCoordinate() { + const subKernels = this.subKernels; + if (subKernels === null || subKernels.length < 1) { + switch (this.tactic) { + case 'speed': + return 'in lowp vec2 vTexCoord;\n'; + case 'performance': + return 'in highp vec2 vTexCoord;\n'; + case 'balanced': + default: + return 'in mediump vec2 vTexCoord;\n'; + } + } else { + switch (this.tactic) { + case 'speed': + return 'out lowp vec2 vTexCoord;\n'; + case 'performance': + return 'out highp vec2 vTexCoord;\n'; + case 'balanced': + default: + return 'out mediump vec2 vTexCoord;\n'; + } + } } - }, - functionToIFunction(source, settings) { - settings = 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 || []; + _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(''); } - - return { - source: sourceString, - argumentTypes, - returnType: settings.returnType || null, - }; - }, - 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); + getKernelString() { + let kernelResultDeclaration; + switch (this.returnType) { + case 'Array(2)': + kernelResultDeclaration = 'vec2 kernelResult'; + break; + case 'Array(3)': + kernelResultDeclaration = 'vec3 kernelResult'; + break; + case 'Array(4)': + kernelResultDeclaration = 'vec4 kernelResult'; + break; + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + kernelResultDeclaration = 'float kernelResult'; + break; + default: + if (this.graphical) { + kernelResultDeclaration = 'float kernelResult'; + } else { + throw new Error(`unrecognized output type "${ this.returnType }"`); + } + } + const result = []; + const subKernels = this.subKernels; + if (subKernels !== null) { + result.push( + kernelResultDeclaration, + 'layout(location = 0) out vec4 data0' + ); + 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 }` + ); + } + } else { + result.push( + 'out vec4 data0', + kernelResultDeclaration + ); + } + return utils$1.linesToString(result) + this.translatedSource; } - 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); + getMainResultGraphical() { + return utils$1.linesToString([ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' data0 = actualColor', + ]); } - 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); + 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`); } - 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); + getMainResultKernelPackedPixels() { + return utils$1.linesToString([ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ` data0 = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)` + ]); } - 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); + 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$1.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`); } - zResults[z] = yResults; + return utils$1.linesToString(result); } - 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; + getMainResultKernelMemoryOptimizedFloats(result, channel) { + result.push( + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ` data0.${channel} = kernelResult`, + ); } - 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; + 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}`, + ); } - 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; + getMainResultKernelNumberTexture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' data0[0] = kernelResult', + ]; } - 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); + 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}`, + ); } - yResults[y] = xResults; } - zResults[z] = yResults; + return result; } - 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); + 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]`, + ); } - yResults[y] = xResults; + return result; } - 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; + 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]`, + ); } - zResults[z] = yResults; + return result; } - 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); + 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}`, + ); } - yResults[y] = xResults; + return result; } - 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); + 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(); + return json; + } + } + + function kernelRunShortcut(kernel) { + let run = function() { + kernel.build.apply(kernel, arguments); + if (kernel.renderKernels) { + run = function() { + kernel.run.apply(kernel, arguments); + if (kernel.switchingKernels) { + kernel.switchingKernels = false; + return kernel.onRequestSwitchKernel(arguments, kernel); + } + return kernel.renderKernels(); + }; + } else if (kernel.renderOutput) { + run = function() { + kernel.run.apply(kernel, arguments); + if (kernel.switchingKernels) { + kernel.switchingKernels = false; + return kernel.onRequestSwitchKernel(arguments, kernel); + } + return kernel.renderOutput(); + }; + } else { + run = function() { + return kernel.run.apply(kernel, arguments); + }; + } + 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); } - yResults[y] = xResults; + }); + }; + shortcut.replaceKernel = function(replacementKernel) { + kernel = replacementKernel; + bindKernelToShortcut(kernel, shortcut); + shortcut.kernel = kernel; + }; + bindKernelToShortcut(kernel, shortcut); + shortcut.kernel = kernel; + return shortcut; + } + function bindKernelToShortcut(kernel, shortcut) { + const properties = utils$1.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() { + kernel[property].apply(kernel, arguments); + return shortcut; + }; + } else { + if (property === 'toString') { + shortcut.toString = function() { + return kernel.toString.apply(kernel, arguments); + }; + } else { + shortcut[property] = kernel[property].bind(kernel); + } + } + } else { + shortcut.__defineGetter__(property, () => { + return kernel[property]; + }); + shortcut.__defineSetter__(property, (value) => { + kernel[property] = value; + }); } - 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 = []; + } - function flatten(ast) { - if (Array.isArray(ast)) { - const results = []; - for (let i = 0; i < ast.length; i++) { - results.push(flatten(ast[i])); + const kernelOrder = [ WebGL2Kernel, WebGLKernel ]; + const kernelTypes = [ 'gpu', 'cpu' ]; + const internalKernels = { + '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 false; + } + static get isCanvasSupported() { + return typeof HTMLCanvasElement !== 'undefined'; + } + static get isGPUHTMLImageArraySupported() { + return WebGL2Kernel.isSupported; + } + static get isSinglePrecisionSupported() { + return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.isFloatRead && Kernel.features.isTextureFloat); + } + constructor(settings) { + settings = settings || {}; + this.canvas = settings.canvas || null; + this.context = settings.context || null; + this.mode = settings.mode; + this.Kernel = null; + this.kernels = []; + this.functions = []; + this.nativeFunctions = []; + this.injectedNative = null; + if (this.mode === 'dev') return; + this.chooseKernel(); + if (settings.functions) { + for (let i = 0; i < settings.functions.length; i++) { + this.addFunction(settings.functions[i]); } - return results.join(''); } - switch (ast.type) { - case 'Program': - return flatten(ast.body); - case 'FunctionDeclaration': - return `function ${ast.id.name}(${ast.params.map(flatten).join(', ')}) ${ flatten(ast.body) }`; - case 'BlockStatement': { - const result = []; - for (let i = 0; i < ast.body.length; i++) { - result.push(flatten(ast.body[i]), ';\n'); - } - return `{\n${result.join('')}}`; + if (settings.nativeFunctions) { + for (const p in settings.nativeFunctions) { + this.addNativeFunction(p, settings.nativeFunctions[p]); } - case 'VariableDeclaration': - switch (ast.declarations[0].id.type) { - case 'ObjectPattern': { - const source = flatten(ast.declarations[0].init); - const properties = ast.declarations.map(declaration => declaration.id.properties.map(flatten))[0]; - if (/this/.test(source)) { - const result = []; - const lookups = properties.map(thisLookup); - for (let i = 0; i < lookups.length; i++) { - const lookup = lookups[i]; - if (lookup === null) continue; - const property = properties[i]; - result.push(`${ast.kind} ${ property } = ${ lookup };\n`); - } - - return result.join(''); - } - return `${ast.kind} { ${properties} } = ${source}`; + } + } + getValidate() { + return validate; + } + 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`); } - case 'ArrayPattern': - return `${ast.kind} [ ${ ast.declarations.map(declaration => flatten(declaration.id)).join(', ') } ] = ${flatten(ast.declarations[0].init)}`; + Kernel = ExternalKernel; + break; } - if (doNotDefine && doNotDefine.indexOf(ast.declarations[0].id.name) !== -1) { - return ''; + } + 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]; } - return `${ast.kind} ${ast.declarations[0].id.name} = ${flatten(ast.declarations[0].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(', ')})`; + } else if (this.mode === 'gpu') { + for (let i = 0; i < kernelOrder.length; i++) { + if (kernelOrder[i].isSupported) { + Kernel = kernelOrder[i]; + break; + } } - 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(', ')})`; + } 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 (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(', ')})`; + } + 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' && !isFunction(source) && typeof source !== 'string') { + throw new Error('source parameter not a function'); + } + if (this.mode === 'dev') { + const devKernel = gpuMock_js_1(source, upgradeDeprecatedCreateKernelSettings(settings)); + this.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) { + 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, + warnVarUsage: kernelRun.warnVarUsage, + }); + fallbackKernel.build.apply(fallbackKernel, args); + const result = fallbackKernel.run.apply(fallbackKernel, args); + kernelRun.replaceKernel(fallbackKernel); + return result; + } + function onRequestSwitchKernel(args, kernel) { + 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 { - throw new Error('unknown ast.callee'); + switch (type) { + case 'Number': + case 'Integer': + case 'Float': + case 'ArrayTexture(1)': + argumentTypes[i] = getVariableType(arg); + break; + default: + argumentTypes[i] = type; + } } } - 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)}`; + const signature = argumentTypes.join(','); + const existingKernel = switchableKernels[signature]; + if (existingKernel) { + existingKernel.run.apply(existingKernel, args); + if (existingKernel.renderKernels) { + return existingKernel.renderKernels(); } else { - return `${flatten(ast.argument)} ${ast.operator}`; + return existingKernel.renderOutput(); } - case 'ExpressionStatement': - return `(${flatten(ast.expression)})`; - 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); - } + } + const newKernel = switchableKernels[signature] = new kernel.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: 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, + warnVarUsage: kernel.warnVarUsage, + returnType: kernel.returnType, + onRequestFallback, + onRequestSwitchKernel, + }); + newKernel.build.apply(newKernel, args); + newKernel.run.apply(newKernel, args); + kernelRun.replaceKernel(newKernel); + if (newKernel.renderKernels) { + return newKernel.renderKernels(); + } else { + return newKernel.renderOutput(); + } + } + 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 kernelRun = kernelRunShortcut(new this.Kernel(source, mergedSettings)); + if (!this.canvas) { + this.canvas = kernelRun.canvas; + } + if (!this.context) { + this.context = kernelRun.context; + } + this.kernels.push(kernelRun); + return kernelRun; + } + 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]; } - throw new Error(`unhandled ast.type of ${ ast.type }`); + 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 = 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 = getFunctionNameFromString(source); + settingsCopy.subKernels.push({ + name: name || p, + source, + property: p, + }); + } + } + const kernel = this.createKernel(fn, settingsCopy); + return kernel; } - 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; + 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(); } - flattenedFunctionDependencies.push(utils.flattenFunctionToString(functionDependency, settings) + ';\n'); + return texture; + }; + } + addFunction(source, settings) { + this.functions.push(functionToIFunction(source, settings)); + return this; + } + addNativeFunction(name, source, settings) { + if (this.kernels.length > 0) { + throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.'); } - return flattenedFunctionDependencies.join('') + result; + settings = settings || {}; + const { argumentTypes, argumentNames } = this.Kernel.nativeFunctionArguments(source) || {}; + this.nativeFunctions.push({ + name, + source, + settings, + argumentTypes, + argumentNames, + returnType: settings.returnType || this.Kernel.nativeFunctionReturnType(source), + }); + return this; + } + injectNative(source) { + this.injectedNative = source; + return this; + } + destroy() { + if (!this.kernels) return; + setTimeout(() => { + 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); + } + } + }, 0); } - return result; - }, - - splitHTMLImageToRGB: (image, mode) => { - const gpu = new GPU({ mode }); - - 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: ['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: ['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: ['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: ['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: (rgba, width, height, mode) => { - const { GPU } = require('./gpu.js'); - - const visualGPUR = new GPU({ mode }); - const visualKernelR = visualGPUR.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 visualGPUG = new GPU({ mode }); - const visualKernelG = visualGPUG.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 visualGPUB = new GPU({ mode }); - const visualKernelB = visualGPUB.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 visualGPUA = new GPU({ mode }); - const visualKernelA = visualGPUA.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); - - visualGPUR.destroy(); - visualGPUG.destroy(); - visualGPUB.destroy(); - visualGPUA.destroy(); - - return [ - visualKernelR.canvas, - visualKernelG.canvas, - visualKernelB.canvas, - visualKernelA.canvas, - ]; } -}; + function upgradeDeprecatedCreateKernelSettings(settings) { + if (!settings) { + return {}; + } + const upgradedSettings = Object.assign({}, settings); + if (settings.hasOwnProperty('floatOutput')) { + warnDeprecated('setting', 'floatOutput', 'precision'); + upgradedSettings.precision = settings.floatOutput ? 'single' : 'unsigned'; + } + if (settings.hasOwnProperty('outputToTexture')) { + warnDeprecated('setting', 'outputToTexture', 'pipeline'); + upgradedSettings.pipeline = Boolean(settings.outputToTexture); + } + if (settings.hasOwnProperty('outputImmutable')) { + warnDeprecated('setting', 'outputImmutable', 'immutable'); + upgradedSettings.immutable = Boolean(settings.outputImmutable); + } + if (settings.hasOwnProperty('floatTextures')) { + warnDeprecated('setting', 'floatTextures', 'optimizeFloatMemory'); + upgradedSettings.optimizeFloatMemory = Boolean(settings.floatTextures); + } + return upgradedSettings; + } -const _systemEndianness = utils.getSystemEndianness(); + function alias(name, source) { + const fnString = source.toString(); + return new Function(`return function ${ name } (${ utils$1.getArgumentNamesFromString(fnString).join(', ') }) { + ${ utils$1.getFunctionBodyFromString(fnString) } +}`)(); + } -module.exports = { - utils -}; -},{"./gpu.js":106,"./input":108,"./texture":111,"acorn":1}]},{},[105])(105) -}); + class HeadlessGLKernel extends WebGLKernel { + static get isSupported() { return false } + static isContextMatch() { return false } + static getIsTextureFloat() { return false } + static getIsDrawBuffers() { return false } + static getChannelCount() { return 1 } + static get testCanvas() { return null } + static get testContext() { return null } + static get features() { return null } + static setupFeatureChecks() {} + static destroyContext() {} + initCanvas() { return {} } + initContext() { return null } + toString() { return '' } + initExtensions() {} + build() {} + destroyExtensions() {} + setOutput() {} + static getFeatures() { + return Object.freeze({ + isFloatRead: false, + isIntegerDivisionAccurate: false, + isTextureFloat: false, + isDrawBuffers: false, + kernelMap: false, + channelCount: 1, + }); + } + }const lib = GPU; + lib.alias = alias; + lib.CPUFunctionNode = CPUFunctionNode; + lib.CPUKernel = CPUKernel; + lib.FunctionBuilder = FunctionBuilder; + lib.FunctionNode = FunctionNode; + lib.HeadlessGLKernel = HeadlessGLKernel; + lib.Input = Input; + lib.input = input; + lib.Texture = Texture; + lib.utils = { ...common, ...utils$1 }; + lib.WebGL2FunctionNode = WebGL2FunctionNode; + lib.WebGL2Kernel = WebGL2Kernel; + lib.WebGLFunctionNode = WebGLFunctionNode; + lib.WebGLKernel = WebGLKernel; + lib.GLKernel = GLKernel; + lib.Kernel = Kernel; + + return lib; + +}()); +//# sourceMappingURL=gpu-browser.js.map diff --git a/dist/gpu-browser.js.map b/dist/gpu-browser.js.map new file mode 100644 index 00000000..ac7ddb42 --- /dev/null +++ b/dist/gpu-browser.js.map @@ -0,0 +1 @@ +{"version":3,"file":"gpu-browser.js","sources":["../node_modules/gpu-mock.js/index.js","../src/common.js","../src/input.js","../node_modules/acorn/dist/acorn.es.js","../src/texture.js","../src/utils.js","../src/backend/kernel.js","../src/backend/function-builder.js","../src/backend/function-tracer.js","../src/backend/function-node.js","../src/backend/cpu/function-node.js","../src/backend/cpu/kernel-string.js","../src/backend/cpu/kernel.js","../src/backend/gl/texture/float.js","../src/backend/gl/texture/array-2-float.js","../src/backend/gl/texture/array-2-float-2d.js","../src/backend/gl/texture/array-2-float-3d.js","../src/backend/gl/texture/array-3-float.js","../src/backend/gl/texture/array-3-float-2d.js","../src/backend/gl/texture/array-3-float-3d.js","../src/backend/gl/texture/array-4-float.js","../src/backend/gl/texture/array-4-float-2d.js","../src/backend/gl/texture/array-4-float-3d.js","../src/backend/gl/texture/float-2d.js","../src/backend/gl/texture/float-3d.js","../src/backend/gl/texture/memory-optimized.js","../src/backend/gl/texture/memory-optimized-2d.js","../src/backend/gl/texture/memory-optimized-3d.js","../src/backend/gl/texture/unsigned.js","../src/backend/gl/texture/unsigned-2d.js","../src/backend/gl/texture/unsigned-3d.js","../src/backend/gl/texture/graphical.js","../src/backend/gl/kernel.js","../src/backend/web-gl/function-node.js","../src/plugins/triangle-noise.js","../src/backend/web-gl/fragment-shader.js","../src/backend/web-gl/vertex-shader.js","../node_modules/gl-wiretap/index.js","../src/backend/gl/kernel-string.js","../src/backend/kernel-value.js","../src/backend/web-gl/kernel-value/index.js","../src/backend/web-gl/kernel-value/boolean.js","../src/backend/web-gl/kernel-value/float.js","../src/backend/web-gl/kernel-value/integer.js","../src/backend/web-gl/kernel-value/html-image.js","../src/backend/web-gl/kernel-value/dynamic-html-image.js","../src/backend/web-gl/kernel-value/html-video.js","../src/backend/web-gl/kernel-value/dynamic-html-video.js","../src/backend/web-gl/kernel-value/single-input.js","../src/backend/web-gl/kernel-value/dynamic-single-input.js","../src/backend/web-gl/kernel-value/unsigned-input.js","../src/backend/web-gl/kernel-value/dynamic-unsigned-input.js","../src/backend/web-gl/kernel-value/memory-optimized-number-texture.js","../src/backend/web-gl/kernel-value/dynamic-memory-optimized-number-texture.js","../src/backend/web-gl/kernel-value/number-texture.js","../src/backend/web-gl/kernel-value/dynamic-number-texture.js","../src/backend/web-gl/kernel-value/single-array.js","../src/backend/web-gl/kernel-value/dynamic-single-array.js","../src/backend/web-gl/kernel-value/single-array1d-i.js","../src/backend/web-gl/kernel-value/dynamic-single-array1d-i.js","../src/backend/web-gl/kernel-value/single-array2d-i.js","../src/backend/web-gl/kernel-value/dynamic-single-array2d-i.js","../src/backend/web-gl/kernel-value/single-array3d-i.js","../src/backend/web-gl/kernel-value/dynamic-single-array3d-i.js","../src/backend/web-gl/kernel-value/single-array2.js","../src/backend/web-gl/kernel-value/single-array3.js","../src/backend/web-gl/kernel-value/single-array4.js","../src/backend/web-gl/kernel-value/unsigned-array.js","../src/backend/web-gl/kernel-value/dynamic-unsigned-array.js","../src/backend/web-gl/kernel-value-maps.js","../src/backend/web-gl/kernel.js","../src/backend/web-gl2/function-node.js","../src/backend/web-gl2/fragment-shader.js","../src/backend/web-gl2/vertex-shader.js","../src/backend/web-gl2/kernel-value/boolean.js","../src/backend/web-gl2/kernel-value/float.js","../src/backend/web-gl2/kernel-value/integer.js","../src/backend/web-gl2/kernel-value/html-image.js","../src/backend/web-gl2/kernel-value/dynamic-html-image.js","../src/backend/web-gl2/kernel-value/html-image-array.js","../src/backend/web-gl2/kernel-value/dynamic-html-image-array.js","../src/backend/web-gl2/kernel-value/html-video.js","../src/backend/web-gl2/kernel-value/dynamic-html-video.js","../src/backend/web-gl2/kernel-value/single-input.js","../src/backend/web-gl2/kernel-value/dynamic-single-input.js","../src/backend/web-gl2/kernel-value/unsigned-input.js","../src/backend/web-gl2/kernel-value/dynamic-unsigned-input.js","../src/backend/web-gl2/kernel-value/memory-optimized-number-texture.js","../src/backend/web-gl2/kernel-value/dynamic-memory-optimized-number-texture.js","../src/backend/web-gl2/kernel-value/number-texture.js","../src/backend/web-gl2/kernel-value/dynamic-number-texture.js","../src/backend/web-gl2/kernel-value/single-array.js","../src/backend/web-gl2/kernel-value/dynamic-single-array.js","../src/backend/web-gl2/kernel-value/single-array1d-i.js","../src/backend/web-gl2/kernel-value/dynamic-single-array1d-i.js","../src/backend/web-gl2/kernel-value/single-array2d-i.js","../src/backend/web-gl2/kernel-value/dynamic-single-array2d-i.js","../src/backend/web-gl2/kernel-value/single-array3d-i.js","../src/backend/web-gl2/kernel-value/dynamic-single-array3d-i.js","../src/backend/web-gl2/kernel-value/single-array2.js","../src/backend/web-gl2/kernel-value/single-array3.js","../src/backend/web-gl2/kernel-value/single-array4.js","../src/backend/web-gl2/kernel-value/unsigned-array.js","../src/backend/web-gl2/kernel-value/dynamic-unsigned-array.js","../src/backend/web-gl2/kernel-value-maps.js","../src/backend/web-gl2/kernel.js","../src/kernel-run-shortcut.js","../src/base-gpu.js","../src/alias.js","../src/browser.js"],"sourcesContent":["function setupArguments(args) {\n const newArguments = new Array(args.length);\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg.toArray) {\n newArguments[i] = arg.toArray();\n } else {\n newArguments[i] = arg;\n }\n }\n return newArguments;\n}\n\nfunction mock1D() {\n const args = setupArguments(arguments);\n const row = new Float32Array(this.output.x);\n for (let x = 0; x < this.output.x; x++) {\n this.thread.x = x;\n this.thread.y = 0;\n this.thread.z = 0;\n row[x] = this._fn.apply(this, args);\n }\n return row;\n}\n\nfunction mock2D() {\n const args = setupArguments(arguments);\n const matrix = new Array(this.output.y);\n for (let y = 0; y < this.output.y; y++) {\n const row = new Float32Array(this.output.x);\n for (let x = 0; x < this.output.x; x++) {\n this.thread.x = x;\n this.thread.y = y;\n this.thread.z = 0;\n row[x] = this._fn.apply(this, args);\n }\n matrix[y] = row;\n }\n return matrix;\n}\n\nfunction mock2DGraphical() {\n const args = setupArguments(arguments);\n for (let y = 0; y < this.output.y; y++) {\n for (let x = 0; x < this.output.x; x++) {\n this.thread.x = x;\n this.thread.y = y;\n this.thread.z = 0;\n this._fn.apply(this, args);\n }\n }\n}\n\nfunction mock3D() {\n const args = setupArguments(arguments);\n const cube = new Array(this.output.z);\n for (let z = 0; z < this.output.z; z++) {\n const matrix = new Array(this.output.y);\n for (let y = 0; y < this.output.y; y++) {\n const row = new Float32Array(this.output.x);\n for (let x = 0; x < this.output.x; x++) {\n this.thread.x = x;\n this.thread.y = y;\n this.thread.z = z;\n row[x] = this._fn.apply(this, args);\n }\n matrix[y] = row;\n }\n cube[z] = matrix;\n }\n return cube;\n}\n\nfunction apiDecorate(kernel) {\n kernel.setOutput = (output) => {\n kernel.output = setupOutput(output);\n if (kernel.graphical) {\n setupGraphical(kernel);\n }\n };\n kernel.toJSON = () => {\n throw new Error('Not usable with gpuMock');\n };\n kernel.setConstants = (flag) => {\n kernel.constants = flag;\n return kernel;\n };\n kernel.setGraphical = (flag) => {\n kernel.graphical = flag;\n return kernel;\n };\n kernel.setCanvas = (flag) => {\n kernel.canvas = flag;\n return kernel;\n };\n kernel.setContext = (flag) => {\n kernel.context = flag;\n return kernel;\n };\n kernel.exec = function() {\n return new Promise((resolve, reject) => {\n try {\n resolve(kernel.apply(kernel, arguments));\n } catch(e) {\n reject(e);\n }\n });\n };\n kernel.getPixels = (flip) => {\n const {x, y} = kernel.output;\n // cpu is not flipped by default\n return flip ? flipPixels(kernel._imageData.data, x, y) : kernel._imageData.data.slice(0);\n };\n kernel.color = function(r, g, b, a) {\n if (typeof a === 'undefined') {\n a = 1;\n }\n\n r = Math.floor(r * 255);\n g = Math.floor(g * 255);\n b = Math.floor(b * 255);\n a = Math.floor(a * 255);\n\n const width = kernel.output.x;\n const height = kernel.output.y;\n\n const x = kernel.thread.x;\n const y = height - kernel.thread.y - 1;\n\n const index = x + y * width;\n\n kernel._colorData[index * 4 + 0] = r;\n kernel._colorData[index * 4 + 1] = g;\n kernel._colorData[index * 4 + 2] = b;\n kernel._colorData[index * 4 + 3] = a;\n };\n\n // these are added for api compatibility, but have no affect\n kernel.setWarnVarUsage = () => {\n return kernel;\n };\n kernel.setOptimizeFloatMemory = () => {\n return kernel;\n };\n kernel.setArgumentTypes = () => {\n return kernel;\n };\n kernel.setDebug = () => {\n return kernel;\n };\n kernel.setLoopMaxIterations = () => {\n return kernel;\n };\n kernel.setPipeline = () => {\n return kernel;\n };\n kernel.setPrecision = () => {\n return kernel;\n };\n kernel.setImmutable = () => {\n return kernel;\n };\n kernel.setFunctions = () => {\n return kernel;\n };\n kernel.addSubKernel = () => {\n return kernel;\n };\n kernel.destroy = () => {};\n kernel.validateSettings = () => {};\n if (kernel.graphical && kernel.output) {\n setupGraphical(kernel);\n }\n return kernel;\n}\n\nfunction setupGraphical(kernel) {\n const {x, y} = kernel.output;\n if (kernel.context && kernel.context.createImageData) {\n const data = new Uint8ClampedArray(x * y * 4);\n kernel._imageData = kernel.context.createImageData(x, y);\n kernel._colorData = data;\n } else {\n const data = new Uint8ClampedArray(x * y * 4);\n kernel._imageData = { data };\n kernel._colorData = data;\n }\n}\n\nfunction setupOutput(output) {\n let result = null;\n if (output.length) {\n if (output.length === 3) {\n const [x,y,z] = output;\n result = { x, y, z };\n } else if (output.length === 2) {\n const [x,y] = output;\n result = { x, y };\n } else {\n const [x] = output;\n result = { x };\n }\n } else {\n result = output;\n }\n return result;\n}\n\nfunction gpuMock(fn, settings = {}) {\n const output = settings.output ? setupOutput(settings.output) : null;\n function kernel() {\n if (kernel.output.z) {\n return mock3D.apply(kernel, arguments);\n } else if (kernel.output.y) {\n if (kernel.graphical) {\n return mock2DGraphical.apply(kernel, arguments);\n }\n return mock2D.apply(kernel, arguments);\n } else {\n return mock1D.apply(kernel, arguments);\n }\n }\n kernel._fn = fn;\n kernel.constants = settings.constants || null;\n kernel.context = settings.context || null;\n kernel.canvas = settings.canvas || null;\n kernel.graphical = settings.graphical || false;\n kernel._imageData = null;\n kernel._colorData = null;\n kernel.output = output;\n kernel.thread = {\n x: 0,\n y: 0,\n z: 0\n };\n return apiDecorate(kernel);\n}\n\nfunction flipPixels(pixels, width, height) {\n // https://stackoverflow.com/a/41973289/1324039\n const halfHeight = height / 2 | 0; // the | 0 keeps the result an int\n const bytesPerRow = width * 4;\n // make a temp buffer to hold one row\n const temp = new Uint8ClampedArray(width * 4);\n const result = pixels.slice(0);\n for (let y = 0; y < halfHeight; ++y) {\n const topOffset = y * bytesPerRow;\n const bottomOffset = (height - y - 1) * bytesPerRow;\n\n // make copy of a row on the top half\n temp.set(result.subarray(topOffset, topOffset + bytesPerRow));\n\n // copy a row from the bottom half to the top\n result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow);\n\n // copy the copy of the top half row to the bottom half\n result.set(temp, bottomOffset);\n }\n return result;\n}\n\nmodule.exports = {\n gpuMock\n};\n","/**\r\n * @fileoverview Branch of utils to prevent circular dependencies.\r\n */\r\n\r\nconst ARGUMENT_NAMES = /([^\\s,]+)/g;\r\nconst FUNCTION_NAME = /function ([^(]*)/;\r\nconst STRIP_COMMENTS = /((\\/\\/.*$)|(\\/\\*[\\s\\S]*?\\*\\/))/mg;\r\n\r\n/**\r\n * @descReturn TRUE, on a JS function\r\n * @param {Function} funcObj - Object to validate if its a function\r\n * @returns {Boolean} TRUE if the object is a JS function\r\n */\r\nexport function isFunction(funcObj) {\r\n return typeof(funcObj) === 'function';\r\n};\r\n\r\n/**\r\n * @desc Return the function name from a JS function string\r\n * @param {String} funcStr - String of JS function to validate\r\n * @returns {String} Function name string (if found)\r\n */\r\nexport function getFunctionNameFromString(funcStr) {\r\n return FUNCTION_NAME.exec(funcStr)[1].trim();\r\n};\r\n\r\n/**\r\n *\r\n * @param {String|Function} source\r\n * @param {IFunctionSettings} [settings]\r\n * @returns {IFunction}\r\n */\r\nexport function functionToIFunction(source, settings) {\r\n settings = settings || {};\r\n if (typeof source !== 'string' && typeof source !== 'function') throw new Error('source not a string or function');\r\n const sourceString = typeof source === 'string' ? source : source.toString();\r\n\r\n let argumentTypes = [];\r\n\r\n if (Array.isArray(settings.argumentTypes)) {\r\n argumentTypes = settings.argumentTypes;\r\n } else if (typeof settings.argumentTypes === 'object') {\r\n argumentTypes = getArgumentNamesFromString(sourceString)\r\n .map(name => settings.argumentTypes[name]) || [];\r\n } else {\r\n argumentTypes = settings.argumentTypes || [];\r\n }\r\n\r\n return {\r\n source: sourceString,\r\n argumentTypes,\r\n returnType: settings.returnType || null,\r\n };\r\n};\r\n\r\nexport function warnDeprecated(type, oldName, newName) {\r\n const msg = newName\r\n ? `It has been replaced with \"${ newName }\"`\r\n : 'It has been removed';\r\n console.warn(`You are using a deprecated ${ type } \"${ oldName }\". ${msg}. Fixing, but please upgrade as it will soon be removed.`)\r\n};\r\n\r\n/**\r\n * @desc Return TRUE, on a valid JS function string\r\n * Note: This does just a VERY simply sanity check. And may give false positives.\r\n *\r\n * @param {String} fn - String of JS function to validate\r\n * @returns {Boolean} TRUE if the string passes basic validation\r\n */\r\nexport function isFunctionString(fn) {\r\n if (typeof fn === 'string') {\r\n return (fn\r\n .slice(0, 'function'.length)\r\n .toLowerCase() === 'function');\r\n }\r\n return false;\r\n};\r\n\r\n/**\r\n * @desc Return list of argument names extracted from a javascript function\r\n * @param {String} fn - String of JS function to validate\r\n * @returns {String[]} Array representing all the parameter names\r\n */\r\nexport function getArgumentNamesFromString(fn) {\r\n const fnStr = fn.replace(STRIP_COMMENTS, '');\r\n let result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);\r\n if (result === null) {\r\n result = [];\r\n }\r\n return result;\r\n};\r\n\r\n/**\r\n * @desc Checks if is an array or Array-like object\r\n * @param {Object} array - The argument object to check if is array\r\n * @returns {Boolean} true if is array or Array-like object\r\n */\r\nexport function isArray(array) {\r\n return !isNaN(array.length);\r\n};\r\n\r\nexport function erectMemoryOptimized2DFloat(array, width, height) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const offset = y * width;\r\n yResults[y] = array.subarray(offset, offset + width);\r\n }\r\n return yResults;\r\n};\r\n\r\nexport function erectMemoryOptimized3DFloat(array, width, height, depth) {\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const offset = (z * height * width) + (y * width);\r\n yResults[y] = array.subarray(offset, offset + width);\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n};\r\n\r\nexport function getAstString(source, ast) {\r\n const lines = Array.isArray(source) ? source : source.split(/\\r?\\n/g);\r\n const start = ast.loc.start;\r\n const end = ast.loc.end;\r\n const result = [];\r\n if (start.line === end.line) {\r\n result.push(lines[start.line - 1].substring(start.column, end.column));\r\n } else {\r\n result.push(lines[start.line - 1].slice(start.column));\r\n for (let i = start.line; i < end.line; i++) {\r\n result.push(lines[i]);\r\n }\r\n result.push(lines[end.line - 1].slice(0, end.column));\r\n }\r\n return result.join('\\n');\r\n};\r\n","import { erectMemoryOptimized2DFloat, erectMemoryOptimized3DFloat } from './common';\r\n\r\nexport class Input {\r\n constructor(value, size) {\r\n this.value = value;\r\n if (Array.isArray(size)) {\r\n this.size = size;\r\n } else {\r\n this.size = new Int32Array(3);\r\n if (size.z) {\r\n this.size = new Int32Array([size.x, size.y, size.z]);\r\n } else if (size.y) {\r\n this.size = new Int32Array([size.x, size.y]);\r\n } else {\r\n this.size = new Int32Array([size.x]);\r\n }\r\n }\r\n\r\n const [w, h, d] = this.size;\r\n if (d) {\r\n if (this.value.length !== (w * h * d)) {\r\n throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} * ${d} = ${(h * w * d)}`);\r\n }\r\n } else if (h) {\r\n if (this.value.length !== (w * h)) {\r\n throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} = ${(h * w)}`);\r\n }\r\n } else {\r\n if (this.value.length !== w) {\r\n throw new Error(`Input size ${this.value.length} does not match ${w}`);\r\n }\r\n }\r\n\r\n }\r\n\r\n toArray() {\r\n const [ w, h, d ] = this.size;\r\n if (d) {\r\n return erectMemoryOptimized3DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h, d);\r\n } else if (h) {\r\n return erectMemoryOptimized2DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h);\r\n } else {\r\n return this.value;\r\n }\r\n }\r\n};\r\n\r\nexport function input(value, size) {\r\n return new Input(value, size);\r\n};\r\n","// Reserved word lists for various dialects of the language\n\nvar reservedWords = {\n 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\",\n 5: \"class enum extends super const export import\",\n 6: \"enum\",\n strict: \"implements interface let package private protected public static yield\",\n strictBind: \"eval arguments\"\n};\n\n// And the keywords\n\nvar 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\";\n\nvar keywords = {\n 5: ecma5AndLessKeywords,\n 6: ecma5AndLessKeywords + \" const class extends export import super\"\n};\n\nvar keywordRelationalOperator = /^in(stanceof)?$/;\n\n// ## Character categories\n\n// Big ugly regular expressions that match characters in the\n// whitespace, identifier, and identifier-start categories. These\n// are only applied when a character is found to actually have a\n// code point above 128.\n// Generated by `bin/generate-identifier-regex.js`.\n\nvar 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\\u0560-\\u0588\\u05d0-\\u05ea\\u05ef-\\u05f2\\u0620-\\u064a\\u066e\\u066f\\u0671-\\u06d3\\u06d5\\u06e5\\u06e6\\u06ee\\u06ef\\u06fa-\\u06fc\\u06ff\\u0710\\u0712-\\u072f\\u074d-\\u07a5\\u07b1\\u07ca-\\u07ea\\u07f4\\u07f5\\u07fa\\u0800-\\u0815\\u081a\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086a\\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\\u09fc\\u0a05-\\u0a0a\\u0a0f\\u0a10\\u0a13-\\u0a28\\u0a2a-\\u0a30\\u0a32\\u0a33\\u0a35\\u0a36\\u0a38\\u0a39\\u0a59-\\u0a5c\\u0a5e\\u0a72-\\u0a74\\u0a85-\\u0a8d\\u0a8f-\\u0a91\\u0a93-\\u0aa8\\u0aaa-\\u0ab0\\u0ab2\\u0ab3\\u0ab5-\\u0ab9\\u0abd\\u0ad0\\u0ae0\\u0ae1\\u0af9\\u0b05-\\u0b0c\\u0b0f\\u0b10\\u0b13-\\u0b28\\u0b2a-\\u0b30\\u0b32\\u0b33\\u0b35-\\u0b39\\u0b3d\\u0b5c\\u0b5d\\u0b5f-\\u0b61\\u0b71\\u0b83\\u0b85-\\u0b8a\\u0b8e-\\u0b90\\u0b92-\\u0b95\\u0b99\\u0b9a\\u0b9c\\u0b9e\\u0b9f\\u0ba3\\u0ba4\\u0ba8-\\u0baa\\u0bae-\\u0bb9\\u0bd0\\u0c05-\\u0c0c\\u0c0e-\\u0c10\\u0c12-\\u0c28\\u0c2a-\\u0c39\\u0c3d\\u0c58-\\u0c5a\\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-\\u1878\\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\\u1c90-\\u1cba\\u1cbd-\\u1cbf\\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-\\u312f\\u3131-\\u318e\\u31a0-\\u31ba\\u31f0-\\u31ff\\u3400-\\u4db5\\u4e00-\\u9fef\\ua000-\\ua48c\\ua4d0-\\ua4fd\\ua500-\\ua60c\\ua610-\\ua61f\\ua62a\\ua62b\\ua640-\\ua66e\\ua67f-\\ua69d\\ua6a0-\\ua6ef\\ua717-\\ua71f\\ua722-\\ua788\\ua78b-\\ua7b9\\ua7f7-\\ua801\\ua803-\\ua805\\ua807-\\ua80a\\ua80c-\\ua822\\ua840-\\ua873\\ua882-\\ua8b3\\ua8f2-\\ua8f7\\ua8fb\\ua8fd\\ua8fe\\ua90a-\\ua925\\ua930-\\ua946\\ua960-\\ua97c\\ua984-\\ua9b2\\ua9cf\\ua9e0-\\ua9e4\\ua9e6-\\ua9ef\\ua9fa-\\ua9fe\\uaa00-\\uaa28\\uaa40-\\uaa42\\uaa44-\\uaa4b\\uaa60-\\uaa76\\uaa7a\\uaa7e-\\uaaaf\\uaab1\\uaab5\\uaab6\\uaab9-\\uaabd\\uaac0\\uaac2\\uaadb-\\uaadd\\uaae0-\\uaaea\\uaaf2-\\uaaf4\\uab01-\\uab06\\uab09-\\uab0e\\uab11-\\uab16\\uab20-\\uab26\\uab28-\\uab2e\\uab30-\\uab5a\\uab5c-\\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\";\nvar 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\\u07fd\\u0816-\\u0819\\u081b-\\u0823\\u0825-\\u0827\\u0829-\\u082d\\u0859-\\u085b\\u08d3-\\u08e1\\u08e3-\\u0903\\u093a-\\u093c\\u093e-\\u094f\\u0951-\\u0957\\u0962\\u0963\\u0966-\\u096f\\u0981-\\u0983\\u09bc\\u09be-\\u09c4\\u09c7\\u09c8\\u09cb-\\u09cd\\u09d7\\u09e2\\u09e3\\u09e6-\\u09ef\\u09fe\\u0a01-\\u0a03\\u0a3c\\u0a3e-\\u0a42\\u0a47\\u0a48\\u0a4b-\\u0a4d\\u0a51\\u0a66-\\u0a71\\u0a75\\u0a81-\\u0a83\\u0abc\\u0abe-\\u0ac5\\u0ac7-\\u0ac9\\u0acb-\\u0acd\\u0ae2\\u0ae3\\u0ae6-\\u0aef\\u0afa-\\u0aff\\u0b01-\\u0b03\\u0b3c\\u0b3e-\\u0b44\\u0b47\\u0b48\\u0b4b-\\u0b4d\\u0b56\\u0b57\\u0b62\\u0b63\\u0b66-\\u0b6f\\u0b82\\u0bbe-\\u0bc2\\u0bc6-\\u0bc8\\u0bca-\\u0bcd\\u0bd7\\u0be6-\\u0bef\\u0c00-\\u0c04\\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\\u0d00-\\u0d03\\u0d3b\\u0d3c\\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\\u1cf7-\\u1cf9\\u1dc0-\\u1df9\\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\\ua8ff-\\ua909\\ua926-\\ua92d\\ua947-\\ua953\\ua980-\\ua983\\ua9b3-\\ua9c0\\ua9d0-\\ua9d9\\ua9e5\\ua9f0-\\ua9f9\\uaa29-\\uaa36\\uaa43\\uaa4c\\uaa4d\\uaa50-\\uaa59\\uaa7b-\\uaa7d\\uaab0\\uaab2-\\uaab4\\uaab7\\uaab8\\uaabe\\uaabf\\uaac1\\uaaeb-\\uaaef\\uaaf5\\uaaf6\\uabe3-\\uabea\\uabec\\uabed\\uabf0-\\uabf9\\ufb1e\\ufe00-\\ufe0f\\ufe20-\\ufe2f\\ufe33\\ufe34\\ufe4d-\\ufe4f\\uff10-\\uff19\\uff3f\";\n\nvar nonASCIIidentifierStart = new RegExp(\"[\" + nonASCIIidentifierStartChars + \"]\");\nvar nonASCIIidentifier = new RegExp(\"[\" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + \"]\");\n\nnonASCIIidentifierStartChars = nonASCIIidentifierChars = null;\n\n// These are a run-length and offset encoded representation of the\n// >0xffff code points that are a valid part of identifiers. The\n// offset starts at 0x10000, and each pair of numbers represents an\n// offset to the next range, and then a size of the range. They were\n// generated by bin/generate-identifier-regex.js\n\n// eslint-disable-next-line comma-spacing\nvar astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,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,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,14,35,477,28,11,0,9,21,190,52,76,44,33,24,27,35,30,0,12,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,26,230,43,117,63,32,0,257,0,11,39,8,0,22,0,12,39,3,3,20,0,35,56,264,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,26,5,2,1,2,31,15,0,328,18,270,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,689,63,129,68,12,0,67,12,65,1,31,6129,15,754,9486,286,82,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,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,15,7472,3104,541];\n\n// eslint-disable-next-line comma-spacing\nvar astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,525,10,176,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,4,9,83,11,7,0,161,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,243,14,166,9,280,9,41,6,2,3,9,0,10,10,47,15,406,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,49,4,2,1,2,4,9,9,330,3,19306,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\n// This has a complexity linear to the value of the code. The\n// assumption is that looking up astral identifier characters is\n// rare.\nfunction isInAstralSet(code, set) {\n var pos = 0x10000;\n for (var i = 0; i < set.length; i += 2) {\n pos += set[i];\n if (pos > code) { return false }\n pos += set[i + 1];\n if (pos >= code) { return true }\n }\n}\n\n// Test whether a given character code starts an identifier.\n\nfunction isIdentifierStart(code, astral) {\n if (code < 65) { return code === 36 }\n if (code < 91) { return true }\n if (code < 97) { return code === 95 }\n if (code < 123) { return true }\n if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) }\n if (astral === false) { return false }\n return isInAstralSet(code, astralIdentifierStartCodes)\n}\n\n// Test whether a given character is part of an identifier.\n\nfunction isIdentifierChar(code, astral) {\n if (code < 48) { return code === 36 }\n if (code < 58) { return true }\n if (code < 65) { return false }\n if (code < 91) { return true }\n if (code < 97) { return code === 95 }\n if (code < 123) { return true }\n if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) }\n if (astral === false) { return false }\n return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes)\n}\n\n// ## Token types\n\n// The assignment of fine-grained, information-carrying type objects\n// allows the tokenizer to store the information it has about a\n// token in a way that is very cheap for the parser to look up.\n\n// All token type variables start with an underscore, to make them\n// easy to recognize.\n\n// The `beforeExpr` property is used to disambiguate between regular\n// expressions and divisions. It is set on all token types that can\n// be followed by an expression (thus, a slash after them would be a\n// regular expression).\n//\n// The `startsExpr` property is used to check if the token ends a\n// `yield` expression. It is set on all token types that either can\n// directly start an expression (like a quotation mark) or can\n// continue an expression (like the body of a string).\n//\n// `isLoop` marks a keyword as starting a loop, which is important\n// to know when parsing a label, in order to allow or disallow\n// continue jumps to that label.\n\nvar TokenType = function TokenType(label, conf) {\n if ( conf === void 0 ) conf = {};\n\n this.label = label;\n this.keyword = conf.keyword;\n this.beforeExpr = !!conf.beforeExpr;\n this.startsExpr = !!conf.startsExpr;\n this.isLoop = !!conf.isLoop;\n this.isAssign = !!conf.isAssign;\n this.prefix = !!conf.prefix;\n this.postfix = !!conf.postfix;\n this.binop = conf.binop || null;\n this.updateContext = null;\n};\n\nfunction binop(name, prec) {\n return new TokenType(name, {beforeExpr: true, binop: prec})\n}\nvar beforeExpr = {beforeExpr: true};\nvar startsExpr = {startsExpr: true};\n\n// Map keyword names to token types.\n\nvar keywords$1 = {};\n\n// Succinct definitions of keyword token types\nfunction kw(name, options) {\n if ( options === void 0 ) options = {};\n\n options.keyword = name;\n return keywords$1[name] = new TokenType(name, options)\n}\n\nvar types = {\n num: new TokenType(\"num\", startsExpr),\n regexp: new TokenType(\"regexp\", startsExpr),\n string: new TokenType(\"string\", startsExpr),\n name: new TokenType(\"name\", startsExpr),\n eof: new TokenType(\"eof\"),\n\n // Punctuation token types.\n bracketL: new TokenType(\"[\", {beforeExpr: true, startsExpr: true}),\n bracketR: new TokenType(\"]\"),\n braceL: new TokenType(\"{\", {beforeExpr: true, startsExpr: true}),\n braceR: new TokenType(\"}\"),\n parenL: new TokenType(\"(\", {beforeExpr: true, startsExpr: true}),\n parenR: new TokenType(\")\"),\n comma: new TokenType(\",\", beforeExpr),\n semi: new TokenType(\";\", beforeExpr),\n colon: new TokenType(\":\", beforeExpr),\n dot: new TokenType(\".\"),\n question: new TokenType(\"?\", beforeExpr),\n arrow: new TokenType(\"=>\", beforeExpr),\n template: new TokenType(\"template\"),\n invalidTemplate: new TokenType(\"invalidTemplate\"),\n ellipsis: new TokenType(\"...\", beforeExpr),\n backQuote: new TokenType(\"`\", startsExpr),\n dollarBraceL: new TokenType(\"${\", {beforeExpr: true, startsExpr: true}),\n\n // Operators. These carry several kinds of properties to help the\n // parser use them properly (the presence of these properties is\n // what categorizes them as operators).\n //\n // `binop`, when present, specifies that this operator is a binary\n // operator, and will refer to its precedence.\n //\n // `prefix` and `postfix` mark the operator as a prefix or postfix\n // unary operator.\n //\n // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as\n // binary operators with a very low precedence, that should result\n // in AssignmentExpression nodes.\n\n eq: new TokenType(\"=\", {beforeExpr: true, isAssign: true}),\n assign: new TokenType(\"_=\", {beforeExpr: true, isAssign: true}),\n incDec: new TokenType(\"++/--\", {prefix: true, postfix: true, startsExpr: true}),\n prefix: new TokenType(\"!/~\", {beforeExpr: true, prefix: true, startsExpr: true}),\n logicalOR: binop(\"||\", 1),\n logicalAND: binop(\"&&\", 2),\n bitwiseOR: binop(\"|\", 3),\n bitwiseXOR: binop(\"^\", 4),\n bitwiseAND: binop(\"&\", 5),\n equality: binop(\"==/!=/===/!==\", 6),\n relational: binop(\"/<=/>=\", 7),\n bitShift: binop(\"<>/>>>\", 8),\n plusMin: new TokenType(\"+/-\", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}),\n modulo: binop(\"%\", 10),\n star: binop(\"*\", 10),\n slash: binop(\"/\", 10),\n starstar: new TokenType(\"**\", {beforeExpr: true}),\n\n // Keyword token types.\n _break: kw(\"break\"),\n _case: kw(\"case\", beforeExpr),\n _catch: kw(\"catch\"),\n _continue: kw(\"continue\"),\n _debugger: kw(\"debugger\"),\n _default: kw(\"default\", beforeExpr),\n _do: kw(\"do\", {isLoop: true, beforeExpr: true}),\n _else: kw(\"else\", beforeExpr),\n _finally: kw(\"finally\"),\n _for: kw(\"for\", {isLoop: true}),\n _function: kw(\"function\", startsExpr),\n _if: kw(\"if\"),\n _return: kw(\"return\", beforeExpr),\n _switch: kw(\"switch\"),\n _throw: kw(\"throw\", beforeExpr),\n _try: kw(\"try\"),\n _var: kw(\"var\"),\n _const: kw(\"const\"),\n _while: kw(\"while\", {isLoop: true}),\n _with: kw(\"with\"),\n _new: kw(\"new\", {beforeExpr: true, startsExpr: true}),\n _this: kw(\"this\", startsExpr),\n _super: kw(\"super\", startsExpr),\n _class: kw(\"class\", startsExpr),\n _extends: kw(\"extends\", beforeExpr),\n _export: kw(\"export\"),\n _import: kw(\"import\"),\n _null: kw(\"null\", startsExpr),\n _true: kw(\"true\", startsExpr),\n _false: kw(\"false\", startsExpr),\n _in: kw(\"in\", {beforeExpr: true, binop: 7}),\n _instanceof: kw(\"instanceof\", {beforeExpr: true, binop: 7}),\n _typeof: kw(\"typeof\", {beforeExpr: true, prefix: true, startsExpr: true}),\n _void: kw(\"void\", {beforeExpr: true, prefix: true, startsExpr: true}),\n _delete: kw(\"delete\", {beforeExpr: true, prefix: true, startsExpr: true})\n};\n\n// Matches a whole line break (where CRLF is considered a single\n// line break). Used to count lines.\n\nvar lineBreak = /\\r\\n?|\\n|\\u2028|\\u2029/;\nvar lineBreakG = new RegExp(lineBreak.source, \"g\");\n\nfunction isNewLine(code, ecma2019String) {\n return code === 10 || code === 13 || (!ecma2019String && (code === 0x2028 || code === 0x2029))\n}\n\nvar nonASCIIwhitespace = /[\\u1680\\u180e\\u2000-\\u200a\\u202f\\u205f\\u3000\\ufeff]/;\n\nvar skipWhiteSpace = /(?:\\s|\\/\\/.*|\\/\\*[^]*?\\*\\/)*/g;\n\nvar ref = Object.prototype;\nvar hasOwnProperty = ref.hasOwnProperty;\nvar toString = ref.toString;\n\n// Checks if an object has a property.\n\nfunction has(obj, propName) {\n return hasOwnProperty.call(obj, propName)\n}\n\nvar isArray = Array.isArray || (function (obj) { return (\n toString.call(obj) === \"[object Array]\"\n); });\n\n// These are used when `options.locations` is on, for the\n// `startLoc` and `endLoc` properties.\n\nvar Position = function Position(line, col) {\n this.line = line;\n this.column = col;\n};\n\nPosition.prototype.offset = function offset (n) {\n return new Position(this.line, this.column + n)\n};\n\nvar SourceLocation = function SourceLocation(p, start, end) {\n this.start = start;\n this.end = end;\n if (p.sourceFile !== null) { this.source = p.sourceFile; }\n};\n\n// The `getLineInfo` function is mostly useful when the\n// `locations` option is off (for performance reasons) and you\n// want to find the line/column position for a given character\n// offset. `input` should be the code string that the offset refers\n// into.\n\nfunction getLineInfo(input, offset) {\n for (var line = 1, cur = 0;;) {\n lineBreakG.lastIndex = cur;\n var match = lineBreakG.exec(input);\n if (match && match.index < offset) {\n ++line;\n cur = match.index + match[0].length;\n } else {\n return new Position(line, offset - cur)\n }\n }\n}\n\n// A second optional argument can be given to further configure\n// the parser process. These options are recognized:\n\nvar defaultOptions = {\n // `ecmaVersion` indicates the ECMAScript version to parse. Must\n // be either 3, 5, 6 (2015), 7 (2016), or 8 (2017). This influences support\n // for strict mode, the set of reserved words, and support for\n // new syntax features. The default is 7.\n ecmaVersion: 7,\n // `sourceType` indicates the mode the code should be parsed in.\n // Can be either `\"script\"` or `\"module\"`. This influences global\n // strict mode and parsing of `import` and `export` declarations.\n sourceType: \"script\",\n // `onInsertedSemicolon` can be a callback that will be called\n // when a semicolon is automatically inserted. It will be passed\n // th position of the comma as an offset, and if `locations` is\n // enabled, it is given the location as a `{line, column}` object\n // as second argument.\n onInsertedSemicolon: null,\n // `onTrailingComma` is similar to `onInsertedSemicolon`, but for\n // trailing commas.\n onTrailingComma: null,\n // By default, reserved words are only enforced if ecmaVersion >= 5.\n // Set `allowReserved` to a boolean value to explicitly turn this on\n // an off. When this option has the value \"never\", reserved words\n // and keywords can also not be used as property names.\n allowReserved: null,\n // When enabled, a return at the top level is not considered an\n // error.\n allowReturnOutsideFunction: false,\n // When enabled, import/export statements are not constrained to\n // appearing at the top of the program.\n allowImportExportEverywhere: false,\n // When enabled, await identifiers are allowed to appear at the top-level scope,\n // but they are still not allowed in non-async functions.\n allowAwaitOutsideFunction: false,\n // When enabled, hashbang directive in the beginning of file\n // is allowed and treated as a line comment.\n allowHashBang: false,\n // When `locations` is on, `loc` properties holding objects with\n // `start` and `end` properties in `{line, column}` form (with\n // line being 1-based and column 0-based) will be attached to the\n // nodes.\n locations: false,\n // A function can be passed as `onToken` option, which will\n // cause Acorn to call that function with object in the same\n // format as tokens returned from `tokenizer().getToken()`. Note\n // that you are not allowed to call the parser from the\n // callback—that will corrupt its internal state.\n onToken: null,\n // A function can be passed as `onComment` option, which will\n // cause Acorn to call that function with `(block, text, start,\n // end)` parameters whenever a comment is skipped. `block` is a\n // boolean indicating whether this is a block (`/* */`) comment,\n // `text` is the content of the comment, and `start` and `end` are\n // character offsets that denote the start and end of the comment.\n // When the `locations` option is on, two more parameters are\n // passed, the full `{line, column}` locations of the start and\n // end of the comments. Note that you are not allowed to call the\n // parser from the callback—that will corrupt its internal state.\n onComment: null,\n // Nodes have their start and end characters offsets recorded in\n // `start` and `end` properties (directly on the node, rather than\n // the `loc` object, which holds line/column data. To also add a\n // [semi-standardized][range] `range` property holding a `[start,\n // end]` array with the same numbers, set the `ranges` option to\n // `true`.\n //\n // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678\n ranges: false,\n // It is possible to parse multiple files into a single AST by\n // passing the tree produced by parsing the first file as\n // `program` option in subsequent parses. This will add the\n // toplevel forms of the parsed file to the `Program` (top) node\n // of an existing parse tree.\n program: null,\n // When `locations` is on, you can pass this to record the source\n // file in every node's `loc` object.\n sourceFile: null,\n // This value, if given, is stored in every node, whether\n // `locations` is on or off.\n directSourceFile: null,\n // When enabled, parenthesized expressions are represented by\n // (non-standard) ParenthesizedExpression nodes\n preserveParens: false,\n plugins: {}\n};\n\n// Interpret and default an options object\n\nfunction getOptions(opts) {\n var options = {};\n\n for (var opt in defaultOptions)\n { options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]; }\n\n if (options.ecmaVersion >= 2015)\n { options.ecmaVersion -= 2009; }\n\n if (options.allowReserved == null)\n { options.allowReserved = options.ecmaVersion < 5; }\n\n if (isArray(options.onToken)) {\n var tokens = options.onToken;\n options.onToken = function (token) { return tokens.push(token); };\n }\n if (isArray(options.onComment))\n { options.onComment = pushComment(options, options.onComment); }\n\n return options\n}\n\nfunction pushComment(options, array) {\n return function(block, text, start, end, startLoc, endLoc) {\n var comment = {\n type: block ? \"Block\" : \"Line\",\n value: text,\n start: start,\n end: end\n };\n if (options.locations)\n { comment.loc = new SourceLocation(this, startLoc, endLoc); }\n if (options.ranges)\n { comment.range = [start, end]; }\n array.push(comment);\n }\n}\n\n// Registered plugins\nvar plugins = {};\n\nfunction keywordRegexp(words) {\n return new RegExp(\"^(?:\" + words.replace(/ /g, \"|\") + \")$\")\n}\n\nvar Parser = function Parser(options, input, startPos) {\n this.options = options = getOptions(options);\n this.sourceFile = options.sourceFile;\n this.keywords = keywordRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]);\n var reserved = \"\";\n if (!options.allowReserved) {\n for (var v = options.ecmaVersion;; v--)\n { if (reserved = reservedWords[v]) { break } }\n if (options.sourceType === \"module\") { reserved += \" await\"; }\n }\n this.reservedWords = keywordRegexp(reserved);\n var reservedStrict = (reserved ? reserved + \" \" : \"\") + reservedWords.strict;\n this.reservedWordsStrict = keywordRegexp(reservedStrict);\n this.reservedWordsStrictBind = keywordRegexp(reservedStrict + \" \" + reservedWords.strictBind);\n this.input = String(input);\n\n // Used to signal to callers of `readWord1` whether the word\n // contained any escape sequences. This is needed because words with\n // escape sequences must not be interpreted as keywords.\n this.containsEsc = false;\n\n // Load plugins\n this.loadPlugins(options.plugins);\n\n // Set up token state\n\n // The current position of the tokenizer in the input.\n if (startPos) {\n this.pos = startPos;\n this.lineStart = this.input.lastIndexOf(\"\\n\", startPos - 1) + 1;\n this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length;\n } else {\n this.pos = this.lineStart = 0;\n this.curLine = 1;\n }\n\n // Properties of the current token:\n // Its type\n this.type = types.eof;\n // For tokens that include more information than their type, the value\n this.value = null;\n // Its start and end offset\n this.start = this.end = this.pos;\n // And, if locations are used, the {line, column} object\n // corresponding to those offsets\n this.startLoc = this.endLoc = this.curPosition();\n\n // Position information for the previous token\n this.lastTokEndLoc = this.lastTokStartLoc = null;\n this.lastTokStart = this.lastTokEnd = this.pos;\n\n // The context stack is used to superficially track syntactic\n // context to predict whether a regular expression is allowed in a\n // given position.\n this.context = this.initialContext();\n this.exprAllowed = true;\n\n // Figure out if it's a module code.\n this.inModule = options.sourceType === \"module\";\n this.strict = this.inModule || this.strictDirective(this.pos);\n\n // Used to signify the start of a potential arrow function\n this.potentialArrowAt = -1;\n\n // Flags to track whether we are in a function, a generator, an async function.\n this.inFunction = this.inGenerator = this.inAsync = false;\n // Positions to delayed-check that yield/await does not exist in default parameters.\n this.yieldPos = this.awaitPos = 0;\n // Labels in scope.\n this.labels = [];\n\n // If enabled, skip leading hashbang line.\n if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === \"#!\")\n { this.skipLineComment(2); }\n\n // Scope tracking for duplicate variable names (see scope.js)\n this.scopeStack = [];\n this.enterFunctionScope();\n\n // For RegExp validation\n this.regexpState = null;\n};\n\n// DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them\nParser.prototype.isKeyword = function isKeyword (word) { return this.keywords.test(word) };\nParser.prototype.isReservedWord = function isReservedWord (word) { return this.reservedWords.test(word) };\n\nParser.prototype.extend = function extend (name, f) {\n this[name] = f(this[name]);\n};\n\nParser.prototype.loadPlugins = function loadPlugins (pluginConfigs) {\n var this$1 = this;\n\n for (var name in pluginConfigs) {\n var plugin = plugins[name];\n if (!plugin) { throw new Error(\"Plugin '\" + name + \"' not found\") }\n plugin(this$1, pluginConfigs[name]);\n }\n};\n\nParser.prototype.parse = function parse () {\n var node = this.options.program || this.startNode();\n this.nextToken();\n return this.parseTopLevel(node)\n};\n\nvar pp = Parser.prototype;\n\n// ## Parser utilities\n\nvar literal = /^(?:'((?:\\\\.|[^'])*?)'|\"((?:\\\\.|[^\"])*?)\"|;)/;\npp.strictDirective = function(start) {\n var this$1 = this;\n\n for (;;) {\n skipWhiteSpace.lastIndex = start;\n start += skipWhiteSpace.exec(this$1.input)[0].length;\n var match = literal.exec(this$1.input.slice(start));\n if (!match) { return false }\n if ((match[1] || match[2]) === \"use strict\") { return true }\n start += match[0].length;\n }\n};\n\n// Predicate that tests whether the next token is of the given\n// type, and if yes, consumes it as a side effect.\n\npp.eat = function(type) {\n if (this.type === type) {\n this.next();\n return true\n } else {\n return false\n }\n};\n\n// Tests whether parsed token is a contextual keyword.\n\npp.isContextual = function(name) {\n return this.type === types.name && this.value === name && !this.containsEsc\n};\n\n// Consumes contextual keyword if possible.\n\npp.eatContextual = function(name) {\n if (!this.isContextual(name)) { return false }\n this.next();\n return true\n};\n\n// Asserts that following token is given contextual keyword.\n\npp.expectContextual = function(name) {\n if (!this.eatContextual(name)) { this.unexpected(); }\n};\n\n// Test whether a semicolon can be inserted at the current position.\n\npp.canInsertSemicolon = function() {\n return this.type === types.eof ||\n this.type === types.braceR ||\n lineBreak.test(this.input.slice(this.lastTokEnd, this.start))\n};\n\npp.insertSemicolon = function() {\n if (this.canInsertSemicolon()) {\n if (this.options.onInsertedSemicolon)\n { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); }\n return true\n }\n};\n\n// Consume a semicolon, or, failing that, see if we are allowed to\n// pretend that there is a semicolon at this position.\n\npp.semicolon = function() {\n if (!this.eat(types.semi) && !this.insertSemicolon()) { this.unexpected(); }\n};\n\npp.afterTrailingComma = function(tokType, notNext) {\n if (this.type === tokType) {\n if (this.options.onTrailingComma)\n { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); }\n if (!notNext)\n { this.next(); }\n return true\n }\n};\n\n// Expect a token of a given type. If found, consume it, otherwise,\n// raise an unexpected token error.\n\npp.expect = function(type) {\n this.eat(type) || this.unexpected();\n};\n\n// Raise an unexpected token error.\n\npp.unexpected = function(pos) {\n this.raise(pos != null ? pos : this.start, \"Unexpected token\");\n};\n\nfunction DestructuringErrors() {\n this.shorthandAssign =\n this.trailingComma =\n this.parenthesizedAssign =\n this.parenthesizedBind =\n this.doubleProto =\n -1;\n}\n\npp.checkPatternErrors = function(refDestructuringErrors, isAssign) {\n if (!refDestructuringErrors) { return }\n if (refDestructuringErrors.trailingComma > -1)\n { this.raiseRecoverable(refDestructuringErrors.trailingComma, \"Comma is not permitted after the rest element\"); }\n var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind;\n if (parens > -1) { this.raiseRecoverable(parens, \"Parenthesized pattern\"); }\n};\n\npp.checkExpressionErrors = function(refDestructuringErrors, andThrow) {\n if (!refDestructuringErrors) { return false }\n var shorthandAssign = refDestructuringErrors.shorthandAssign;\n var doubleProto = refDestructuringErrors.doubleProto;\n if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 }\n if (shorthandAssign >= 0)\n { this.raise(shorthandAssign, \"Shorthand property assignments are valid only in destructuring patterns\"); }\n if (doubleProto >= 0)\n { this.raiseRecoverable(doubleProto, \"Redefinition of __proto__ property\"); }\n};\n\npp.checkYieldAwaitInDefaultParams = function() {\n if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos))\n { this.raise(this.yieldPos, \"Yield expression cannot be a default value\"); }\n if (this.awaitPos)\n { this.raise(this.awaitPos, \"Await expression cannot be a default value\"); }\n};\n\npp.isSimpleAssignTarget = function(expr) {\n if (expr.type === \"ParenthesizedExpression\")\n { return this.isSimpleAssignTarget(expr.expression) }\n return expr.type === \"Identifier\" || expr.type === \"MemberExpression\"\n};\n\nvar pp$1 = Parser.prototype;\n\n// ### Statement parsing\n\n// Parse a program. Initializes the parser, reads any number of\n// statements, and wraps them in a Program node. Optionally takes a\n// `program` argument. If present, the statements will be appended\n// to its body instead of creating a new node.\n\npp$1.parseTopLevel = function(node) {\n var this$1 = this;\n\n var exports = {};\n if (!node.body) { node.body = []; }\n while (this.type !== types.eof) {\n var stmt = this$1.parseStatement(true, true, exports);\n node.body.push(stmt);\n }\n this.adaptDirectivePrologue(node.body);\n this.next();\n if (this.options.ecmaVersion >= 6) {\n node.sourceType = this.options.sourceType;\n }\n return this.finishNode(node, \"Program\")\n};\n\nvar loopLabel = {kind: \"loop\"};\nvar switchLabel = {kind: \"switch\"};\n\npp$1.isLet = function() {\n if (this.options.ecmaVersion < 6 || !this.isContextual(\"let\")) { return false }\n skipWhiteSpace.lastIndex = this.pos;\n var skip = skipWhiteSpace.exec(this.input);\n var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);\n if (nextCh === 91 || nextCh === 123) { return true } // '{' and '['\n if (isIdentifierStart(nextCh, true)) {\n var pos = next + 1;\n while (isIdentifierChar(this.input.charCodeAt(pos), true)) { ++pos; }\n var ident = this.input.slice(next, pos);\n if (!keywordRelationalOperator.test(ident)) { return true }\n }\n return false\n};\n\n// check 'async [no LineTerminator here] function'\n// - 'async /*foo*/ function' is OK.\n// - 'async /*\\n*/ function' is invalid.\npp$1.isAsyncFunction = function() {\n if (this.options.ecmaVersion < 8 || !this.isContextual(\"async\"))\n { return false }\n\n skipWhiteSpace.lastIndex = this.pos;\n var skip = skipWhiteSpace.exec(this.input);\n var next = this.pos + skip[0].length;\n return !lineBreak.test(this.input.slice(this.pos, next)) &&\n this.input.slice(next, next + 8) === \"function\" &&\n (next + 8 === this.input.length || !isIdentifierChar(this.input.charAt(next + 8)))\n};\n\n// Parse a single statement.\n//\n// If expecting a statement and finding a slash operator, parse a\n// regular expression literal. This is to handle cases like\n// `if (foo) /blah/.exec(foo)`, where looking at the previous token\n// does not help.\n\npp$1.parseStatement = function(declaration, topLevel, exports) {\n var starttype = this.type, node = this.startNode(), kind;\n\n if (this.isLet()) {\n starttype = types._var;\n kind = \"let\";\n }\n\n // Most types of statements are recognized by the keyword they\n // start with. Many are trivial to parse, some require a bit of\n // complexity.\n\n switch (starttype) {\n case types._break: case types._continue: return this.parseBreakContinueStatement(node, starttype.keyword)\n case types._debugger: return this.parseDebuggerStatement(node)\n case types._do: return this.parseDoStatement(node)\n case types._for: return this.parseForStatement(node)\n case types._function:\n if (!declaration && this.options.ecmaVersion >= 6) { this.unexpected(); }\n return this.parseFunctionStatement(node, false)\n case types._class:\n if (!declaration) { this.unexpected(); }\n return this.parseClass(node, true)\n case types._if: return this.parseIfStatement(node)\n case types._return: return this.parseReturnStatement(node)\n case types._switch: return this.parseSwitchStatement(node)\n case types._throw: return this.parseThrowStatement(node)\n case types._try: return this.parseTryStatement(node)\n case types._const: case types._var:\n kind = kind || this.value;\n if (!declaration && kind !== \"var\") { this.unexpected(); }\n return this.parseVarStatement(node, kind)\n case types._while: return this.parseWhileStatement(node)\n case types._with: return this.parseWithStatement(node)\n case types.braceL: return this.parseBlock()\n case types.semi: return this.parseEmptyStatement(node)\n case types._export:\n case types._import:\n if (!this.options.allowImportExportEverywhere) {\n if (!topLevel)\n { this.raise(this.start, \"'import' and 'export' may only appear at the top level\"); }\n if (!this.inModule)\n { this.raise(this.start, \"'import' and 'export' may appear only with 'sourceType: module'\"); }\n }\n return starttype === types._import ? this.parseImport(node) : this.parseExport(node, exports)\n\n // If the statement does not start with a statement keyword or a\n // brace, it's an ExpressionStatement or LabeledStatement. We\n // simply start parsing an expression, and afterwards, if the\n // next token is a colon and the expression was a simple\n // Identifier node, we switch to interpreting it as a label.\n default:\n if (this.isAsyncFunction()) {\n if (!declaration) { this.unexpected(); }\n this.next();\n return this.parseFunctionStatement(node, true)\n }\n\n var maybeName = this.value, expr = this.parseExpression();\n if (starttype === types.name && expr.type === \"Identifier\" && this.eat(types.colon))\n { return this.parseLabeledStatement(node, maybeName, expr) }\n else { return this.parseExpressionStatement(node, expr) }\n }\n};\n\npp$1.parseBreakContinueStatement = function(node, keyword) {\n var this$1 = this;\n\n var isBreak = keyword === \"break\";\n this.next();\n if (this.eat(types.semi) || this.insertSemicolon()) { node.label = null; }\n else if (this.type !== types.name) { this.unexpected(); }\n else {\n node.label = this.parseIdent();\n this.semicolon();\n }\n\n // Verify that there is an actual destination to break or\n // continue to.\n var i = 0;\n for (; i < this.labels.length; ++i) {\n var lab = this$1.labels[i];\n if (node.label == null || lab.name === node.label.name) {\n if (lab.kind != null && (isBreak || lab.kind === \"loop\")) { break }\n if (node.label && isBreak) { break }\n }\n }\n if (i === this.labels.length) { this.raise(node.start, \"Unsyntactic \" + keyword); }\n return this.finishNode(node, isBreak ? \"BreakStatement\" : \"ContinueStatement\")\n};\n\npp$1.parseDebuggerStatement = function(node) {\n this.next();\n this.semicolon();\n return this.finishNode(node, \"DebuggerStatement\")\n};\n\npp$1.parseDoStatement = function(node) {\n this.next();\n this.labels.push(loopLabel);\n node.body = this.parseStatement(false);\n this.labels.pop();\n this.expect(types._while);\n node.test = this.parseParenExpression();\n if (this.options.ecmaVersion >= 6)\n { this.eat(types.semi); }\n else\n { this.semicolon(); }\n return this.finishNode(node, \"DoWhileStatement\")\n};\n\n// Disambiguating between a `for` and a `for`/`in` or `for`/`of`\n// loop is non-trivial. Basically, we have to parse the init `var`\n// statement or expression, disallowing the `in` operator (see\n// the second parameter to `parseExpression`), and then check\n// whether the next token is `in` or `of`. When there is no init\n// part (semicolon immediately after the opening parenthesis), it\n// is a regular `for` loop.\n\npp$1.parseForStatement = function(node) {\n this.next();\n var awaitAt = (this.options.ecmaVersion >= 9 && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction)) && this.eatContextual(\"await\")) ? this.lastTokStart : -1;\n this.labels.push(loopLabel);\n this.enterLexicalScope();\n this.expect(types.parenL);\n if (this.type === types.semi) {\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n return this.parseFor(node, null)\n }\n var isLet = this.isLet();\n if (this.type === types._var || this.type === types._const || isLet) {\n var init$1 = this.startNode(), kind = isLet ? \"let\" : this.value;\n this.next();\n this.parseVar(init$1, true, kind);\n this.finishNode(init$1, \"VariableDeclaration\");\n if ((this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual(\"of\"))) && init$1.declarations.length === 1 &&\n !(kind !== \"var\" && init$1.declarations[0].init)) {\n if (this.options.ecmaVersion >= 9) {\n if (this.type === types._in) {\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n } else { node.await = awaitAt > -1; }\n }\n return this.parseForIn(node, init$1)\n }\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n return this.parseFor(node, init$1)\n }\n var refDestructuringErrors = new DestructuringErrors;\n var init = this.parseExpression(true, refDestructuringErrors);\n if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual(\"of\"))) {\n if (this.options.ecmaVersion >= 9) {\n if (this.type === types._in) {\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n } else { node.await = awaitAt > -1; }\n }\n this.toAssignable(init, false, refDestructuringErrors);\n this.checkLVal(init);\n return this.parseForIn(node, init)\n } else {\n this.checkExpressionErrors(refDestructuringErrors, true);\n }\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n return this.parseFor(node, init)\n};\n\npp$1.parseFunctionStatement = function(node, isAsync) {\n this.next();\n return this.parseFunction(node, true, false, isAsync)\n};\n\npp$1.parseIfStatement = function(node) {\n this.next();\n node.test = this.parseParenExpression();\n // allow function declarations in branches, but only in non-strict mode\n node.consequent = this.parseStatement(!this.strict && this.type === types._function);\n node.alternate = this.eat(types._else) ? this.parseStatement(!this.strict && this.type === types._function) : null;\n return this.finishNode(node, \"IfStatement\")\n};\n\npp$1.parseReturnStatement = function(node) {\n if (!this.inFunction && !this.options.allowReturnOutsideFunction)\n { this.raise(this.start, \"'return' outside of function\"); }\n this.next();\n\n // In `return` (and `break`/`continue`), the keywords with\n // optional arguments, we eagerly look for a semicolon or the\n // possibility to insert one.\n\n if (this.eat(types.semi) || this.insertSemicolon()) { node.argument = null; }\n else { node.argument = this.parseExpression(); this.semicolon(); }\n return this.finishNode(node, \"ReturnStatement\")\n};\n\npp$1.parseSwitchStatement = function(node) {\n var this$1 = this;\n\n this.next();\n node.discriminant = this.parseParenExpression();\n node.cases = [];\n this.expect(types.braceL);\n this.labels.push(switchLabel);\n this.enterLexicalScope();\n\n // Statements under must be grouped (by label) in SwitchCase\n // nodes. `cur` is used to keep the node that we are currently\n // adding statements to.\n\n var cur;\n for (var sawDefault = false; this.type !== types.braceR;) {\n if (this$1.type === types._case || this$1.type === types._default) {\n var isCase = this$1.type === types._case;\n if (cur) { this$1.finishNode(cur, \"SwitchCase\"); }\n node.cases.push(cur = this$1.startNode());\n cur.consequent = [];\n this$1.next();\n if (isCase) {\n cur.test = this$1.parseExpression();\n } else {\n if (sawDefault) { this$1.raiseRecoverable(this$1.lastTokStart, \"Multiple default clauses\"); }\n sawDefault = true;\n cur.test = null;\n }\n this$1.expect(types.colon);\n } else {\n if (!cur) { this$1.unexpected(); }\n cur.consequent.push(this$1.parseStatement(true));\n }\n }\n this.exitLexicalScope();\n if (cur) { this.finishNode(cur, \"SwitchCase\"); }\n this.next(); // Closing brace\n this.labels.pop();\n return this.finishNode(node, \"SwitchStatement\")\n};\n\npp$1.parseThrowStatement = function(node) {\n this.next();\n if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start)))\n { this.raise(this.lastTokEnd, \"Illegal newline after throw\"); }\n node.argument = this.parseExpression();\n this.semicolon();\n return this.finishNode(node, \"ThrowStatement\")\n};\n\n// Reused empty array added for node fields that are always empty.\n\nvar empty = [];\n\npp$1.parseTryStatement = function(node) {\n this.next();\n node.block = this.parseBlock();\n node.handler = null;\n if (this.type === types._catch) {\n var clause = this.startNode();\n this.next();\n if (this.eat(types.parenL)) {\n clause.param = this.parseBindingAtom();\n this.enterLexicalScope();\n this.checkLVal(clause.param, \"let\");\n this.expect(types.parenR);\n } else {\n if (this.options.ecmaVersion < 10) { this.unexpected(); }\n clause.param = null;\n this.enterLexicalScope();\n }\n clause.body = this.parseBlock(false);\n this.exitLexicalScope();\n node.handler = this.finishNode(clause, \"CatchClause\");\n }\n node.finalizer = this.eat(types._finally) ? this.parseBlock() : null;\n if (!node.handler && !node.finalizer)\n { this.raise(node.start, \"Missing catch or finally clause\"); }\n return this.finishNode(node, \"TryStatement\")\n};\n\npp$1.parseVarStatement = function(node, kind) {\n this.next();\n this.parseVar(node, false, kind);\n this.semicolon();\n return this.finishNode(node, \"VariableDeclaration\")\n};\n\npp$1.parseWhileStatement = function(node) {\n this.next();\n node.test = this.parseParenExpression();\n this.labels.push(loopLabel);\n node.body = this.parseStatement(false);\n this.labels.pop();\n return this.finishNode(node, \"WhileStatement\")\n};\n\npp$1.parseWithStatement = function(node) {\n if (this.strict) { this.raise(this.start, \"'with' in strict mode\"); }\n this.next();\n node.object = this.parseParenExpression();\n node.body = this.parseStatement(false);\n return this.finishNode(node, \"WithStatement\")\n};\n\npp$1.parseEmptyStatement = function(node) {\n this.next();\n return this.finishNode(node, \"EmptyStatement\")\n};\n\npp$1.parseLabeledStatement = function(node, maybeName, expr) {\n var this$1 = this;\n\n for (var i$1 = 0, list = this$1.labels; i$1 < list.length; i$1 += 1)\n {\n var label = list[i$1];\n\n if (label.name === maybeName)\n { this$1.raise(expr.start, \"Label '\" + maybeName + \"' is already declared\");\n } }\n var kind = this.type.isLoop ? \"loop\" : this.type === types._switch ? \"switch\" : null;\n for (var i = this.labels.length - 1; i >= 0; i--) {\n var label$1 = this$1.labels[i];\n if (label$1.statementStart === node.start) {\n // Update information about previous labels on this node\n label$1.statementStart = this$1.start;\n label$1.kind = kind;\n } else { break }\n }\n this.labels.push({name: maybeName, kind: kind, statementStart: this.start});\n node.body = this.parseStatement(true);\n if (node.body.type === \"ClassDeclaration\" ||\n node.body.type === \"VariableDeclaration\" && node.body.kind !== \"var\" ||\n node.body.type === \"FunctionDeclaration\" && (this.strict || node.body.generator || node.body.async))\n { this.raiseRecoverable(node.body.start, \"Invalid labeled declaration\"); }\n this.labels.pop();\n node.label = expr;\n return this.finishNode(node, \"LabeledStatement\")\n};\n\npp$1.parseExpressionStatement = function(node, expr) {\n node.expression = expr;\n this.semicolon();\n return this.finishNode(node, \"ExpressionStatement\")\n};\n\n// Parse a semicolon-enclosed block of statements, handling `\"use\n// strict\"` declarations when `allowStrict` is true (used for\n// function bodies).\n\npp$1.parseBlock = function(createNewLexicalScope) {\n var this$1 = this;\n if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true;\n\n var node = this.startNode();\n node.body = [];\n this.expect(types.braceL);\n if (createNewLexicalScope) {\n this.enterLexicalScope();\n }\n while (!this.eat(types.braceR)) {\n var stmt = this$1.parseStatement(true);\n node.body.push(stmt);\n }\n if (createNewLexicalScope) {\n this.exitLexicalScope();\n }\n return this.finishNode(node, \"BlockStatement\")\n};\n\n// Parse a regular `for` loop. The disambiguation code in\n// `parseStatement` will already have parsed the init statement or\n// expression.\n\npp$1.parseFor = function(node, init) {\n node.init = init;\n this.expect(types.semi);\n node.test = this.type === types.semi ? null : this.parseExpression();\n this.expect(types.semi);\n node.update = this.type === types.parenR ? null : this.parseExpression();\n this.expect(types.parenR);\n this.exitLexicalScope();\n node.body = this.parseStatement(false);\n this.labels.pop();\n return this.finishNode(node, \"ForStatement\")\n};\n\n// Parse a `for`/`in` and `for`/`of` loop, which are almost\n// same from parser's perspective.\n\npp$1.parseForIn = function(node, init) {\n var type = this.type === types._in ? \"ForInStatement\" : \"ForOfStatement\";\n this.next();\n if (type === \"ForInStatement\") {\n if (init.type === \"AssignmentPattern\" ||\n (init.type === \"VariableDeclaration\" && init.declarations[0].init != null &&\n (this.strict || init.declarations[0].id.type !== \"Identifier\")))\n { this.raise(init.start, \"Invalid assignment in for-in loop head\"); }\n }\n node.left = init;\n node.right = type === \"ForInStatement\" ? this.parseExpression() : this.parseMaybeAssign();\n this.expect(types.parenR);\n this.exitLexicalScope();\n node.body = this.parseStatement(false);\n this.labels.pop();\n return this.finishNode(node, type)\n};\n\n// Parse a list of variable declarations.\n\npp$1.parseVar = function(node, isFor, kind) {\n var this$1 = this;\n\n node.declarations = [];\n node.kind = kind;\n for (;;) {\n var decl = this$1.startNode();\n this$1.parseVarId(decl, kind);\n if (this$1.eat(types.eq)) {\n decl.init = this$1.parseMaybeAssign(isFor);\n } else if (kind === \"const\" && !(this$1.type === types._in || (this$1.options.ecmaVersion >= 6 && this$1.isContextual(\"of\")))) {\n this$1.unexpected();\n } else if (decl.id.type !== \"Identifier\" && !(isFor && (this$1.type === types._in || this$1.isContextual(\"of\")))) {\n this$1.raise(this$1.lastTokEnd, \"Complex binding patterns require an initialization value\");\n } else {\n decl.init = null;\n }\n node.declarations.push(this$1.finishNode(decl, \"VariableDeclarator\"));\n if (!this$1.eat(types.comma)) { break }\n }\n return node\n};\n\npp$1.parseVarId = function(decl, kind) {\n decl.id = this.parseBindingAtom(kind);\n this.checkLVal(decl.id, kind, false);\n};\n\n// Parse a function declaration or literal (depending on the\n// `isStatement` parameter).\n\npp$1.parseFunction = function(node, isStatement, allowExpressionBody, isAsync) {\n this.initFunction(node);\n if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync)\n { node.generator = this.eat(types.star); }\n if (this.options.ecmaVersion >= 8)\n { node.async = !!isAsync; }\n\n if (isStatement) {\n node.id = isStatement === \"nullableID\" && this.type !== types.name ? null : this.parseIdent();\n if (node.id) {\n this.checkLVal(node.id, this.inModule && !this.inFunction ? \"let\" : \"var\");\n }\n }\n\n var oldInGen = this.inGenerator, oldInAsync = this.inAsync,\n oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction;\n this.inGenerator = node.generator;\n this.inAsync = node.async;\n this.yieldPos = 0;\n this.awaitPos = 0;\n this.inFunction = true;\n this.enterFunctionScope();\n\n if (!isStatement)\n { node.id = this.type === types.name ? this.parseIdent() : null; }\n\n this.parseFunctionParams(node);\n this.parseFunctionBody(node, allowExpressionBody);\n\n this.inGenerator = oldInGen;\n this.inAsync = oldInAsync;\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n this.inFunction = oldInFunc;\n return this.finishNode(node, isStatement ? \"FunctionDeclaration\" : \"FunctionExpression\")\n};\n\npp$1.parseFunctionParams = function(node) {\n this.expect(types.parenL);\n node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8);\n this.checkYieldAwaitInDefaultParams();\n};\n\n// Parse a class declaration or literal (depending on the\n// `isStatement` parameter).\n\npp$1.parseClass = function(node, isStatement) {\n var this$1 = this;\n\n this.next();\n\n this.parseClassId(node, isStatement);\n this.parseClassSuper(node);\n var classBody = this.startNode();\n var hadConstructor = false;\n classBody.body = [];\n this.expect(types.braceL);\n while (!this.eat(types.braceR)) {\n var member = this$1.parseClassMember(classBody);\n if (member && member.type === \"MethodDefinition\" && member.kind === \"constructor\") {\n if (hadConstructor) { this$1.raise(member.start, \"Duplicate constructor in the same class\"); }\n hadConstructor = true;\n }\n }\n node.body = this.finishNode(classBody, \"ClassBody\");\n return this.finishNode(node, isStatement ? \"ClassDeclaration\" : \"ClassExpression\")\n};\n\npp$1.parseClassMember = function(classBody) {\n var this$1 = this;\n\n if (this.eat(types.semi)) { return null }\n\n var method = this.startNode();\n var tryContextual = function (k, noLineBreak) {\n if ( noLineBreak === void 0 ) noLineBreak = false;\n\n var start = this$1.start, startLoc = this$1.startLoc;\n if (!this$1.eatContextual(k)) { return false }\n if (this$1.type !== types.parenL && (!noLineBreak || !this$1.canInsertSemicolon())) { return true }\n if (method.key) { this$1.unexpected(); }\n method.computed = false;\n method.key = this$1.startNodeAt(start, startLoc);\n method.key.name = k;\n this$1.finishNode(method.key, \"Identifier\");\n return false\n };\n\n method.kind = \"method\";\n method.static = tryContextual(\"static\");\n var isGenerator = this.eat(types.star);\n var isAsync = false;\n if (!isGenerator) {\n if (this.options.ecmaVersion >= 8 && tryContextual(\"async\", true)) {\n isAsync = true;\n isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star);\n } else if (tryContextual(\"get\")) {\n method.kind = \"get\";\n } else if (tryContextual(\"set\")) {\n method.kind = \"set\";\n }\n }\n if (!method.key) { this.parsePropertyName(method); }\n var key = method.key;\n if (!method.computed && !method.static && (key.type === \"Identifier\" && key.name === \"constructor\" ||\n key.type === \"Literal\" && key.value === \"constructor\")) {\n if (method.kind !== \"method\") { this.raise(key.start, \"Constructor can't have get/set modifier\"); }\n if (isGenerator) { this.raise(key.start, \"Constructor can't be a generator\"); }\n if (isAsync) { this.raise(key.start, \"Constructor can't be an async method\"); }\n method.kind = \"constructor\";\n } else if (method.static && key.type === \"Identifier\" && key.name === \"prototype\") {\n this.raise(key.start, \"Classes may not have a static property named prototype\");\n }\n this.parseClassMethod(classBody, method, isGenerator, isAsync);\n if (method.kind === \"get\" && method.value.params.length !== 0)\n { this.raiseRecoverable(method.value.start, \"getter should have no params\"); }\n if (method.kind === \"set\" && method.value.params.length !== 1)\n { this.raiseRecoverable(method.value.start, \"setter should have exactly one param\"); }\n if (method.kind === \"set\" && method.value.params[0].type === \"RestElement\")\n { this.raiseRecoverable(method.value.params[0].start, \"Setter cannot use rest params\"); }\n return method\n};\n\npp$1.parseClassMethod = function(classBody, method, isGenerator, isAsync) {\n method.value = this.parseMethod(isGenerator, isAsync);\n classBody.body.push(this.finishNode(method, \"MethodDefinition\"));\n};\n\npp$1.parseClassId = function(node, isStatement) {\n node.id = this.type === types.name ? this.parseIdent() : isStatement === true ? this.unexpected() : null;\n};\n\npp$1.parseClassSuper = function(node) {\n node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null;\n};\n\n// Parses module export declaration.\n\npp$1.parseExport = function(node, exports) {\n var this$1 = this;\n\n this.next();\n // export * from '...'\n if (this.eat(types.star)) {\n this.expectContextual(\"from\");\n if (this.type !== types.string) { this.unexpected(); }\n node.source = this.parseExprAtom();\n this.semicolon();\n return this.finishNode(node, \"ExportAllDeclaration\")\n }\n if (this.eat(types._default)) { // export default ...\n this.checkExport(exports, \"default\", this.lastTokStart);\n var isAsync;\n if (this.type === types._function || (isAsync = this.isAsyncFunction())) {\n var fNode = this.startNode();\n this.next();\n if (isAsync) { this.next(); }\n node.declaration = this.parseFunction(fNode, \"nullableID\", false, isAsync);\n } else if (this.type === types._class) {\n var cNode = this.startNode();\n node.declaration = this.parseClass(cNode, \"nullableID\");\n } else {\n node.declaration = this.parseMaybeAssign();\n this.semicolon();\n }\n return this.finishNode(node, \"ExportDefaultDeclaration\")\n }\n // export var|const|let|function|class ...\n if (this.shouldParseExportStatement()) {\n node.declaration = this.parseStatement(true);\n if (node.declaration.type === \"VariableDeclaration\")\n { this.checkVariableExport(exports, node.declaration.declarations); }\n else\n { this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); }\n node.specifiers = [];\n node.source = null;\n } else { // export { x, y as z } [from '...']\n node.declaration = null;\n node.specifiers = this.parseExportSpecifiers(exports);\n if (this.eatContextual(\"from\")) {\n if (this.type !== types.string) { this.unexpected(); }\n node.source = this.parseExprAtom();\n } else {\n // check for keywords used as local names\n for (var i = 0, list = node.specifiers; i < list.length; i += 1) {\n var spec = list[i];\n\n this$1.checkUnreserved(spec.local);\n }\n\n node.source = null;\n }\n this.semicolon();\n }\n return this.finishNode(node, \"ExportNamedDeclaration\")\n};\n\npp$1.checkExport = function(exports, name, pos) {\n if (!exports) { return }\n if (has(exports, name))\n { this.raiseRecoverable(pos, \"Duplicate export '\" + name + \"'\"); }\n exports[name] = true;\n};\n\npp$1.checkPatternExport = function(exports, pat) {\n var this$1 = this;\n\n var type = pat.type;\n if (type === \"Identifier\")\n { this.checkExport(exports, pat.name, pat.start); }\n else if (type === \"ObjectPattern\")\n { for (var i = 0, list = pat.properties; i < list.length; i += 1)\n {\n var prop = list[i];\n\n this$1.checkPatternExport(exports, prop);\n } }\n else if (type === \"ArrayPattern\")\n { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) {\n var elt = list$1[i$1];\n\n if (elt) { this$1.checkPatternExport(exports, elt); }\n } }\n else if (type === \"Property\")\n { this.checkPatternExport(exports, pat.value); }\n else if (type === \"AssignmentPattern\")\n { this.checkPatternExport(exports, pat.left); }\n else if (type === \"RestElement\")\n { this.checkPatternExport(exports, pat.argument); }\n else if (type === \"ParenthesizedExpression\")\n { this.checkPatternExport(exports, pat.expression); }\n};\n\npp$1.checkVariableExport = function(exports, decls) {\n var this$1 = this;\n\n if (!exports) { return }\n for (var i = 0, list = decls; i < list.length; i += 1)\n {\n var decl = list[i];\n\n this$1.checkPatternExport(exports, decl.id);\n }\n};\n\npp$1.shouldParseExportStatement = function() {\n return this.type.keyword === \"var\" ||\n this.type.keyword === \"const\" ||\n this.type.keyword === \"class\" ||\n this.type.keyword === \"function\" ||\n this.isLet() ||\n this.isAsyncFunction()\n};\n\n// Parses a comma-separated list of module exports.\n\npp$1.parseExportSpecifiers = function(exports) {\n var this$1 = this;\n\n var nodes = [], first = true;\n // export { x, y as z } [from '...']\n this.expect(types.braceL);\n while (!this.eat(types.braceR)) {\n if (!first) {\n this$1.expect(types.comma);\n if (this$1.afterTrailingComma(types.braceR)) { break }\n } else { first = false; }\n\n var node = this$1.startNode();\n node.local = this$1.parseIdent(true);\n node.exported = this$1.eatContextual(\"as\") ? this$1.parseIdent(true) : node.local;\n this$1.checkExport(exports, node.exported.name, node.exported.start);\n nodes.push(this$1.finishNode(node, \"ExportSpecifier\"));\n }\n return nodes\n};\n\n// Parses import declaration.\n\npp$1.parseImport = function(node) {\n this.next();\n // import '...'\n if (this.type === types.string) {\n node.specifiers = empty;\n node.source = this.parseExprAtom();\n } else {\n node.specifiers = this.parseImportSpecifiers();\n this.expectContextual(\"from\");\n node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected();\n }\n this.semicolon();\n return this.finishNode(node, \"ImportDeclaration\")\n};\n\n// Parses a comma-separated list of module imports.\n\npp$1.parseImportSpecifiers = function() {\n var this$1 = this;\n\n var nodes = [], first = true;\n if (this.type === types.name) {\n // import defaultObj, { x, y as z } from '...'\n var node = this.startNode();\n node.local = this.parseIdent();\n this.checkLVal(node.local, \"let\");\n nodes.push(this.finishNode(node, \"ImportDefaultSpecifier\"));\n if (!this.eat(types.comma)) { return nodes }\n }\n if (this.type === types.star) {\n var node$1 = this.startNode();\n this.next();\n this.expectContextual(\"as\");\n node$1.local = this.parseIdent();\n this.checkLVal(node$1.local, \"let\");\n nodes.push(this.finishNode(node$1, \"ImportNamespaceSpecifier\"));\n return nodes\n }\n this.expect(types.braceL);\n while (!this.eat(types.braceR)) {\n if (!first) {\n this$1.expect(types.comma);\n if (this$1.afterTrailingComma(types.braceR)) { break }\n } else { first = false; }\n\n var node$2 = this$1.startNode();\n node$2.imported = this$1.parseIdent(true);\n if (this$1.eatContextual(\"as\")) {\n node$2.local = this$1.parseIdent();\n } else {\n this$1.checkUnreserved(node$2.imported);\n node$2.local = node$2.imported;\n }\n this$1.checkLVal(node$2.local, \"let\");\n nodes.push(this$1.finishNode(node$2, \"ImportSpecifier\"));\n }\n return nodes\n};\n\n// Set `ExpressionStatement#directive` property for directive prologues.\npp$1.adaptDirectivePrologue = function(statements) {\n for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) {\n statements[i].directive = statements[i].expression.raw.slice(1, -1);\n }\n};\npp$1.isDirectiveCandidate = function(statement) {\n return (\n statement.type === \"ExpressionStatement\" &&\n statement.expression.type === \"Literal\" &&\n typeof statement.expression.value === \"string\" &&\n // Reject parenthesized strings.\n (this.input[statement.start] === \"\\\"\" || this.input[statement.start] === \"'\")\n )\n};\n\nvar pp$2 = Parser.prototype;\n\n// Convert existing expression atom to assignable pattern\n// if possible.\n\npp$2.toAssignable = function(node, isBinding, refDestructuringErrors) {\n var this$1 = this;\n\n if (this.options.ecmaVersion >= 6 && node) {\n switch (node.type) {\n case \"Identifier\":\n if (this.inAsync && node.name === \"await\")\n { this.raise(node.start, \"Can not use 'await' as identifier inside an async function\"); }\n break\n\n case \"ObjectPattern\":\n case \"ArrayPattern\":\n case \"RestElement\":\n break\n\n case \"ObjectExpression\":\n node.type = \"ObjectPattern\";\n if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }\n for (var i = 0, list = node.properties; i < list.length; i += 1) {\n var prop = list[i];\n\n this$1.toAssignable(prop, isBinding);\n // Early error:\n // AssignmentRestProperty[Yield, Await] :\n // `...` DestructuringAssignmentTarget[Yield, Await]\n //\n // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|.\n if (\n prop.type === \"RestElement\" &&\n (prop.argument.type === \"ArrayPattern\" || prop.argument.type === \"ObjectPattern\")\n ) {\n this$1.raise(prop.argument.start, \"Unexpected token\");\n }\n }\n break\n\n case \"Property\":\n // AssignmentProperty has type === \"Property\"\n if (node.kind !== \"init\") { this.raise(node.key.start, \"Object pattern can't contain getter or setter\"); }\n this.toAssignable(node.value, isBinding);\n break\n\n case \"ArrayExpression\":\n node.type = \"ArrayPattern\";\n if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }\n this.toAssignableList(node.elements, isBinding);\n break\n\n case \"SpreadElement\":\n node.type = \"RestElement\";\n this.toAssignable(node.argument, isBinding);\n if (node.argument.type === \"AssignmentPattern\")\n { this.raise(node.argument.start, \"Rest elements cannot have a default value\"); }\n break\n\n case \"AssignmentExpression\":\n if (node.operator !== \"=\") { this.raise(node.left.end, \"Only '=' operator can be used for specifying default value.\"); }\n node.type = \"AssignmentPattern\";\n delete node.operator;\n this.toAssignable(node.left, isBinding);\n // falls through to AssignmentPattern\n\n case \"AssignmentPattern\":\n break\n\n case \"ParenthesizedExpression\":\n this.toAssignable(node.expression, isBinding);\n break\n\n case \"MemberExpression\":\n if (!isBinding) { break }\n\n default:\n this.raise(node.start, \"Assigning to rvalue\");\n }\n } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }\n return node\n};\n\n// Convert list of expression atoms to binding list.\n\npp$2.toAssignableList = function(exprList, isBinding) {\n var this$1 = this;\n\n var end = exprList.length;\n for (var i = 0; i < end; i++) {\n var elt = exprList[i];\n if (elt) { this$1.toAssignable(elt, isBinding); }\n }\n if (end) {\n var last = exprList[end - 1];\n if (this.options.ecmaVersion === 6 && isBinding && last && last.type === \"RestElement\" && last.argument.type !== \"Identifier\")\n { this.unexpected(last.argument.start); }\n }\n return exprList\n};\n\n// Parses spread element.\n\npp$2.parseSpread = function(refDestructuringErrors) {\n var node = this.startNode();\n this.next();\n node.argument = this.parseMaybeAssign(false, refDestructuringErrors);\n return this.finishNode(node, \"SpreadElement\")\n};\n\npp$2.parseRestBinding = function() {\n var node = this.startNode();\n this.next();\n\n // RestElement inside of a function parameter must be an identifier\n if (this.options.ecmaVersion === 6 && this.type !== types.name)\n { this.unexpected(); }\n\n node.argument = this.parseBindingAtom();\n\n return this.finishNode(node, \"RestElement\")\n};\n\n// Parses lvalue (assignable) atom.\n\npp$2.parseBindingAtom = function() {\n if (this.options.ecmaVersion >= 6) {\n switch (this.type) {\n case types.bracketL:\n var node = this.startNode();\n this.next();\n node.elements = this.parseBindingList(types.bracketR, true, true);\n return this.finishNode(node, \"ArrayPattern\")\n\n case types.braceL:\n return this.parseObj(true)\n }\n }\n return this.parseIdent()\n};\n\npp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma) {\n var this$1 = this;\n\n var elts = [], first = true;\n while (!this.eat(close)) {\n if (first) { first = false; }\n else { this$1.expect(types.comma); }\n if (allowEmpty && this$1.type === types.comma) {\n elts.push(null);\n } else if (allowTrailingComma && this$1.afterTrailingComma(close)) {\n break\n } else if (this$1.type === types.ellipsis) {\n var rest = this$1.parseRestBinding();\n this$1.parseBindingListItem(rest);\n elts.push(rest);\n if (this$1.type === types.comma) { this$1.raise(this$1.start, \"Comma is not permitted after the rest element\"); }\n this$1.expect(close);\n break\n } else {\n var elem = this$1.parseMaybeDefault(this$1.start, this$1.startLoc);\n this$1.parseBindingListItem(elem);\n elts.push(elem);\n }\n }\n return elts\n};\n\npp$2.parseBindingListItem = function(param) {\n return param\n};\n\n// Parses assignment pattern around given atom if possible.\n\npp$2.parseMaybeDefault = function(startPos, startLoc, left) {\n left = left || this.parseBindingAtom();\n if (this.options.ecmaVersion < 6 || !this.eat(types.eq)) { return left }\n var node = this.startNodeAt(startPos, startLoc);\n node.left = left;\n node.right = this.parseMaybeAssign();\n return this.finishNode(node, \"AssignmentPattern\")\n};\n\n// Verify that a node is an lval — something that can be assigned\n// to.\n// bindingType can be either:\n// 'var' indicating that the lval creates a 'var' binding\n// 'let' indicating that the lval creates a lexical ('let' or 'const') binding\n// 'none' indicating that the binding should be checked for illegal identifiers, but not for duplicate references\n\npp$2.checkLVal = function(expr, bindingType, checkClashes) {\n var this$1 = this;\n\n switch (expr.type) {\n case \"Identifier\":\n if (this.strict && this.reservedWordsStrictBind.test(expr.name))\n { this.raiseRecoverable(expr.start, (bindingType ? \"Binding \" : \"Assigning to \") + expr.name + \" in strict mode\"); }\n if (checkClashes) {\n if (has(checkClashes, expr.name))\n { this.raiseRecoverable(expr.start, \"Argument name clash\"); }\n checkClashes[expr.name] = true;\n }\n if (bindingType && bindingType !== \"none\") {\n if (\n bindingType === \"var\" && !this.canDeclareVarName(expr.name) ||\n bindingType !== \"var\" && !this.canDeclareLexicalName(expr.name)\n ) {\n this.raiseRecoverable(expr.start, (\"Identifier '\" + (expr.name) + \"' has already been declared\"));\n }\n if (bindingType === \"var\") {\n this.declareVarName(expr.name);\n } else {\n this.declareLexicalName(expr.name);\n }\n }\n break\n\n case \"MemberExpression\":\n if (bindingType) { this.raiseRecoverable(expr.start, \"Binding member expression\"); }\n break\n\n case \"ObjectPattern\":\n for (var i = 0, list = expr.properties; i < list.length; i += 1)\n {\n var prop = list[i];\n\n this$1.checkLVal(prop, bindingType, checkClashes);\n }\n break\n\n case \"Property\":\n // AssignmentProperty has type === \"Property\"\n this.checkLVal(expr.value, bindingType, checkClashes);\n break\n\n case \"ArrayPattern\":\n for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) {\n var elem = list$1[i$1];\n\n if (elem) { this$1.checkLVal(elem, bindingType, checkClashes); }\n }\n break\n\n case \"AssignmentPattern\":\n this.checkLVal(expr.left, bindingType, checkClashes);\n break\n\n case \"RestElement\":\n this.checkLVal(expr.argument, bindingType, checkClashes);\n break\n\n case \"ParenthesizedExpression\":\n this.checkLVal(expr.expression, bindingType, checkClashes);\n break\n\n default:\n this.raise(expr.start, (bindingType ? \"Binding\" : \"Assigning to\") + \" rvalue\");\n }\n};\n\n// A recursive descent parser operates by defining functions for all\n// syntactic elements, and recursively calling those, each function\n// advancing the input stream and returning an AST node. Precedence\n// of constructs (for example, the fact that `!x[1]` means `!(x[1])`\n// instead of `(!x)[1]` is handled by the fact that the parser\n// function that parses unary prefix operators is called first, and\n// in turn calls the function that parses `[]` subscripts — that\n// way, it'll receive the node for `x[1]` already parsed, and wraps\n// *that* in the unary operator node.\n//\n// Acorn uses an [operator precedence parser][opp] to handle binary\n// operator precedence, because it is much more compact than using\n// the technique outlined above, which uses different, nesting\n// functions to specify precedence, for all of the ten binary\n// precedence levels that JavaScript defines.\n//\n// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser\n\nvar pp$3 = Parser.prototype;\n\n// Check if property name clashes with already added.\n// Object/class getters and setters are not allowed to clash —\n// either with each other or with an init property — and in\n// strict mode, init properties are also not allowed to be repeated.\n\npp$3.checkPropClash = function(prop, propHash, refDestructuringErrors) {\n if (this.options.ecmaVersion >= 9 && prop.type === \"SpreadElement\")\n { return }\n if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand))\n { return }\n var key = prop.key;\n var name;\n switch (key.type) {\n case \"Identifier\": name = key.name; break\n case \"Literal\": name = String(key.value); break\n default: return\n }\n var kind = prop.kind;\n if (this.options.ecmaVersion >= 6) {\n if (name === \"__proto__\" && kind === \"init\") {\n if (propHash.proto) {\n if (refDestructuringErrors && refDestructuringErrors.doubleProto < 0) { refDestructuringErrors.doubleProto = key.start; }\n // Backwards-compat kludge. Can be removed in version 6.0\n else { this.raiseRecoverable(key.start, \"Redefinition of __proto__ property\"); }\n }\n propHash.proto = true;\n }\n return\n }\n name = \"$\" + name;\n var other = propHash[name];\n if (other) {\n var redefinition;\n if (kind === \"init\") {\n redefinition = this.strict && other.init || other.get || other.set;\n } else {\n redefinition = other.init || other[kind];\n }\n if (redefinition)\n { this.raiseRecoverable(key.start, \"Redefinition of property\"); }\n } else {\n other = propHash[name] = {\n init: false,\n get: false,\n set: false\n };\n }\n other[kind] = true;\n};\n\n// ### Expression parsing\n\n// These nest, from the most general expression type at the top to\n// 'atomic', nondivisible expression types at the bottom. Most of\n// the functions will simply let the function(s) below them parse,\n// and, *if* the syntactic construct they handle is present, wrap\n// the AST node that the inner parser gave them in another node.\n\n// Parse a full expression. The optional arguments are used to\n// forbid the `in` operator (in for loops initalization expressions)\n// and provide reference for storing '=' operator inside shorthand\n// property assignment in contexts where both object expression\n// and object pattern might appear (so it's possible to raise\n// delayed syntax error at correct position).\n\npp$3.parseExpression = function(noIn, refDestructuringErrors) {\n var this$1 = this;\n\n var startPos = this.start, startLoc = this.startLoc;\n var expr = this.parseMaybeAssign(noIn, refDestructuringErrors);\n if (this.type === types.comma) {\n var node = this.startNodeAt(startPos, startLoc);\n node.expressions = [expr];\n while (this.eat(types.comma)) { node.expressions.push(this$1.parseMaybeAssign(noIn, refDestructuringErrors)); }\n return this.finishNode(node, \"SequenceExpression\")\n }\n return expr\n};\n\n// Parse an assignment expression. This includes applications of\n// operators like `+=`.\n\npp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) {\n if (this.inGenerator && this.isContextual(\"yield\")) { return this.parseYield() }\n\n var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1;\n if (refDestructuringErrors) {\n oldParenAssign = refDestructuringErrors.parenthesizedAssign;\n oldTrailingComma = refDestructuringErrors.trailingComma;\n refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1;\n } else {\n refDestructuringErrors = new DestructuringErrors;\n ownDestructuringErrors = true;\n }\n\n var startPos = this.start, startLoc = this.startLoc;\n if (this.type === types.parenL || this.type === types.name)\n { this.potentialArrowAt = this.start; }\n var left = this.parseMaybeConditional(noIn, refDestructuringErrors);\n if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); }\n if (this.type.isAssign) {\n var node = this.startNodeAt(startPos, startLoc);\n node.operator = this.value;\n node.left = this.type === types.eq ? this.toAssignable(left, false, refDestructuringErrors) : left;\n if (!ownDestructuringErrors) { DestructuringErrors.call(refDestructuringErrors); }\n refDestructuringErrors.shorthandAssign = -1; // reset because shorthand default was used correctly\n this.checkLVal(left);\n this.next();\n node.right = this.parseMaybeAssign(noIn);\n return this.finishNode(node, \"AssignmentExpression\")\n } else {\n if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); }\n }\n if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; }\n if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; }\n return left\n};\n\n// Parse a ternary conditional (`?:`) operator.\n\npp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) {\n var startPos = this.start, startLoc = this.startLoc;\n var expr = this.parseExprOps(noIn, refDestructuringErrors);\n if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }\n if (this.eat(types.question)) {\n var node = this.startNodeAt(startPos, startLoc);\n node.test = expr;\n node.consequent = this.parseMaybeAssign();\n this.expect(types.colon);\n node.alternate = this.parseMaybeAssign(noIn);\n return this.finishNode(node, \"ConditionalExpression\")\n }\n return expr\n};\n\n// Start the precedence parser.\n\npp$3.parseExprOps = function(noIn, refDestructuringErrors) {\n var startPos = this.start, startLoc = this.startLoc;\n var expr = this.parseMaybeUnary(refDestructuringErrors, false);\n if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }\n return expr.start === startPos && expr.type === \"ArrowFunctionExpression\" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn)\n};\n\n// Parse binary operators with the operator precedence parsing\n// algorithm. `left` is the left-hand side of the operator.\n// `minPrec` provides context that allows the function to stop and\n// defer further parser to one of its callers when it encounters an\n// operator that has a lower precedence than the set it is parsing.\n\npp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) {\n var prec = this.type.binop;\n if (prec != null && (!noIn || this.type !== types._in)) {\n if (prec > minPrec) {\n var logical = this.type === types.logicalOR || this.type === types.logicalAND;\n var op = this.value;\n this.next();\n var startPos = this.start, startLoc = this.startLoc;\n var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn);\n var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical);\n return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn)\n }\n }\n return left\n};\n\npp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) {\n var node = this.startNodeAt(startPos, startLoc);\n node.left = left;\n node.operator = op;\n node.right = right;\n return this.finishNode(node, logical ? \"LogicalExpression\" : \"BinaryExpression\")\n};\n\n// Parse unary operators, both prefix and postfix.\n\npp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) {\n var this$1 = this;\n\n var startPos = this.start, startLoc = this.startLoc, expr;\n if (this.isContextual(\"await\") && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction))) {\n expr = this.parseAwait();\n sawUnary = true;\n } else if (this.type.prefix) {\n var node = this.startNode(), update = this.type === types.incDec;\n node.operator = this.value;\n node.prefix = true;\n this.next();\n node.argument = this.parseMaybeUnary(null, true);\n this.checkExpressionErrors(refDestructuringErrors, true);\n if (update) { this.checkLVal(node.argument); }\n else if (this.strict && node.operator === \"delete\" &&\n node.argument.type === \"Identifier\")\n { this.raiseRecoverable(node.start, \"Deleting local variable in strict mode\"); }\n else { sawUnary = true; }\n expr = this.finishNode(node, update ? \"UpdateExpression\" : \"UnaryExpression\");\n } else {\n expr = this.parseExprSubscripts(refDestructuringErrors);\n if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }\n while (this.type.postfix && !this.canInsertSemicolon()) {\n var node$1 = this$1.startNodeAt(startPos, startLoc);\n node$1.operator = this$1.value;\n node$1.prefix = false;\n node$1.argument = expr;\n this$1.checkLVal(expr);\n this$1.next();\n expr = this$1.finishNode(node$1, \"UpdateExpression\");\n }\n }\n\n if (!sawUnary && this.eat(types.starstar))\n { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), \"**\", false) }\n else\n { return expr }\n};\n\n// Parse call, dot, and `[]`-subscript expressions.\n\npp$3.parseExprSubscripts = function(refDestructuringErrors) {\n var startPos = this.start, startLoc = this.startLoc;\n var expr = this.parseExprAtom(refDestructuringErrors);\n var skipArrowSubscripts = expr.type === \"ArrowFunctionExpression\" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== \")\";\n if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) { return expr }\n var result = this.parseSubscripts(expr, startPos, startLoc);\n if (refDestructuringErrors && result.type === \"MemberExpression\") {\n if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; }\n if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; }\n }\n return result\n};\n\npp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) {\n var this$1 = this;\n\n var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === \"Identifier\" && base.name === \"async\" &&\n this.lastTokEnd === base.end && !this.canInsertSemicolon() && this.input.slice(base.start, base.end) === \"async\";\n for (var computed = (void 0);;) {\n if ((computed = this$1.eat(types.bracketL)) || this$1.eat(types.dot)) {\n var node = this$1.startNodeAt(startPos, startLoc);\n node.object = base;\n node.property = computed ? this$1.parseExpression() : this$1.parseIdent(true);\n node.computed = !!computed;\n if (computed) { this$1.expect(types.bracketR); }\n base = this$1.finishNode(node, \"MemberExpression\");\n } else if (!noCalls && this$1.eat(types.parenL)) {\n var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this$1.yieldPos, oldAwaitPos = this$1.awaitPos;\n this$1.yieldPos = 0;\n this$1.awaitPos = 0;\n var exprList = this$1.parseExprList(types.parenR, this$1.options.ecmaVersion >= 8, false, refDestructuringErrors);\n if (maybeAsyncArrow && !this$1.canInsertSemicolon() && this$1.eat(types.arrow)) {\n this$1.checkPatternErrors(refDestructuringErrors, false);\n this$1.checkYieldAwaitInDefaultParams();\n this$1.yieldPos = oldYieldPos;\n this$1.awaitPos = oldAwaitPos;\n return this$1.parseArrowExpression(this$1.startNodeAt(startPos, startLoc), exprList, true)\n }\n this$1.checkExpressionErrors(refDestructuringErrors, true);\n this$1.yieldPos = oldYieldPos || this$1.yieldPos;\n this$1.awaitPos = oldAwaitPos || this$1.awaitPos;\n var node$1 = this$1.startNodeAt(startPos, startLoc);\n node$1.callee = base;\n node$1.arguments = exprList;\n base = this$1.finishNode(node$1, \"CallExpression\");\n } else if (this$1.type === types.backQuote) {\n var node$2 = this$1.startNodeAt(startPos, startLoc);\n node$2.tag = base;\n node$2.quasi = this$1.parseTemplate({isTagged: true});\n base = this$1.finishNode(node$2, \"TaggedTemplateExpression\");\n } else {\n return base\n }\n }\n};\n\n// Parse an atomic expression — either a single token that is an\n// expression, an expression started by a keyword like `function` or\n// `new`, or an expression wrapped in punctuation like `()`, `[]`,\n// or `{}`.\n\npp$3.parseExprAtom = function(refDestructuringErrors) {\n var node, canBeArrow = this.potentialArrowAt === this.start;\n switch (this.type) {\n case types._super:\n if (!this.inFunction)\n { this.raise(this.start, \"'super' outside of function or class\"); }\n node = this.startNode();\n this.next();\n // The `super` keyword can appear at below:\n // SuperProperty:\n // super [ Expression ]\n // super . IdentifierName\n // SuperCall:\n // super Arguments\n if (this.type !== types.dot && this.type !== types.bracketL && this.type !== types.parenL)\n { this.unexpected(); }\n return this.finishNode(node, \"Super\")\n\n case types._this:\n node = this.startNode();\n this.next();\n return this.finishNode(node, \"ThisExpression\")\n\n case types.name:\n var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc;\n var id = this.parseIdent(this.type !== types.name);\n if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === \"async\" && !this.canInsertSemicolon() && this.eat(types._function))\n { return this.parseFunction(this.startNodeAt(startPos, startLoc), false, false, true) }\n if (canBeArrow && !this.canInsertSemicolon()) {\n if (this.eat(types.arrow))\n { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) }\n if (this.options.ecmaVersion >= 8 && id.name === \"async\" && this.type === types.name && !containsEsc) {\n id = this.parseIdent();\n if (this.canInsertSemicolon() || !this.eat(types.arrow))\n { this.unexpected(); }\n return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true)\n }\n }\n return id\n\n case types.regexp:\n var value = this.value;\n node = this.parseLiteral(value.value);\n node.regex = {pattern: value.pattern, flags: value.flags};\n return node\n\n case types.num: case types.string:\n return this.parseLiteral(this.value)\n\n case types._null: case types._true: case types._false:\n node = this.startNode();\n node.value = this.type === types._null ? null : this.type === types._true;\n node.raw = this.type.keyword;\n this.next();\n return this.finishNode(node, \"Literal\")\n\n case types.parenL:\n var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow);\n if (refDestructuringErrors) {\n if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr))\n { refDestructuringErrors.parenthesizedAssign = start; }\n if (refDestructuringErrors.parenthesizedBind < 0)\n { refDestructuringErrors.parenthesizedBind = start; }\n }\n return expr\n\n case types.bracketL:\n node = this.startNode();\n this.next();\n node.elements = this.parseExprList(types.bracketR, true, true, refDestructuringErrors);\n return this.finishNode(node, \"ArrayExpression\")\n\n case types.braceL:\n return this.parseObj(false, refDestructuringErrors)\n\n case types._function:\n node = this.startNode();\n this.next();\n return this.parseFunction(node, false)\n\n case types._class:\n return this.parseClass(this.startNode(), false)\n\n case types._new:\n return this.parseNew()\n\n case types.backQuote:\n return this.parseTemplate()\n\n default:\n this.unexpected();\n }\n};\n\npp$3.parseLiteral = function(value) {\n var node = this.startNode();\n node.value = value;\n node.raw = this.input.slice(this.start, this.end);\n this.next();\n return this.finishNode(node, \"Literal\")\n};\n\npp$3.parseParenExpression = function() {\n this.expect(types.parenL);\n var val = this.parseExpression();\n this.expect(types.parenR);\n return val\n};\n\npp$3.parseParenAndDistinguishExpression = function(canBeArrow) {\n var this$1 = this;\n\n var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8;\n if (this.options.ecmaVersion >= 6) {\n this.next();\n\n var innerStartPos = this.start, innerStartLoc = this.startLoc;\n var exprList = [], first = true, lastIsComma = false;\n var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart;\n this.yieldPos = 0;\n this.awaitPos = 0;\n while (this.type !== types.parenR) {\n first ? first = false : this$1.expect(types.comma);\n if (allowTrailingComma && this$1.afterTrailingComma(types.parenR, true)) {\n lastIsComma = true;\n break\n } else if (this$1.type === types.ellipsis) {\n spreadStart = this$1.start;\n exprList.push(this$1.parseParenItem(this$1.parseRestBinding()));\n if (this$1.type === types.comma) { this$1.raise(this$1.start, \"Comma is not permitted after the rest element\"); }\n break\n } else {\n exprList.push(this$1.parseMaybeAssign(false, refDestructuringErrors, this$1.parseParenItem));\n }\n }\n var innerEndPos = this.start, innerEndLoc = this.startLoc;\n this.expect(types.parenR);\n\n if (canBeArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) {\n this.checkPatternErrors(refDestructuringErrors, false);\n this.checkYieldAwaitInDefaultParams();\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n return this.parseParenArrowList(startPos, startLoc, exprList)\n }\n\n if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); }\n if (spreadStart) { this.unexpected(spreadStart); }\n this.checkExpressionErrors(refDestructuringErrors, true);\n this.yieldPos = oldYieldPos || this.yieldPos;\n this.awaitPos = oldAwaitPos || this.awaitPos;\n\n if (exprList.length > 1) {\n val = this.startNodeAt(innerStartPos, innerStartLoc);\n val.expressions = exprList;\n this.finishNodeAt(val, \"SequenceExpression\", innerEndPos, innerEndLoc);\n } else {\n val = exprList[0];\n }\n } else {\n val = this.parseParenExpression();\n }\n\n if (this.options.preserveParens) {\n var par = this.startNodeAt(startPos, startLoc);\n par.expression = val;\n return this.finishNode(par, \"ParenthesizedExpression\")\n } else {\n return val\n }\n};\n\npp$3.parseParenItem = function(item) {\n return item\n};\n\npp$3.parseParenArrowList = function(startPos, startLoc, exprList) {\n return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList)\n};\n\n// New's precedence is slightly tricky. It must allow its argument to\n// be a `[]` or dot subscript expression, but not a call — at least,\n// not without wrapping it in parentheses. Thus, it uses the noCalls\n// argument to parseSubscripts to prevent it from consuming the\n// argument list.\n\nvar empty$1 = [];\n\npp$3.parseNew = function() {\n var node = this.startNode();\n var meta = this.parseIdent(true);\n if (this.options.ecmaVersion >= 6 && this.eat(types.dot)) {\n node.meta = meta;\n var containsEsc = this.containsEsc;\n node.property = this.parseIdent(true);\n if (node.property.name !== \"target\" || containsEsc)\n { this.raiseRecoverable(node.property.start, \"The only valid meta property for new is new.target\"); }\n if (!this.inFunction)\n { this.raiseRecoverable(node.start, \"new.target can only be used in functions\"); }\n return this.finishNode(node, \"MetaProperty\")\n }\n var startPos = this.start, startLoc = this.startLoc;\n node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true);\n if (this.eat(types.parenL)) { node.arguments = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false); }\n else { node.arguments = empty$1; }\n return this.finishNode(node, \"NewExpression\")\n};\n\n// Parse template expression.\n\npp$3.parseTemplateElement = function(ref) {\n var isTagged = ref.isTagged;\n\n var elem = this.startNode();\n if (this.type === types.invalidTemplate) {\n if (!isTagged) {\n this.raiseRecoverable(this.start, \"Bad escape sequence in untagged template literal\");\n }\n elem.value = {\n raw: this.value,\n cooked: null\n };\n } else {\n elem.value = {\n raw: this.input.slice(this.start, this.end).replace(/\\r\\n?/g, \"\\n\"),\n cooked: this.value\n };\n }\n this.next();\n elem.tail = this.type === types.backQuote;\n return this.finishNode(elem, \"TemplateElement\")\n};\n\npp$3.parseTemplate = function(ref) {\n var this$1 = this;\n if ( ref === void 0 ) ref = {};\n var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false;\n\n var node = this.startNode();\n this.next();\n node.expressions = [];\n var curElt = this.parseTemplateElement({isTagged: isTagged});\n node.quasis = [curElt];\n while (!curElt.tail) {\n if (this$1.type === types.eof) { this$1.raise(this$1.pos, \"Unterminated template literal\"); }\n this$1.expect(types.dollarBraceL);\n node.expressions.push(this$1.parseExpression());\n this$1.expect(types.braceR);\n node.quasis.push(curElt = this$1.parseTemplateElement({isTagged: isTagged}));\n }\n this.next();\n return this.finishNode(node, \"TemplateLiteral\")\n};\n\npp$3.isAsyncProp = function(prop) {\n return !prop.computed && prop.key.type === \"Identifier\" && prop.key.name === \"async\" &&\n (this.type === types.name || this.type === types.num || this.type === types.string || this.type === types.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types.star)) &&\n !lineBreak.test(this.input.slice(this.lastTokEnd, this.start))\n};\n\n// Parse an object literal or binding pattern.\n\npp$3.parseObj = function(isPattern, refDestructuringErrors) {\n var this$1 = this;\n\n var node = this.startNode(), first = true, propHash = {};\n node.properties = [];\n this.next();\n while (!this.eat(types.braceR)) {\n if (!first) {\n this$1.expect(types.comma);\n if (this$1.afterTrailingComma(types.braceR)) { break }\n } else { first = false; }\n\n var prop = this$1.parseProperty(isPattern, refDestructuringErrors);\n if (!isPattern) { this$1.checkPropClash(prop, propHash, refDestructuringErrors); }\n node.properties.push(prop);\n }\n return this.finishNode(node, isPattern ? \"ObjectPattern\" : \"ObjectExpression\")\n};\n\npp$3.parseProperty = function(isPattern, refDestructuringErrors) {\n var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc;\n if (this.options.ecmaVersion >= 9 && this.eat(types.ellipsis)) {\n if (isPattern) {\n prop.argument = this.parseIdent(false);\n if (this.type === types.comma) {\n this.raise(this.start, \"Comma is not permitted after the rest element\");\n }\n return this.finishNode(prop, \"RestElement\")\n }\n // To disallow parenthesized identifier via `this.toAssignable()`.\n if (this.type === types.parenL && refDestructuringErrors) {\n if (refDestructuringErrors.parenthesizedAssign < 0) {\n refDestructuringErrors.parenthesizedAssign = this.start;\n }\n if (refDestructuringErrors.parenthesizedBind < 0) {\n refDestructuringErrors.parenthesizedBind = this.start;\n }\n }\n // Parse argument.\n prop.argument = this.parseMaybeAssign(false, refDestructuringErrors);\n // To disallow trailing comma via `this.toAssignable()`.\n if (this.type === types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) {\n refDestructuringErrors.trailingComma = this.start;\n }\n // Finish\n return this.finishNode(prop, \"SpreadElement\")\n }\n if (this.options.ecmaVersion >= 6) {\n prop.method = false;\n prop.shorthand = false;\n if (isPattern || refDestructuringErrors) {\n startPos = this.start;\n startLoc = this.startLoc;\n }\n if (!isPattern)\n { isGenerator = this.eat(types.star); }\n }\n var containsEsc = this.containsEsc;\n this.parsePropertyName(prop);\n if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) {\n isAsync = true;\n isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star);\n this.parsePropertyName(prop, refDestructuringErrors);\n } else {\n isAsync = false;\n }\n this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc);\n return this.finishNode(prop, \"Property\")\n};\n\npp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) {\n if ((isGenerator || isAsync) && this.type === types.colon)\n { this.unexpected(); }\n\n if (this.eat(types.colon)) {\n prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors);\n prop.kind = \"init\";\n } else if (this.options.ecmaVersion >= 6 && this.type === types.parenL) {\n if (isPattern) { this.unexpected(); }\n prop.kind = \"init\";\n prop.method = true;\n prop.value = this.parseMethod(isGenerator, isAsync);\n } else if (!isPattern && !containsEsc &&\n this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === \"Identifier\" &&\n (prop.key.name === \"get\" || prop.key.name === \"set\") &&\n (this.type !== types.comma && this.type !== types.braceR)) {\n if (isGenerator || isAsync) { this.unexpected(); }\n prop.kind = prop.key.name;\n this.parsePropertyName(prop);\n prop.value = this.parseMethod(false);\n var paramCount = prop.kind === \"get\" ? 0 : 1;\n if (prop.value.params.length !== paramCount) {\n var start = prop.value.start;\n if (prop.kind === \"get\")\n { this.raiseRecoverable(start, \"getter should have no params\"); }\n else\n { this.raiseRecoverable(start, \"setter should have exactly one param\"); }\n } else {\n if (prop.kind === \"set\" && prop.value.params[0].type === \"RestElement\")\n { this.raiseRecoverable(prop.value.params[0].start, \"Setter cannot use rest params\"); }\n }\n } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === \"Identifier\") {\n this.checkUnreserved(prop.key);\n prop.kind = \"init\";\n if (isPattern) {\n prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);\n } else if (this.type === types.eq && refDestructuringErrors) {\n if (refDestructuringErrors.shorthandAssign < 0)\n { refDestructuringErrors.shorthandAssign = this.start; }\n prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);\n } else {\n prop.value = prop.key;\n }\n prop.shorthand = true;\n } else { this.unexpected(); }\n};\n\npp$3.parsePropertyName = function(prop) {\n if (this.options.ecmaVersion >= 6) {\n if (this.eat(types.bracketL)) {\n prop.computed = true;\n prop.key = this.parseMaybeAssign();\n this.expect(types.bracketR);\n return prop.key\n } else {\n prop.computed = false;\n }\n }\n return prop.key = this.type === types.num || this.type === types.string ? this.parseExprAtom() : this.parseIdent(true)\n};\n\n// Initialize empty function node.\n\npp$3.initFunction = function(node) {\n node.id = null;\n if (this.options.ecmaVersion >= 6) {\n node.generator = false;\n node.expression = false;\n }\n if (this.options.ecmaVersion >= 8)\n { node.async = false; }\n};\n\n// Parse object or class method.\n\npp$3.parseMethod = function(isGenerator, isAsync) {\n var node = this.startNode(), oldInGen = this.inGenerator, oldInAsync = this.inAsync,\n oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction;\n\n this.initFunction(node);\n if (this.options.ecmaVersion >= 6)\n { node.generator = isGenerator; }\n if (this.options.ecmaVersion >= 8)\n { node.async = !!isAsync; }\n\n this.inGenerator = node.generator;\n this.inAsync = node.async;\n this.yieldPos = 0;\n this.awaitPos = 0;\n this.inFunction = true;\n this.enterFunctionScope();\n\n this.expect(types.parenL);\n node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8);\n this.checkYieldAwaitInDefaultParams();\n this.parseFunctionBody(node, false);\n\n this.inGenerator = oldInGen;\n this.inAsync = oldInAsync;\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n this.inFunction = oldInFunc;\n return this.finishNode(node, \"FunctionExpression\")\n};\n\n// Parse arrow function expression with given parameters.\n\npp$3.parseArrowExpression = function(node, params, isAsync) {\n var oldInGen = this.inGenerator, oldInAsync = this.inAsync,\n oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction;\n\n this.enterFunctionScope();\n this.initFunction(node);\n if (this.options.ecmaVersion >= 8)\n { node.async = !!isAsync; }\n\n this.inGenerator = false;\n this.inAsync = node.async;\n this.yieldPos = 0;\n this.awaitPos = 0;\n this.inFunction = true;\n\n node.params = this.toAssignableList(params, true);\n this.parseFunctionBody(node, true);\n\n this.inGenerator = oldInGen;\n this.inAsync = oldInAsync;\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n this.inFunction = oldInFunc;\n return this.finishNode(node, \"ArrowFunctionExpression\")\n};\n\n// Parse function body and check parameters.\n\npp$3.parseFunctionBody = function(node, isArrowFunction) {\n var isExpression = isArrowFunction && this.type !== types.braceL;\n var oldStrict = this.strict, useStrict = false;\n\n if (isExpression) {\n node.body = this.parseMaybeAssign();\n node.expression = true;\n this.checkParams(node, false);\n } else {\n var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params);\n if (!oldStrict || nonSimple) {\n useStrict = this.strictDirective(this.end);\n // If this is a strict mode function, verify that argument names\n // are not repeated, and it does not try to bind the words `eval`\n // or `arguments`.\n if (useStrict && nonSimple)\n { this.raiseRecoverable(node.start, \"Illegal 'use strict' directive in function with non-simple parameter list\"); }\n }\n // Start a new scope with regard to labels and the `inFunction`\n // flag (restore them to their old value afterwards).\n var oldLabels = this.labels;\n this.labels = [];\n if (useStrict) { this.strict = true; }\n\n // Add the params to varDeclaredNames to ensure that an error is thrown\n // if a let/const declaration in the function clashes with one of the params.\n this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && this.isSimpleParamList(node.params));\n node.body = this.parseBlock(false);\n node.expression = false;\n this.adaptDirectivePrologue(node.body.body);\n this.labels = oldLabels;\n }\n this.exitFunctionScope();\n\n if (this.strict && node.id) {\n // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval'\n this.checkLVal(node.id, \"none\");\n }\n this.strict = oldStrict;\n};\n\npp$3.isSimpleParamList = function(params) {\n for (var i = 0, list = params; i < list.length; i += 1)\n {\n var param = list[i];\n\n if (param.type !== \"Identifier\") { return false\n } }\n return true\n};\n\n// Checks function params for various disallowed patterns such as using \"eval\"\n// or \"arguments\" and duplicate parameters.\n\npp$3.checkParams = function(node, allowDuplicates) {\n var this$1 = this;\n\n var nameHash = {};\n for (var i = 0, list = node.params; i < list.length; i += 1)\n {\n var param = list[i];\n\n this$1.checkLVal(param, \"var\", allowDuplicates ? null : nameHash);\n }\n};\n\n// Parses a comma-separated list of expressions, and returns them as\n// an array. `close` is the token type that ends the list, and\n// `allowEmpty` can be turned on to allow subsequent commas with\n// nothing in between them to be parsed as `null` (which is needed\n// for array literals).\n\npp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) {\n var this$1 = this;\n\n var elts = [], first = true;\n while (!this.eat(close)) {\n if (!first) {\n this$1.expect(types.comma);\n if (allowTrailingComma && this$1.afterTrailingComma(close)) { break }\n } else { first = false; }\n\n var elt = (void 0);\n if (allowEmpty && this$1.type === types.comma)\n { elt = null; }\n else if (this$1.type === types.ellipsis) {\n elt = this$1.parseSpread(refDestructuringErrors);\n if (refDestructuringErrors && this$1.type === types.comma && refDestructuringErrors.trailingComma < 0)\n { refDestructuringErrors.trailingComma = this$1.start; }\n } else {\n elt = this$1.parseMaybeAssign(false, refDestructuringErrors);\n }\n elts.push(elt);\n }\n return elts\n};\n\npp$3.checkUnreserved = function(ref) {\n var start = ref.start;\n var end = ref.end;\n var name = ref.name;\n\n if (this.inGenerator && name === \"yield\")\n { this.raiseRecoverable(start, \"Can not use 'yield' as identifier inside a generator\"); }\n if (this.inAsync && name === \"await\")\n { this.raiseRecoverable(start, \"Can not use 'await' as identifier inside an async function\"); }\n if (this.isKeyword(name))\n { this.raise(start, (\"Unexpected keyword '\" + name + \"'\")); }\n if (this.options.ecmaVersion < 6 &&\n this.input.slice(start, end).indexOf(\"\\\\\") !== -1) { return }\n var re = this.strict ? this.reservedWordsStrict : this.reservedWords;\n if (re.test(name)) {\n if (!this.inAsync && name === \"await\")\n { this.raiseRecoverable(start, \"Can not use keyword 'await' outside an async function\"); }\n this.raiseRecoverable(start, (\"The keyword '\" + name + \"' is reserved\"));\n }\n};\n\n// Parse the next token as an identifier. If `liberal` is true (used\n// when parsing properties), it will also convert keywords into\n// identifiers.\n\npp$3.parseIdent = function(liberal, isBinding) {\n var node = this.startNode();\n if (liberal && this.options.allowReserved === \"never\") { liberal = false; }\n if (this.type === types.name) {\n node.name = this.value;\n } else if (this.type.keyword) {\n node.name = this.type.keyword;\n\n // To fix https://github.com/acornjs/acorn/issues/575\n // `class` and `function` keywords push new context into this.context.\n // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name.\n // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword\n if ((node.name === \"class\" || node.name === \"function\") &&\n (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) {\n this.context.pop();\n }\n } else {\n this.unexpected();\n }\n this.next();\n this.finishNode(node, \"Identifier\");\n if (!liberal) { this.checkUnreserved(node); }\n return node\n};\n\n// Parses yield expression inside generator.\n\npp$3.parseYield = function() {\n if (!this.yieldPos) { this.yieldPos = this.start; }\n\n var node = this.startNode();\n this.next();\n if (this.type === types.semi || this.canInsertSemicolon() || (this.type !== types.star && !this.type.startsExpr)) {\n node.delegate = false;\n node.argument = null;\n } else {\n node.delegate = this.eat(types.star);\n node.argument = this.parseMaybeAssign();\n }\n return this.finishNode(node, \"YieldExpression\")\n};\n\npp$3.parseAwait = function() {\n if (!this.awaitPos) { this.awaitPos = this.start; }\n\n var node = this.startNode();\n this.next();\n node.argument = this.parseMaybeUnary(null, true);\n return this.finishNode(node, \"AwaitExpression\")\n};\n\nvar pp$4 = Parser.prototype;\n\n// This function is used to raise exceptions on parse errors. It\n// takes an offset integer (into the current `input`) to indicate\n// the location of the error, attaches the position to the end\n// of the error message, and then raises a `SyntaxError` with that\n// message.\n\npp$4.raise = function(pos, message) {\n var loc = getLineInfo(this.input, pos);\n message += \" (\" + loc.line + \":\" + loc.column + \")\";\n var err = new SyntaxError(message);\n err.pos = pos; err.loc = loc; err.raisedAt = this.pos;\n throw err\n};\n\npp$4.raiseRecoverable = pp$4.raise;\n\npp$4.curPosition = function() {\n if (this.options.locations) {\n return new Position(this.curLine, this.pos - this.lineStart)\n }\n};\n\nvar pp$5 = Parser.prototype;\n\n// Object.assign polyfill\nvar assign = Object.assign || function(target) {\n var sources = [], len = arguments.length - 1;\n while ( len-- > 0 ) sources[ len ] = arguments[ len + 1 ];\n\n for (var i = 0, list = sources; i < list.length; i += 1) {\n var source = list[i];\n\n for (var key in source) {\n if (has(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target\n};\n\n// The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names.\n\npp$5.enterFunctionScope = function() {\n // var: a hash of var-declared names in the current lexical scope\n // lexical: a hash of lexically-declared names in the current lexical scope\n // childVar: a hash of var-declared names in all child lexical scopes of the current lexical scope (within the current function scope)\n // parentLexical: a hash of lexically-declared names in all parent lexical scopes of the current lexical scope (within the current function scope)\n this.scopeStack.push({var: {}, lexical: {}, childVar: {}, parentLexical: {}});\n};\n\npp$5.exitFunctionScope = function() {\n this.scopeStack.pop();\n};\n\npp$5.enterLexicalScope = function() {\n var parentScope = this.scopeStack[this.scopeStack.length - 1];\n var childScope = {var: {}, lexical: {}, childVar: {}, parentLexical: {}};\n\n this.scopeStack.push(childScope);\n assign(childScope.parentLexical, parentScope.lexical, parentScope.parentLexical);\n};\n\npp$5.exitLexicalScope = function() {\n var childScope = this.scopeStack.pop();\n var parentScope = this.scopeStack[this.scopeStack.length - 1];\n\n assign(parentScope.childVar, childScope.var, childScope.childVar);\n};\n\n/**\n * A name can be declared with `var` if there are no variables with the same name declared with `let`/`const`\n * in the current lexical scope or any of the parent lexical scopes in this function.\n */\npp$5.canDeclareVarName = function(name) {\n var currentScope = this.scopeStack[this.scopeStack.length - 1];\n\n return !has(currentScope.lexical, name) && !has(currentScope.parentLexical, name)\n};\n\n/**\n * A name can be declared with `let`/`const` if there are no variables with the same name declared with `let`/`const`\n * in the current scope, and there are no variables with the same name declared with `var` in the current scope or in\n * any child lexical scopes in this function.\n */\npp$5.canDeclareLexicalName = function(name) {\n var currentScope = this.scopeStack[this.scopeStack.length - 1];\n\n return !has(currentScope.lexical, name) && !has(currentScope.var, name) && !has(currentScope.childVar, name)\n};\n\npp$5.declareVarName = function(name) {\n this.scopeStack[this.scopeStack.length - 1].var[name] = true;\n};\n\npp$5.declareLexicalName = function(name) {\n this.scopeStack[this.scopeStack.length - 1].lexical[name] = true;\n};\n\nvar Node = function Node(parser, pos, loc) {\n this.type = \"\";\n this.start = pos;\n this.end = 0;\n if (parser.options.locations)\n { this.loc = new SourceLocation(parser, loc); }\n if (parser.options.directSourceFile)\n { this.sourceFile = parser.options.directSourceFile; }\n if (parser.options.ranges)\n { this.range = [pos, 0]; }\n};\n\n// Start an AST node, attaching a start offset.\n\nvar pp$6 = Parser.prototype;\n\npp$6.startNode = function() {\n return new Node(this, this.start, this.startLoc)\n};\n\npp$6.startNodeAt = function(pos, loc) {\n return new Node(this, pos, loc)\n};\n\n// Finish an AST node, adding `type` and `end` properties.\n\nfunction finishNodeAt(node, type, pos, loc) {\n node.type = type;\n node.end = pos;\n if (this.options.locations)\n { node.loc.end = loc; }\n if (this.options.ranges)\n { node.range[1] = pos; }\n return node\n}\n\npp$6.finishNode = function(node, type) {\n return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc)\n};\n\n// Finish node at given position\n\npp$6.finishNodeAt = function(node, type, pos, loc) {\n return finishNodeAt.call(this, node, type, pos, loc)\n};\n\n// The algorithm used to determine whether a regexp can appear at a\n// given point in the program is loosely based on sweet.js' approach.\n// See https://github.com/mozilla/sweet.js/wiki/design\n\nvar TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) {\n this.token = token;\n this.isExpr = !!isExpr;\n this.preserveSpace = !!preserveSpace;\n this.override = override;\n this.generator = !!generator;\n};\n\nvar types$1 = {\n b_stat: new TokContext(\"{\", false),\n b_expr: new TokContext(\"{\", true),\n b_tmpl: new TokContext(\"${\", false),\n p_stat: new TokContext(\"(\", false),\n p_expr: new TokContext(\"(\", true),\n q_tmpl: new TokContext(\"`\", true, true, function (p) { return p.tryReadTemplateToken(); }),\n f_stat: new TokContext(\"function\", false),\n f_expr: new TokContext(\"function\", true),\n f_expr_gen: new TokContext(\"function\", true, false, null, true),\n f_gen: new TokContext(\"function\", false, false, null, true)\n};\n\nvar pp$7 = Parser.prototype;\n\npp$7.initialContext = function() {\n return [types$1.b_stat]\n};\n\npp$7.braceIsBlock = function(prevType) {\n var parent = this.curContext();\n if (parent === types$1.f_expr || parent === types$1.f_stat)\n { return true }\n if (prevType === types.colon && (parent === types$1.b_stat || parent === types$1.b_expr))\n { return !parent.isExpr }\n\n // The check for `tt.name && exprAllowed` detects whether we are\n // after a `yield` or `of` construct. See the `updateContext` for\n // `tt.name`.\n if (prevType === types._return || prevType === types.name && this.exprAllowed)\n { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) }\n if (prevType === types._else || prevType === types.semi || prevType === types.eof || prevType === types.parenR || prevType === types.arrow)\n { return true }\n if (prevType === types.braceL)\n { return parent === types$1.b_stat }\n if (prevType === types._var || prevType === types.name)\n { return false }\n return !this.exprAllowed\n};\n\npp$7.inGeneratorContext = function() {\n var this$1 = this;\n\n for (var i = this.context.length - 1; i >= 1; i--) {\n var context = this$1.context[i];\n if (context.token === \"function\")\n { return context.generator }\n }\n return false\n};\n\npp$7.updateContext = function(prevType) {\n var update, type = this.type;\n if (type.keyword && prevType === types.dot)\n { this.exprAllowed = false; }\n else if (update = type.updateContext)\n { update.call(this, prevType); }\n else\n { this.exprAllowed = type.beforeExpr; }\n};\n\n// Token-specific context update code\n\ntypes.parenR.updateContext = types.braceR.updateContext = function() {\n if (this.context.length === 1) {\n this.exprAllowed = true;\n return\n }\n var out = this.context.pop();\n if (out === types$1.b_stat && this.curContext().token === \"function\") {\n out = this.context.pop();\n }\n this.exprAllowed = !out.isExpr;\n};\n\ntypes.braceL.updateContext = function(prevType) {\n this.context.push(this.braceIsBlock(prevType) ? types$1.b_stat : types$1.b_expr);\n this.exprAllowed = true;\n};\n\ntypes.dollarBraceL.updateContext = function() {\n this.context.push(types$1.b_tmpl);\n this.exprAllowed = true;\n};\n\ntypes.parenL.updateContext = function(prevType) {\n var statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while;\n this.context.push(statementParens ? types$1.p_stat : types$1.p_expr);\n this.exprAllowed = true;\n};\n\ntypes.incDec.updateContext = function() {\n // tokExprAllowed stays unchanged\n};\n\ntypes._function.updateContext = types._class.updateContext = function(prevType) {\n if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else &&\n !((prevType === types.colon || prevType === types.braceL) && this.curContext() === types$1.b_stat))\n { this.context.push(types$1.f_expr); }\n else\n { this.context.push(types$1.f_stat); }\n this.exprAllowed = false;\n};\n\ntypes.backQuote.updateContext = function() {\n if (this.curContext() === types$1.q_tmpl)\n { this.context.pop(); }\n else\n { this.context.push(types$1.q_tmpl); }\n this.exprAllowed = false;\n};\n\ntypes.star.updateContext = function(prevType) {\n if (prevType === types._function) {\n var index = this.context.length - 1;\n if (this.context[index] === types$1.f_expr)\n { this.context[index] = types$1.f_expr_gen; }\n else\n { this.context[index] = types$1.f_gen; }\n }\n this.exprAllowed = true;\n};\n\ntypes.name.updateContext = function(prevType) {\n var allowed = false;\n if (this.options.ecmaVersion >= 6 && prevType !== types.dot) {\n if (this.value === \"of\" && !this.exprAllowed ||\n this.value === \"yield\" && this.inGeneratorContext())\n { allowed = true; }\n }\n this.exprAllowed = allowed;\n};\n\nvar data = {\n \"$LONE\": [\n \"ASCII\",\n \"ASCII_Hex_Digit\",\n \"AHex\",\n \"Alphabetic\",\n \"Alpha\",\n \"Any\",\n \"Assigned\",\n \"Bidi_Control\",\n \"Bidi_C\",\n \"Bidi_Mirrored\",\n \"Bidi_M\",\n \"Case_Ignorable\",\n \"CI\",\n \"Cased\",\n \"Changes_When_Casefolded\",\n \"CWCF\",\n \"Changes_When_Casemapped\",\n \"CWCM\",\n \"Changes_When_Lowercased\",\n \"CWL\",\n \"Changes_When_NFKC_Casefolded\",\n \"CWKCF\",\n \"Changes_When_Titlecased\",\n \"CWT\",\n \"Changes_When_Uppercased\",\n \"CWU\",\n \"Dash\",\n \"Default_Ignorable_Code_Point\",\n \"DI\",\n \"Deprecated\",\n \"Dep\",\n \"Diacritic\",\n \"Dia\",\n \"Emoji\",\n \"Emoji_Component\",\n \"Emoji_Modifier\",\n \"Emoji_Modifier_Base\",\n \"Emoji_Presentation\",\n \"Extender\",\n \"Ext\",\n \"Grapheme_Base\",\n \"Gr_Base\",\n \"Grapheme_Extend\",\n \"Gr_Ext\",\n \"Hex_Digit\",\n \"Hex\",\n \"IDS_Binary_Operator\",\n \"IDSB\",\n \"IDS_Trinary_Operator\",\n \"IDST\",\n \"ID_Continue\",\n \"IDC\",\n \"ID_Start\",\n \"IDS\",\n \"Ideographic\",\n \"Ideo\",\n \"Join_Control\",\n \"Join_C\",\n \"Logical_Order_Exception\",\n \"LOE\",\n \"Lowercase\",\n \"Lower\",\n \"Math\",\n \"Noncharacter_Code_Point\",\n \"NChar\",\n \"Pattern_Syntax\",\n \"Pat_Syn\",\n \"Pattern_White_Space\",\n \"Pat_WS\",\n \"Quotation_Mark\",\n \"QMark\",\n \"Radical\",\n \"Regional_Indicator\",\n \"RI\",\n \"Sentence_Terminal\",\n \"STerm\",\n \"Soft_Dotted\",\n \"SD\",\n \"Terminal_Punctuation\",\n \"Term\",\n \"Unified_Ideograph\",\n \"UIdeo\",\n \"Uppercase\",\n \"Upper\",\n \"Variation_Selector\",\n \"VS\",\n \"White_Space\",\n \"space\",\n \"XID_Continue\",\n \"XIDC\",\n \"XID_Start\",\n \"XIDS\"\n ],\n \"General_Category\": [\n \"Cased_Letter\",\n \"LC\",\n \"Close_Punctuation\",\n \"Pe\",\n \"Connector_Punctuation\",\n \"Pc\",\n \"Control\",\n \"Cc\",\n \"cntrl\",\n \"Currency_Symbol\",\n \"Sc\",\n \"Dash_Punctuation\",\n \"Pd\",\n \"Decimal_Number\",\n \"Nd\",\n \"digit\",\n \"Enclosing_Mark\",\n \"Me\",\n \"Final_Punctuation\",\n \"Pf\",\n \"Format\",\n \"Cf\",\n \"Initial_Punctuation\",\n \"Pi\",\n \"Letter\",\n \"L\",\n \"Letter_Number\",\n \"Nl\",\n \"Line_Separator\",\n \"Zl\",\n \"Lowercase_Letter\",\n \"Ll\",\n \"Mark\",\n \"M\",\n \"Combining_Mark\",\n \"Math_Symbol\",\n \"Sm\",\n \"Modifier_Letter\",\n \"Lm\",\n \"Modifier_Symbol\",\n \"Sk\",\n \"Nonspacing_Mark\",\n \"Mn\",\n \"Number\",\n \"N\",\n \"Open_Punctuation\",\n \"Ps\",\n \"Other\",\n \"C\",\n \"Other_Letter\",\n \"Lo\",\n \"Other_Number\",\n \"No\",\n \"Other_Punctuation\",\n \"Po\",\n \"Other_Symbol\",\n \"So\",\n \"Paragraph_Separator\",\n \"Zp\",\n \"Private_Use\",\n \"Co\",\n \"Punctuation\",\n \"P\",\n \"punct\",\n \"Separator\",\n \"Z\",\n \"Space_Separator\",\n \"Zs\",\n \"Spacing_Mark\",\n \"Mc\",\n \"Surrogate\",\n \"Cs\",\n \"Symbol\",\n \"S\",\n \"Titlecase_Letter\",\n \"Lt\",\n \"Unassigned\",\n \"Cn\",\n \"Uppercase_Letter\",\n \"Lu\"\n ],\n \"Script\": [\n \"Adlam\",\n \"Adlm\",\n \"Ahom\",\n \"Anatolian_Hieroglyphs\",\n \"Hluw\",\n \"Arabic\",\n \"Arab\",\n \"Armenian\",\n \"Armn\",\n \"Avestan\",\n \"Avst\",\n \"Balinese\",\n \"Bali\",\n \"Bamum\",\n \"Bamu\",\n \"Bassa_Vah\",\n \"Bass\",\n \"Batak\",\n \"Batk\",\n \"Bengali\",\n \"Beng\",\n \"Bhaiksuki\",\n \"Bhks\",\n \"Bopomofo\",\n \"Bopo\",\n \"Brahmi\",\n \"Brah\",\n \"Braille\",\n \"Brai\",\n \"Buginese\",\n \"Bugi\",\n \"Buhid\",\n \"Buhd\",\n \"Canadian_Aboriginal\",\n \"Cans\",\n \"Carian\",\n \"Cari\",\n \"Caucasian_Albanian\",\n \"Aghb\",\n \"Chakma\",\n \"Cakm\",\n \"Cham\",\n \"Cherokee\",\n \"Cher\",\n \"Common\",\n \"Zyyy\",\n \"Coptic\",\n \"Copt\",\n \"Qaac\",\n \"Cuneiform\",\n \"Xsux\",\n \"Cypriot\",\n \"Cprt\",\n \"Cyrillic\",\n \"Cyrl\",\n \"Deseret\",\n \"Dsrt\",\n \"Devanagari\",\n \"Deva\",\n \"Duployan\",\n \"Dupl\",\n \"Egyptian_Hieroglyphs\",\n \"Egyp\",\n \"Elbasan\",\n \"Elba\",\n \"Ethiopic\",\n \"Ethi\",\n \"Georgian\",\n \"Geor\",\n \"Glagolitic\",\n \"Glag\",\n \"Gothic\",\n \"Goth\",\n \"Grantha\",\n \"Gran\",\n \"Greek\",\n \"Grek\",\n \"Gujarati\",\n \"Gujr\",\n \"Gurmukhi\",\n \"Guru\",\n \"Han\",\n \"Hani\",\n \"Hangul\",\n \"Hang\",\n \"Hanunoo\",\n \"Hano\",\n \"Hatran\",\n \"Hatr\",\n \"Hebrew\",\n \"Hebr\",\n \"Hiragana\",\n \"Hira\",\n \"Imperial_Aramaic\",\n \"Armi\",\n \"Inherited\",\n \"Zinh\",\n \"Qaai\",\n \"Inscriptional_Pahlavi\",\n \"Phli\",\n \"Inscriptional_Parthian\",\n \"Prti\",\n \"Javanese\",\n \"Java\",\n \"Kaithi\",\n \"Kthi\",\n \"Kannada\",\n \"Knda\",\n \"Katakana\",\n \"Kana\",\n \"Kayah_Li\",\n \"Kali\",\n \"Kharoshthi\",\n \"Khar\",\n \"Khmer\",\n \"Khmr\",\n \"Khojki\",\n \"Khoj\",\n \"Khudawadi\",\n \"Sind\",\n \"Lao\",\n \"Laoo\",\n \"Latin\",\n \"Latn\",\n \"Lepcha\",\n \"Lepc\",\n \"Limbu\",\n \"Limb\",\n \"Linear_A\",\n \"Lina\",\n \"Linear_B\",\n \"Linb\",\n \"Lisu\",\n \"Lycian\",\n \"Lyci\",\n \"Lydian\",\n \"Lydi\",\n \"Mahajani\",\n \"Mahj\",\n \"Malayalam\",\n \"Mlym\",\n \"Mandaic\",\n \"Mand\",\n \"Manichaean\",\n \"Mani\",\n \"Marchen\",\n \"Marc\",\n \"Masaram_Gondi\",\n \"Gonm\",\n \"Meetei_Mayek\",\n \"Mtei\",\n \"Mende_Kikakui\",\n \"Mend\",\n \"Meroitic_Cursive\",\n \"Merc\",\n \"Meroitic_Hieroglyphs\",\n \"Mero\",\n \"Miao\",\n \"Plrd\",\n \"Modi\",\n \"Mongolian\",\n \"Mong\",\n \"Mro\",\n \"Mroo\",\n \"Multani\",\n \"Mult\",\n \"Myanmar\",\n \"Mymr\",\n \"Nabataean\",\n \"Nbat\",\n \"New_Tai_Lue\",\n \"Talu\",\n \"Newa\",\n \"Nko\",\n \"Nkoo\",\n \"Nushu\",\n \"Nshu\",\n \"Ogham\",\n \"Ogam\",\n \"Ol_Chiki\",\n \"Olck\",\n \"Old_Hungarian\",\n \"Hung\",\n \"Old_Italic\",\n \"Ital\",\n \"Old_North_Arabian\",\n \"Narb\",\n \"Old_Permic\",\n \"Perm\",\n \"Old_Persian\",\n \"Xpeo\",\n \"Old_South_Arabian\",\n \"Sarb\",\n \"Old_Turkic\",\n \"Orkh\",\n \"Oriya\",\n \"Orya\",\n \"Osage\",\n \"Osge\",\n \"Osmanya\",\n \"Osma\",\n \"Pahawh_Hmong\",\n \"Hmng\",\n \"Palmyrene\",\n \"Palm\",\n \"Pau_Cin_Hau\",\n \"Pauc\",\n \"Phags_Pa\",\n \"Phag\",\n \"Phoenician\",\n \"Phnx\",\n \"Psalter_Pahlavi\",\n \"Phlp\",\n \"Rejang\",\n \"Rjng\",\n \"Runic\",\n \"Runr\",\n \"Samaritan\",\n \"Samr\",\n \"Saurashtra\",\n \"Saur\",\n \"Sharada\",\n \"Shrd\",\n \"Shavian\",\n \"Shaw\",\n \"Siddham\",\n \"Sidd\",\n \"SignWriting\",\n \"Sgnw\",\n \"Sinhala\",\n \"Sinh\",\n \"Sora_Sompeng\",\n \"Sora\",\n \"Soyombo\",\n \"Soyo\",\n \"Sundanese\",\n \"Sund\",\n \"Syloti_Nagri\",\n \"Sylo\",\n \"Syriac\",\n \"Syrc\",\n \"Tagalog\",\n \"Tglg\",\n \"Tagbanwa\",\n \"Tagb\",\n \"Tai_Le\",\n \"Tale\",\n \"Tai_Tham\",\n \"Lana\",\n \"Tai_Viet\",\n \"Tavt\",\n \"Takri\",\n \"Takr\",\n \"Tamil\",\n \"Taml\",\n \"Tangut\",\n \"Tang\",\n \"Telugu\",\n \"Telu\",\n \"Thaana\",\n \"Thaa\",\n \"Thai\",\n \"Tibetan\",\n \"Tibt\",\n \"Tifinagh\",\n \"Tfng\",\n \"Tirhuta\",\n \"Tirh\",\n \"Ugaritic\",\n \"Ugar\",\n \"Vai\",\n \"Vaii\",\n \"Warang_Citi\",\n \"Wara\",\n \"Yi\",\n \"Yiii\",\n \"Zanabazar_Square\",\n \"Zanb\"\n ]\n};\nArray.prototype.push.apply(data.$LONE, data.General_Category);\ndata.gc = data.General_Category;\ndata.sc = data.Script_Extensions = data.scx = data.Script;\n\nvar pp$9 = Parser.prototype;\n\nvar RegExpValidationState = function RegExpValidationState(parser) {\n this.parser = parser;\n this.validFlags = \"gim\" + (parser.options.ecmaVersion >= 6 ? \"uy\" : \"\") + (parser.options.ecmaVersion >= 9 ? \"s\" : \"\");\n this.source = \"\";\n this.flags = \"\";\n this.start = 0;\n this.switchU = false;\n this.switchN = false;\n this.pos = 0;\n this.lastIntValue = 0;\n this.lastStringValue = \"\";\n this.lastAssertionIsQuantifiable = false;\n this.numCapturingParens = 0;\n this.maxBackReference = 0;\n this.groupNames = [];\n this.backReferenceNames = [];\n};\n\nRegExpValidationState.prototype.reset = function reset (start, pattern, flags) {\n var unicode = flags.indexOf(\"u\") !== -1;\n this.start = start | 0;\n this.source = pattern + \"\";\n this.flags = flags;\n this.switchU = unicode && this.parser.options.ecmaVersion >= 6;\n this.switchN = unicode && this.parser.options.ecmaVersion >= 9;\n};\n\nRegExpValidationState.prototype.raise = function raise (message) {\n this.parser.raiseRecoverable(this.start, (\"Invalid regular expression: /\" + (this.source) + \"/: \" + message));\n};\n\n// If u flag is given, this returns the code point at the index (it combines a surrogate pair).\n// Otherwise, this returns the code unit of the index (can be a part of a surrogate pair).\nRegExpValidationState.prototype.at = function at (i) {\n var s = this.source;\n var l = s.length;\n if (i >= l) {\n return -1\n }\n var c = s.charCodeAt(i);\n if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {\n return c\n }\n return (c << 10) + s.charCodeAt(i + 1) - 0x35FDC00\n};\n\nRegExpValidationState.prototype.nextIndex = function nextIndex (i) {\n var s = this.source;\n var l = s.length;\n if (i >= l) {\n return l\n }\n var c = s.charCodeAt(i);\n if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {\n return i + 1\n }\n return i + 2\n};\n\nRegExpValidationState.prototype.current = function current () {\n return this.at(this.pos)\n};\n\nRegExpValidationState.prototype.lookahead = function lookahead () {\n return this.at(this.nextIndex(this.pos))\n};\n\nRegExpValidationState.prototype.advance = function advance () {\n this.pos = this.nextIndex(this.pos);\n};\n\nRegExpValidationState.prototype.eat = function eat (ch) {\n if (this.current() === ch) {\n this.advance();\n return true\n }\n return false\n};\n\nfunction codePointToString$1(ch) {\n if (ch <= 0xFFFF) { return String.fromCharCode(ch) }\n ch -= 0x10000;\n return String.fromCharCode((ch >> 10) + 0xD800, (ch & 0x03FF) + 0xDC00)\n}\n\n/**\n * Validate the flags part of a given RegExpLiteral.\n *\n * @param {RegExpValidationState} state The state to validate RegExp.\n * @returns {void}\n */\npp$9.validateRegExpFlags = function(state) {\n var this$1 = this;\n\n var validFlags = state.validFlags;\n var flags = state.flags;\n\n for (var i = 0; i < flags.length; i++) {\n var flag = flags.charAt(i);\n if (validFlags.indexOf(flag) === -1) {\n this$1.raise(state.start, \"Invalid regular expression flag\");\n }\n if (flags.indexOf(flag, i + 1) > -1) {\n this$1.raise(state.start, \"Duplicate regular expression flag\");\n }\n }\n};\n\n/**\n * Validate the pattern part of a given RegExpLiteral.\n *\n * @param {RegExpValidationState} state The state to validate RegExp.\n * @returns {void}\n */\npp$9.validateRegExpPattern = function(state) {\n this.regexp_pattern(state);\n\n // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of\n // parsing contains a |GroupName|, reparse with the goal symbol\n // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError*\n // exception if _P_ did not conform to the grammar, if any elements of _P_\n // were not matched by the parse, or if any Early Error conditions exist.\n if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) {\n state.switchN = true;\n this.regexp_pattern(state);\n }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern\npp$9.regexp_pattern = function(state) {\n state.pos = 0;\n state.lastIntValue = 0;\n state.lastStringValue = \"\";\n state.lastAssertionIsQuantifiable = false;\n state.numCapturingParens = 0;\n state.maxBackReference = 0;\n state.groupNames.length = 0;\n state.backReferenceNames.length = 0;\n\n this.regexp_disjunction(state);\n\n if (state.pos !== state.source.length) {\n // Make the same messages as V8.\n if (state.eat(0x29 /* ) */)) {\n state.raise(\"Unmatched ')'\");\n }\n if (state.eat(0x5D /* [ */) || state.eat(0x7D /* } */)) {\n state.raise(\"Lone quantifier brackets\");\n }\n }\n if (state.maxBackReference > state.numCapturingParens) {\n state.raise(\"Invalid escape\");\n }\n for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) {\n var name = list[i];\n\n if (state.groupNames.indexOf(name) === -1) {\n state.raise(\"Invalid named capture referenced\");\n }\n }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction\npp$9.regexp_disjunction = function(state) {\n var this$1 = this;\n\n this.regexp_alternative(state);\n while (state.eat(0x7C /* | */)) {\n this$1.regexp_alternative(state);\n }\n\n // Make the same message as V8.\n if (this.regexp_eatQuantifier(state, true)) {\n state.raise(\"Nothing to repeat\");\n }\n if (state.eat(0x7B /* { */)) {\n state.raise(\"Lone quantifier brackets\");\n }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative\npp$9.regexp_alternative = function(state) {\n while (state.pos < state.source.length && this.regexp_eatTerm(state))\n { }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term\npp$9.regexp_eatTerm = function(state) {\n if (this.regexp_eatAssertion(state)) {\n // Handle `QuantifiableAssertion Quantifier` alternative.\n // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion\n // is a QuantifiableAssertion.\n if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) {\n // Make the same message as V8.\n if (state.switchU) {\n state.raise(\"Invalid quantifier\");\n }\n }\n return true\n }\n\n if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) {\n this.regexp_eatQuantifier(state);\n return true\n }\n\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion\npp$9.regexp_eatAssertion = function(state) {\n var start = state.pos;\n state.lastAssertionIsQuantifiable = false;\n\n // ^, $\n if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) {\n return true\n }\n\n // \\b \\B\n if (state.eat(0x5C /* \\ */)) {\n if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) {\n return true\n }\n state.pos = start;\n }\n\n // Lookahead / Lookbehind\n if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) {\n var lookbehind = false;\n if (this.options.ecmaVersion >= 9) {\n lookbehind = state.eat(0x3C /* < */);\n }\n if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) {\n this.regexp_disjunction(state);\n if (!state.eat(0x29 /* ) */)) {\n state.raise(\"Unterminated group\");\n }\n state.lastAssertionIsQuantifiable = !lookbehind;\n return true\n }\n }\n\n state.pos = start;\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier\npp$9.regexp_eatQuantifier = function(state, noError) {\n if ( noError === void 0 ) noError = false;\n\n if (this.regexp_eatQuantifierPrefix(state, noError)) {\n state.eat(0x3F /* ? */);\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix\npp$9.regexp_eatQuantifierPrefix = function(state, noError) {\n return (\n state.eat(0x2A /* * */) ||\n state.eat(0x2B /* + */) ||\n state.eat(0x3F /* ? */) ||\n this.regexp_eatBracedQuantifier(state, noError)\n )\n};\npp$9.regexp_eatBracedQuantifier = function(state, noError) {\n var start = state.pos;\n if (state.eat(0x7B /* { */)) {\n var min = 0, max = -1;\n if (this.regexp_eatDecimalDigits(state)) {\n min = state.lastIntValue;\n if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) {\n max = state.lastIntValue;\n }\n if (state.eat(0x7D /* } */)) {\n // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term\n if (max !== -1 && max < min && !noError) {\n state.raise(\"numbers out of order in {} quantifier\");\n }\n return true\n }\n }\n if (state.switchU && !noError) {\n state.raise(\"Incomplete quantifier\");\n }\n state.pos = start;\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Atom\npp$9.regexp_eatAtom = function(state) {\n return (\n this.regexp_eatPatternCharacters(state) ||\n state.eat(0x2E /* . */) ||\n this.regexp_eatReverseSolidusAtomEscape(state) ||\n this.regexp_eatCharacterClass(state) ||\n this.regexp_eatUncapturingGroup(state) ||\n this.regexp_eatCapturingGroup(state)\n )\n};\npp$9.regexp_eatReverseSolidusAtomEscape = function(state) {\n var start = state.pos;\n if (state.eat(0x5C /* \\ */)) {\n if (this.regexp_eatAtomEscape(state)) {\n return true\n }\n state.pos = start;\n }\n return false\n};\npp$9.regexp_eatUncapturingGroup = function(state) {\n var start = state.pos;\n if (state.eat(0x28 /* ( */)) {\n if (state.eat(0x3F /* ? */) && state.eat(0x3A /* : */)) {\n this.regexp_disjunction(state);\n if (state.eat(0x29 /* ) */)) {\n return true\n }\n state.raise(\"Unterminated group\");\n }\n state.pos = start;\n }\n return false\n};\npp$9.regexp_eatCapturingGroup = function(state) {\n if (state.eat(0x28 /* ( */)) {\n if (this.options.ecmaVersion >= 9) {\n this.regexp_groupSpecifier(state);\n } else if (state.current() === 0x3F /* ? */) {\n state.raise(\"Invalid group\");\n }\n this.regexp_disjunction(state);\n if (state.eat(0x29 /* ) */)) {\n state.numCapturingParens += 1;\n return true\n }\n state.raise(\"Unterminated group\");\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom\npp$9.regexp_eatExtendedAtom = function(state) {\n return (\n state.eat(0x2E /* . */) ||\n this.regexp_eatReverseSolidusAtomEscape(state) ||\n this.regexp_eatCharacterClass(state) ||\n this.regexp_eatUncapturingGroup(state) ||\n this.regexp_eatCapturingGroup(state) ||\n this.regexp_eatInvalidBracedQuantifier(state) ||\n this.regexp_eatExtendedPatternCharacter(state)\n )\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier\npp$9.regexp_eatInvalidBracedQuantifier = function(state) {\n if (this.regexp_eatBracedQuantifier(state, true)) {\n state.raise(\"Nothing to repeat\");\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter\npp$9.regexp_eatSyntaxCharacter = function(state) {\n var ch = state.current();\n if (isSyntaxCharacter(ch)) {\n state.lastIntValue = ch;\n state.advance();\n return true\n }\n return false\n};\nfunction isSyntaxCharacter(ch) {\n return (\n ch === 0x24 /* $ */ ||\n ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ ||\n ch === 0x2E /* . */ ||\n ch === 0x3F /* ? */ ||\n ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ ||\n ch >= 0x7B /* { */ && ch <= 0x7D /* } */\n )\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter\n// But eat eager.\npp$9.regexp_eatPatternCharacters = function(state) {\n var start = state.pos;\n var ch = 0;\n while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) {\n state.advance();\n }\n return state.pos !== start\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter\npp$9.regexp_eatExtendedPatternCharacter = function(state) {\n var ch = state.current();\n if (\n ch !== -1 &&\n ch !== 0x24 /* $ */ &&\n !(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) &&\n ch !== 0x2E /* . */ &&\n ch !== 0x3F /* ? */ &&\n ch !== 0x5B /* [ */ &&\n ch !== 0x5E /* ^ */ &&\n ch !== 0x7C /* | */\n ) {\n state.advance();\n return true\n }\n return false\n};\n\n// GroupSpecifier[U] ::\n// [empty]\n// `?` GroupName[?U]\npp$9.regexp_groupSpecifier = function(state) {\n if (state.eat(0x3F /* ? */)) {\n if (this.regexp_eatGroupName(state)) {\n if (state.groupNames.indexOf(state.lastStringValue) !== -1) {\n state.raise(\"Duplicate capture group name\");\n }\n state.groupNames.push(state.lastStringValue);\n return\n }\n state.raise(\"Invalid group\");\n }\n};\n\n// GroupName[U] ::\n// `<` RegExpIdentifierName[?U] `>`\n// Note: this updates `state.lastStringValue` property with the eaten name.\npp$9.regexp_eatGroupName = function(state) {\n state.lastStringValue = \"\";\n if (state.eat(0x3C /* < */)) {\n if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) {\n return true\n }\n state.raise(\"Invalid capture group name\");\n }\n return false\n};\n\n// RegExpIdentifierName[U] ::\n// RegExpIdentifierStart[?U]\n// RegExpIdentifierName[?U] RegExpIdentifierPart[?U]\n// Note: this updates `state.lastStringValue` property with the eaten name.\npp$9.regexp_eatRegExpIdentifierName = function(state) {\n state.lastStringValue = \"\";\n if (this.regexp_eatRegExpIdentifierStart(state)) {\n state.lastStringValue += codePointToString$1(state.lastIntValue);\n while (this.regexp_eatRegExpIdentifierPart(state)) {\n state.lastStringValue += codePointToString$1(state.lastIntValue);\n }\n return true\n }\n return false\n};\n\n// RegExpIdentifierStart[U] ::\n// UnicodeIDStart\n// `$`\n// `_`\n// `\\` RegExpUnicodeEscapeSequence[?U]\npp$9.regexp_eatRegExpIdentifierStart = function(state) {\n var start = state.pos;\n var ch = state.current();\n state.advance();\n\n if (ch === 0x5C /* \\ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) {\n ch = state.lastIntValue;\n }\n if (isRegExpIdentifierStart(ch)) {\n state.lastIntValue = ch;\n return true\n }\n\n state.pos = start;\n return false\n};\nfunction isRegExpIdentifierStart(ch) {\n return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */\n}\n\n// RegExpIdentifierPart[U] ::\n// UnicodeIDContinue\n// `$`\n// `_`\n// `\\` RegExpUnicodeEscapeSequence[?U]\n// \n// \npp$9.regexp_eatRegExpIdentifierPart = function(state) {\n var start = state.pos;\n var ch = state.current();\n state.advance();\n\n if (ch === 0x5C /* \\ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) {\n ch = state.lastIntValue;\n }\n if (isRegExpIdentifierPart(ch)) {\n state.lastIntValue = ch;\n return true\n }\n\n state.pos = start;\n return false\n};\nfunction isRegExpIdentifierPart(ch) {\n return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* */ || ch === 0x200D /* */\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape\npp$9.regexp_eatAtomEscape = function(state) {\n if (\n this.regexp_eatBackReference(state) ||\n this.regexp_eatCharacterClassEscape(state) ||\n this.regexp_eatCharacterEscape(state) ||\n (state.switchN && this.regexp_eatKGroupName(state))\n ) {\n return true\n }\n if (state.switchU) {\n // Make the same message as V8.\n if (state.current() === 0x63 /* c */) {\n state.raise(\"Invalid unicode escape\");\n }\n state.raise(\"Invalid escape\");\n }\n return false\n};\npp$9.regexp_eatBackReference = function(state) {\n var start = state.pos;\n if (this.regexp_eatDecimalEscape(state)) {\n var n = state.lastIntValue;\n if (state.switchU) {\n // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape\n if (n > state.maxBackReference) {\n state.maxBackReference = n;\n }\n return true\n }\n if (n <= state.numCapturingParens) {\n return true\n }\n state.pos = start;\n }\n return false\n};\npp$9.regexp_eatKGroupName = function(state) {\n if (state.eat(0x6B /* k */)) {\n if (this.regexp_eatGroupName(state)) {\n state.backReferenceNames.push(state.lastStringValue);\n return true\n }\n state.raise(\"Invalid named reference\");\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape\npp$9.regexp_eatCharacterEscape = function(state) {\n return (\n this.regexp_eatControlEscape(state) ||\n this.regexp_eatCControlLetter(state) ||\n this.regexp_eatZero(state) ||\n this.regexp_eatHexEscapeSequence(state) ||\n this.regexp_eatRegExpUnicodeEscapeSequence(state) ||\n (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) ||\n this.regexp_eatIdentityEscape(state)\n )\n};\npp$9.regexp_eatCControlLetter = function(state) {\n var start = state.pos;\n if (state.eat(0x63 /* c */)) {\n if (this.regexp_eatControlLetter(state)) {\n return true\n }\n state.pos = start;\n }\n return false\n};\npp$9.regexp_eatZero = function(state) {\n if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) {\n state.lastIntValue = 0;\n state.advance();\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape\npp$9.regexp_eatControlEscape = function(state) {\n var ch = state.current();\n if (ch === 0x74 /* t */) {\n state.lastIntValue = 0x09; /* \\t */\n state.advance();\n return true\n }\n if (ch === 0x6E /* n */) {\n state.lastIntValue = 0x0A; /* \\n */\n state.advance();\n return true\n }\n if (ch === 0x76 /* v */) {\n state.lastIntValue = 0x0B; /* \\v */\n state.advance();\n return true\n }\n if (ch === 0x66 /* f */) {\n state.lastIntValue = 0x0C; /* \\f */\n state.advance();\n return true\n }\n if (ch === 0x72 /* r */) {\n state.lastIntValue = 0x0D; /* \\r */\n state.advance();\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter\npp$9.regexp_eatControlLetter = function(state) {\n var ch = state.current();\n if (isControlLetter(ch)) {\n state.lastIntValue = ch % 0x20;\n state.advance();\n return true\n }\n return false\n};\nfunction isControlLetter(ch) {\n return (\n (ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) ||\n (ch >= 0x61 /* a */ && ch <= 0x7A /* z */)\n )\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence\npp$9.regexp_eatRegExpUnicodeEscapeSequence = function(state) {\n var start = state.pos;\n\n if (state.eat(0x75 /* u */)) {\n if (this.regexp_eatFixedHexDigits(state, 4)) {\n var lead = state.lastIntValue;\n if (state.switchU && lead >= 0xD800 && lead <= 0xDBFF) {\n var leadSurrogateEnd = state.pos;\n if (state.eat(0x5C /* \\ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) {\n var trail = state.lastIntValue;\n if (trail >= 0xDC00 && trail <= 0xDFFF) {\n state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;\n return true\n }\n }\n state.pos = leadSurrogateEnd;\n state.lastIntValue = lead;\n }\n return true\n }\n if (\n state.switchU &&\n state.eat(0x7B /* { */) &&\n this.regexp_eatHexDigits(state) &&\n state.eat(0x7D /* } */) &&\n isValidUnicode(state.lastIntValue)\n ) {\n return true\n }\n if (state.switchU) {\n state.raise(\"Invalid unicode escape\");\n }\n state.pos = start;\n }\n\n return false\n};\nfunction isValidUnicode(ch) {\n return ch >= 0 && ch <= 0x10FFFF\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape\npp$9.regexp_eatIdentityEscape = function(state) {\n if (state.switchU) {\n if (this.regexp_eatSyntaxCharacter(state)) {\n return true\n }\n if (state.eat(0x2F /* / */)) {\n state.lastIntValue = 0x2F; /* / */\n return true\n }\n return false\n }\n\n var ch = state.current();\n if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) {\n state.lastIntValue = ch;\n state.advance();\n return true\n }\n\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape\npp$9.regexp_eatDecimalEscape = function(state) {\n state.lastIntValue = 0;\n var ch = state.current();\n if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) {\n do {\n state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);\n state.advance();\n } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */)\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape\npp$9.regexp_eatCharacterClassEscape = function(state) {\n var ch = state.current();\n\n if (isCharacterClassEscape(ch)) {\n state.lastIntValue = -1;\n state.advance();\n return true\n }\n\n if (\n state.switchU &&\n this.options.ecmaVersion >= 9 &&\n (ch === 0x50 /* P */ || ch === 0x70 /* p */)\n ) {\n state.lastIntValue = -1;\n state.advance();\n if (\n state.eat(0x7B /* { */) &&\n this.regexp_eatUnicodePropertyValueExpression(state) &&\n state.eat(0x7D /* } */)\n ) {\n return true\n }\n state.raise(\"Invalid property name\");\n }\n\n return false\n};\nfunction isCharacterClassEscape(ch) {\n return (\n ch === 0x64 /* d */ ||\n ch === 0x44 /* D */ ||\n ch === 0x73 /* s */ ||\n ch === 0x53 /* S */ ||\n ch === 0x77 /* w */ ||\n ch === 0x57 /* W */\n )\n}\n\n// UnicodePropertyValueExpression ::\n// UnicodePropertyName `=` UnicodePropertyValue\n// LoneUnicodePropertyNameOrValue\npp$9.regexp_eatUnicodePropertyValueExpression = function(state) {\n var start = state.pos;\n\n // UnicodePropertyName `=` UnicodePropertyValue\n if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) {\n var name = state.lastStringValue;\n if (this.regexp_eatUnicodePropertyValue(state)) {\n var value = state.lastStringValue;\n this.regexp_validateUnicodePropertyNameAndValue(state, name, value);\n return true\n }\n }\n state.pos = start;\n\n // LoneUnicodePropertyNameOrValue\n if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) {\n var nameOrValue = state.lastStringValue;\n this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue);\n return true\n }\n return false\n};\npp$9.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) {\n if (!data.hasOwnProperty(name) || data[name].indexOf(value) === -1) {\n state.raise(\"Invalid property name\");\n }\n};\npp$9.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) {\n if (data.$LONE.indexOf(nameOrValue) === -1) {\n state.raise(\"Invalid property name\");\n }\n};\n\n// UnicodePropertyName ::\n// UnicodePropertyNameCharacters\npp$9.regexp_eatUnicodePropertyName = function(state) {\n var ch = 0;\n state.lastStringValue = \"\";\n while (isUnicodePropertyNameCharacter(ch = state.current())) {\n state.lastStringValue += codePointToString$1(ch);\n state.advance();\n }\n return state.lastStringValue !== \"\"\n};\nfunction isUnicodePropertyNameCharacter(ch) {\n return isControlLetter(ch) || ch === 0x5F /* _ */\n}\n\n// UnicodePropertyValue ::\n// UnicodePropertyValueCharacters\npp$9.regexp_eatUnicodePropertyValue = function(state) {\n var ch = 0;\n state.lastStringValue = \"\";\n while (isUnicodePropertyValueCharacter(ch = state.current())) {\n state.lastStringValue += codePointToString$1(ch);\n state.advance();\n }\n return state.lastStringValue !== \"\"\n};\nfunction isUnicodePropertyValueCharacter(ch) {\n return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch)\n}\n\n// LoneUnicodePropertyNameOrValue ::\n// UnicodePropertyValueCharacters\npp$9.regexp_eatLoneUnicodePropertyNameOrValue = function(state) {\n return this.regexp_eatUnicodePropertyValue(state)\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass\npp$9.regexp_eatCharacterClass = function(state) {\n if (state.eat(0x5B /* [ */)) {\n state.eat(0x5E /* ^ */);\n this.regexp_classRanges(state);\n if (state.eat(0x5D /* [ */)) {\n return true\n }\n // Unreachable since it threw \"unterminated regular expression\" error before.\n state.raise(\"Unterminated character class\");\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges\n// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges\n// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash\npp$9.regexp_classRanges = function(state) {\n var this$1 = this;\n\n while (this.regexp_eatClassAtom(state)) {\n var left = state.lastIntValue;\n if (state.eat(0x2D /* - */) && this$1.regexp_eatClassAtom(state)) {\n var right = state.lastIntValue;\n if (state.switchU && (left === -1 || right === -1)) {\n state.raise(\"Invalid character class\");\n }\n if (left !== -1 && right !== -1 && left > right) {\n state.raise(\"Range out of order in character class\");\n }\n }\n }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash\npp$9.regexp_eatClassAtom = function(state) {\n var start = state.pos;\n\n if (state.eat(0x5C /* \\ */)) {\n if (this.regexp_eatClassEscape(state)) {\n return true\n }\n if (state.switchU) {\n // Make the same message as V8.\n var ch$1 = state.current();\n if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) {\n state.raise(\"Invalid class escape\");\n }\n state.raise(\"Invalid escape\");\n }\n state.pos = start;\n }\n\n var ch = state.current();\n if (ch !== 0x5D /* [ */) {\n state.lastIntValue = ch;\n state.advance();\n return true\n }\n\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape\npp$9.regexp_eatClassEscape = function(state) {\n var start = state.pos;\n\n if (state.eat(0x62 /* b */)) {\n state.lastIntValue = 0x08; /* */\n return true\n }\n\n if (state.switchU && state.eat(0x2D /* - */)) {\n state.lastIntValue = 0x2D; /* - */\n return true\n }\n\n if (!state.switchU && state.eat(0x63 /* c */)) {\n if (this.regexp_eatClassControlLetter(state)) {\n return true\n }\n state.pos = start;\n }\n\n return (\n this.regexp_eatCharacterClassEscape(state) ||\n this.regexp_eatCharacterEscape(state)\n )\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter\npp$9.regexp_eatClassControlLetter = function(state) {\n var ch = state.current();\n if (isDecimalDigit(ch) || ch === 0x5F /* _ */) {\n state.lastIntValue = ch % 0x20;\n state.advance();\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence\npp$9.regexp_eatHexEscapeSequence = function(state) {\n var start = state.pos;\n if (state.eat(0x78 /* x */)) {\n if (this.regexp_eatFixedHexDigits(state, 2)) {\n return true\n }\n if (state.switchU) {\n state.raise(\"Invalid escape\");\n }\n state.pos = start;\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits\npp$9.regexp_eatDecimalDigits = function(state) {\n var start = state.pos;\n var ch = 0;\n state.lastIntValue = 0;\n while (isDecimalDigit(ch = state.current())) {\n state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);\n state.advance();\n }\n return state.pos !== start\n};\nfunction isDecimalDigit(ch) {\n return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits\npp$9.regexp_eatHexDigits = function(state) {\n var start = state.pos;\n var ch = 0;\n state.lastIntValue = 0;\n while (isHexDigit(ch = state.current())) {\n state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);\n state.advance();\n }\n return state.pos !== start\n};\nfunction isHexDigit(ch) {\n return (\n (ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) ||\n (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) ||\n (ch >= 0x61 /* a */ && ch <= 0x66 /* f */)\n )\n}\nfunction hexToInt(ch) {\n if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) {\n return 10 + (ch - 0x41 /* A */)\n }\n if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) {\n return 10 + (ch - 0x61 /* a */)\n }\n return ch - 0x30 /* 0 */\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence\n// Allows only 0-377(octal) i.e. 0-255(decimal).\npp$9.regexp_eatLegacyOctalEscapeSequence = function(state) {\n if (this.regexp_eatOctalDigit(state)) {\n var n1 = state.lastIntValue;\n if (this.regexp_eatOctalDigit(state)) {\n var n2 = state.lastIntValue;\n if (n1 <= 3 && this.regexp_eatOctalDigit(state)) {\n state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue;\n } else {\n state.lastIntValue = n1 * 8 + n2;\n }\n } else {\n state.lastIntValue = n1;\n }\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit\npp$9.regexp_eatOctalDigit = function(state) {\n var ch = state.current();\n if (isOctalDigit(ch)) {\n state.lastIntValue = ch - 0x30; /* 0 */\n state.advance();\n return true\n }\n state.lastIntValue = 0;\n return false\n};\nfunction isOctalDigit(ch) {\n return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits\n// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit\n// And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence\npp$9.regexp_eatFixedHexDigits = function(state, length) {\n var start = state.pos;\n state.lastIntValue = 0;\n for (var i = 0; i < length; ++i) {\n var ch = state.current();\n if (!isHexDigit(ch)) {\n state.pos = start;\n return false\n }\n state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);\n state.advance();\n }\n return true\n};\n\n// Object type used to represent tokens. Note that normally, tokens\n// simply exist as properties on the parser object. This is only\n// used for the onToken callback and the external tokenizer.\n\nvar Token = function Token(p) {\n this.type = p.type;\n this.value = p.value;\n this.start = p.start;\n this.end = p.end;\n if (p.options.locations)\n { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); }\n if (p.options.ranges)\n { this.range = [p.start, p.end]; }\n};\n\n// ## Tokenizer\n\nvar pp$8 = Parser.prototype;\n\n// Move to the next token\n\npp$8.next = function() {\n if (this.options.onToken)\n { this.options.onToken(new Token(this)); }\n\n this.lastTokEnd = this.end;\n this.lastTokStart = this.start;\n this.lastTokEndLoc = this.endLoc;\n this.lastTokStartLoc = this.startLoc;\n this.nextToken();\n};\n\npp$8.getToken = function() {\n this.next();\n return new Token(this)\n};\n\n// If we're in an ES6 environment, make parsers iterable\nif (typeof Symbol !== \"undefined\")\n { pp$8[Symbol.iterator] = function() {\n var this$1 = this;\n\n return {\n next: function () {\n var token = this$1.getToken();\n return {\n done: token.type === types.eof,\n value: token\n }\n }\n }\n }; }\n\n// Toggle strict mode. Re-reads the next number or string to please\n// pedantic tests (`\"use strict\"; 010;` should fail).\n\npp$8.curContext = function() {\n return this.context[this.context.length - 1]\n};\n\n// Read a single token, updating the parser object's token-related\n// properties.\n\npp$8.nextToken = function() {\n var curContext = this.curContext();\n if (!curContext || !curContext.preserveSpace) { this.skipSpace(); }\n\n this.start = this.pos;\n if (this.options.locations) { this.startLoc = this.curPosition(); }\n if (this.pos >= this.input.length) { return this.finishToken(types.eof) }\n\n if (curContext.override) { return curContext.override(this) }\n else { this.readToken(this.fullCharCodeAtPos()); }\n};\n\npp$8.readToken = function(code) {\n // Identifier or keyword. '\\uXXXX' sequences are allowed in\n // identifiers, so '\\' also dispatches to that.\n if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\\' */)\n { return this.readWord() }\n\n return this.getTokenFromCode(code)\n};\n\npp$8.fullCharCodeAtPos = function() {\n var code = this.input.charCodeAt(this.pos);\n if (code <= 0xd7ff || code >= 0xe000) { return code }\n var next = this.input.charCodeAt(this.pos + 1);\n return (code << 10) + next - 0x35fdc00\n};\n\npp$8.skipBlockComment = function() {\n var this$1 = this;\n\n var startLoc = this.options.onComment && this.curPosition();\n var start = this.pos, end = this.input.indexOf(\"*/\", this.pos += 2);\n if (end === -1) { this.raise(this.pos - 2, \"Unterminated comment\"); }\n this.pos = end + 2;\n if (this.options.locations) {\n lineBreakG.lastIndex = start;\n var match;\n while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) {\n ++this$1.curLine;\n this$1.lineStart = match.index + match[0].length;\n }\n }\n if (this.options.onComment)\n { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos,\n startLoc, this.curPosition()); }\n};\n\npp$8.skipLineComment = function(startSkip) {\n var this$1 = this;\n\n var start = this.pos;\n var startLoc = this.options.onComment && this.curPosition();\n var ch = this.input.charCodeAt(this.pos += startSkip);\n while (this.pos < this.input.length && !isNewLine(ch)) {\n ch = this$1.input.charCodeAt(++this$1.pos);\n }\n if (this.options.onComment)\n { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos,\n startLoc, this.curPosition()); }\n};\n\n// Called at the start of the parse and after every token. Skips\n// whitespace and comments, and.\n\npp$8.skipSpace = function() {\n var this$1 = this;\n\n loop: while (this.pos < this.input.length) {\n var ch = this$1.input.charCodeAt(this$1.pos);\n switch (ch) {\n case 32: case 160: // ' '\n ++this$1.pos;\n break\n case 13:\n if (this$1.input.charCodeAt(this$1.pos + 1) === 10) {\n ++this$1.pos;\n }\n case 10: case 8232: case 8233:\n ++this$1.pos;\n if (this$1.options.locations) {\n ++this$1.curLine;\n this$1.lineStart = this$1.pos;\n }\n break\n case 47: // '/'\n switch (this$1.input.charCodeAt(this$1.pos + 1)) {\n case 42: // '*'\n this$1.skipBlockComment();\n break\n case 47:\n this$1.skipLineComment(2);\n break\n default:\n break loop\n }\n break\n default:\n if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {\n ++this$1.pos;\n } else {\n break loop\n }\n }\n }\n};\n\n// Called at the end of every token. Sets `end`, `val`, and\n// maintains `context` and `exprAllowed`, and skips the space after\n// the token, so that the next one's `start` will point at the\n// right position.\n\npp$8.finishToken = function(type, val) {\n this.end = this.pos;\n if (this.options.locations) { this.endLoc = this.curPosition(); }\n var prevType = this.type;\n this.type = type;\n this.value = val;\n\n this.updateContext(prevType);\n};\n\n// ### Token reading\n\n// This is the function that is called to fetch the next token. It\n// is somewhat obscure, because it works in character codes rather\n// than characters, and because operator parsing has been inlined\n// into it.\n//\n// All in the name of speed.\n//\npp$8.readToken_dot = function() {\n var next = this.input.charCodeAt(this.pos + 1);\n if (next >= 48 && next <= 57) { return this.readNumber(true) }\n var next2 = this.input.charCodeAt(this.pos + 2);\n if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.'\n this.pos += 3;\n return this.finishToken(types.ellipsis)\n } else {\n ++this.pos;\n return this.finishToken(types.dot)\n }\n};\n\npp$8.readToken_slash = function() { // '/'\n var next = this.input.charCodeAt(this.pos + 1);\n if (this.exprAllowed) { ++this.pos; return this.readRegexp() }\n if (next === 61) { return this.finishOp(types.assign, 2) }\n return this.finishOp(types.slash, 1)\n};\n\npp$8.readToken_mult_modulo_exp = function(code) { // '%*'\n var next = this.input.charCodeAt(this.pos + 1);\n var size = 1;\n var tokentype = code === 42 ? types.star : types.modulo;\n\n // exponentiation operator ** and **=\n if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) {\n ++size;\n tokentype = types.starstar;\n next = this.input.charCodeAt(this.pos + 2);\n }\n\n if (next === 61) { return this.finishOp(types.assign, size + 1) }\n return this.finishOp(tokentype, size)\n};\n\npp$8.readToken_pipe_amp = function(code) { // '|&'\n var next = this.input.charCodeAt(this.pos + 1);\n if (next === code) { return this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2) }\n if (next === 61) { return this.finishOp(types.assign, 2) }\n return this.finishOp(code === 124 ? types.bitwiseOR : types.bitwiseAND, 1)\n};\n\npp$8.readToken_caret = function() { // '^'\n var next = this.input.charCodeAt(this.pos + 1);\n if (next === 61) { return this.finishOp(types.assign, 2) }\n return this.finishOp(types.bitwiseXOR, 1)\n};\n\npp$8.readToken_plus_min = function(code) { // '+-'\n var next = this.input.charCodeAt(this.pos + 1);\n if (next === code) {\n if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 &&\n (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) {\n // A `-->` line comment\n this.skipLineComment(3);\n this.skipSpace();\n return this.nextToken()\n }\n return this.finishOp(types.incDec, 2)\n }\n if (next === 61) { return this.finishOp(types.assign, 2) }\n return this.finishOp(types.plusMin, 1)\n};\n\npp$8.readToken_lt_gt = function(code) { // '<>'\n var next = this.input.charCodeAt(this.pos + 1);\n var size = 1;\n if (next === code) {\n size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;\n if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types.assign, size + 1) }\n return this.finishOp(types.bitShift, size)\n }\n if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 &&\n this.input.charCodeAt(this.pos + 3) === 45) {\n // `` line comment\n this.skipLineComment(3);\n this.skipSpace();\n return this.nextToken()\n }\n return this.finishOp(types.incDec, 2)\n }\n if (next === 61) { return this.finishOp(types.assign, 2) }\n return this.finishOp(types.plusMin, 1)\n};\n\npp$8.readToken_lt_gt = function(code) { // '<>'\n var next = this.input.charCodeAt(this.pos + 1);\n var size = 1;\n if (next === code) {\n size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;\n if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types.assign, size + 1) }\n return this.finishOp(types.bitShift, size)\n }\n if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 &&\n this.input.charCodeAt(this.pos + 3) === 45) {\n // `\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)); -}); - -gulp.task('make', gulp.series('build', 'beautify', 'minify', 'build-tests')); - diff --git a/package-lock.json b/package-lock.json index ef8e266d..7f2c6ed4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,8573 +1,5381 @@ -{ - "name": "gpu.js", - "version": "2.0.4", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@nodelib/fs.scandir": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.1.tgz", - "integrity": "sha512-NT/skIZjgotDSiXs0WqYhgcuBKhUMgfekCmCGtkUAiLqZdOnrdjmZr9wRl3ll64J9NF79uZ4fk16Dx0yMc/Xbg==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.1", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.1.tgz", - "integrity": "sha512-+RqhBlLn6YRBGOIoVYthsG0J9dfpO79eJyN7BYBkZJtfqrBwf2KK+rD/M/yjZR6WBmIhAgOV7S60eCgaSWtbFw==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.2.tgz", - "integrity": "sha512-J/DR3+W12uCzAJkw7niXDcqcKBg6+5G5Q/ZpThpGNzAUz70eOR6RV4XnnSN01qHZiVl0eavoxJsBypQoKsV2QQ==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.1", - "fastq": "^1.6.0" - } - }, - "@sinonjs/commons": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.4.0.tgz", - "integrity": "sha512-9jHK3YF/8HtJ9wCAbG+j8cD0i0+ATS9A7gXFqS36TblLPNy6rEEc+SB0imo91eCboGaBYGV/MT1/br/J+EE7Tw==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/formatio": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.1.tgz", - "integrity": "sha512-tsHvOB24rvyvV2+zKMmPkZ7dXX6LSLKZ7aOtXY6Edklp0uRcgGpOsQTTGTcWViFyx4uhWc6GV8QdnALbIbIdeQ==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1", - "@sinonjs/samsam": "^3.1.0" - } - }, - "@sinonjs/samsam": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.2.tgz", - "integrity": "sha512-ILO/rR8LfAb60Y1Yfp9vxfYAASK43NFC2mLzpvLUbCQY/Qu8YwReboseu8aheCEkyElZF2L2T9mHcR2bgdvZyA==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.0.2", - "array-from": "^2.1.1", - "lodash": "^4.17.11" - } - }, - "@sinonjs/text-encoding": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", - "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/node": { - "version": "12.6.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.8.tgz", - "integrity": "sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg==", - "dev": true - }, - "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, - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "acorn": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", - "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==" - }, - "acorn-dynamic-import": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", - "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", - "dev": true - }, - "acorn-node": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.7.0.tgz", - "integrity": "sha512-XhahLSsCB6X6CJbe+uNu3Mn9sJBNFxtBN9NLgAOQovfS6Kh0lDUtmlclhjn9CvEK7A7YyRU13PXlNcpSiLI9Yw==", - "dev": true, - "requires": { - "acorn": "^6.1.1", - "acorn-dynamic-import": "^4.0.0", - "acorn-walk": "^6.1.1", - "xtend": "^4.0.1" - }, - "dependencies": { - "acorn": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz", - "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==", - "dev": true - } - } - }, - "acorn-walk": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", - "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", - "dev": true - }, - "after": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", - "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", - "dev": true - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "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, - "requires": { - "ansi-wrap": "^0.1.0" - } - }, - "ansi-cyan": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", - "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-gray": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", - "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-red": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", - "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", - "dev": true - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "append-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", - "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", - "dev": true, - "requires": { - "buffer-equal": "^1.0.0" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "requires": { - "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" - } - }, - "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==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-filter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", - "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=", - "dev": true, - "requires": { - "make-iterator": "^1.0.0" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", - "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=", - "dev": true, - "requires": { - "make-iterator": "^1.0.0" - } - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", - "dev": true - }, - "array-filter": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", - "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", - "dev": true - }, - "array-from": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", - "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", - "dev": true - }, - "array-initial": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", - "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=", - "dev": true, - "requires": { - "array-slice": "^1.0.0", - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, - "array-last": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", - "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", - "dev": true, - "requires": { - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, - "array-map": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", - "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=", - "dev": true - }, - "array-reduce": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", - "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=", - "dev": true - }, - "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 - }, - "array-sort": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", - "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", - "dev": true, - "requires": { - "default-compare": "^1.0.0", - "get-value": "^2.0.6", - "kind-of": "^5.0.2" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "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 - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "arraybuffer.slice": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", - "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "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, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dev": true, - "requires": { - "object-assign": "^4.1.1", - "util": "0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - } - } - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "async-done": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", - "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.2", - "process-nextick-args": "^2.0.0", - "stream-exhaust": "^1.0.1" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-each-series": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-0.1.1.tgz", - "integrity": "sha1-dhfBkXQB/Yykooqtzj266Yr+tDI=", - "dev": true - }, - "async-limiter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", - "dev": true - }, - "async-settle": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", - "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=", - "dev": true, - "requires": { - "async-done": "^1.2.2" - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "axios": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz", - "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==", - "dev": true, - "requires": { - "follow-redirects": "1.5.10", - "is-buffer": "^2.0.2" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", - "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==", - "dev": true - } - } - }, - "bach": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", - "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=", - "dev": true, - "requires": { - "arr-filter": "^1.1.1", - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "array-each": "^1.0.0", - "array-initial": "^1.0.0", - "array-last": "^1.1.1", - "async-done": "^1.2.2", - "async-settle": "^1.0.0", - "now-and-later": "^2.0.0" - } - }, - "backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "base64-arraybuffer": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", - "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", - "dev": true - }, - "base64-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", - "dev": true - }, - "base64id": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", - "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", - "dev": true - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "benchmark": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", - "integrity": "sha1-CfPeMckWQl1JjMLuVloOvzwqVik=", - "dev": true, - "requires": { - "lodash": "^4.17.4", - "platform": "^1.3.3" - } - }, - "better-assert": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", - "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", - "dev": true, - "requires": { - "callsite": "1.0.0" - } - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "binaryextensions": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-2.1.2.tgz", - "integrity": "sha512-xVNN69YGDghOqCCtA6FI7avYrr02mTJjOgB0/f1VPD3pJC8QEvjTKWc4epDx8AqxxA75NI0QpVM2gPJXUbE4Tg==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bit-twiddle": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bit-twiddle/-/bit-twiddle-1.0.2.tgz", - "integrity": "sha1-DGwfq+KyPRcXPZpht7cJPrnhdp4=" - }, - "bl": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", - "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", - "dev": true, - "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "blob": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", - "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", - "dev": true - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "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, - "requires": { - "JSONStream": "^1.0.3", - "combine-source-map": "~0.8.0", - "defined": "^1.0.0", - "safe-buffer": "^5.1.1", - "through2": "^2.0.0", - "umd": "^3.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "browser-resolve": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", - "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", - "dev": true, - "requires": { - "resolve": "1.1.7" - }, - "dependencies": { - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - } - } - }, - "browser-sync": { - "version": "2.26.7", - "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.26.7.tgz", - "integrity": "sha512-lY3emme0OyvA2ujEMpRmyRy9LY6gHLuTr2/ABxhIm3lADOiRXzP4dgekvnDrQqZ/Ec2Fz19lEjm6kglSG5766w==", - "dev": true, - "requires": { - "browser-sync-client": "^2.26.6", - "browser-sync-ui": "^2.26.4", - "bs-recipes": "1.3.4", - "bs-snippet-injector": "^2.0.1", - "chokidar": "^2.0.4", - "connect": "3.6.6", - "connect-history-api-fallback": "^1", - "dev-ip": "^1.0.1", - "easy-extender": "^2.3.4", - "eazy-logger": "^3", - "etag": "^1.8.1", - "fresh": "^0.5.2", - "fs-extra": "3.0.1", - "http-proxy": "1.15.2", - "immutable": "^3", - "localtunnel": "1.9.2", - "micromatch": "^3.1.10", - "opn": "5.3.0", - "portscanner": "2.1.1", - "qs": "6.2.3", - "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": "2.1.1", - "ua-parser-js": "0.7.17", - "yargs": "6.4.0" - }, - "dependencies": { - "qs": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz", - "integrity": "sha1-HPyyXBCpsrSDBT/zn138kjOQjP4=", - "dev": true - } - } - }, - "browser-sync-client": { - "version": "2.26.6", - "resolved": "https://registry.npmjs.org/browser-sync-client/-/browser-sync-client-2.26.6.tgz", - "integrity": "sha512-mGrkZdNzttKdf/16I+y+2dTQxoMCIpKbVIMJ/uP8ZpnKu9f9qa/2CYVtLtbjZG8nsM14EwiCrjuFTGBEnT3Gjw==", - "dev": true, - "requires": { - "etag": "1.8.1", - "fresh": "0.5.2", - "mitt": "^1.1.3", - "rxjs": "^5.5.6" - } - }, - "browser-sync-ui": { - "version": "2.26.4", - "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-2.26.4.tgz", - "integrity": "sha512-u20P3EsZoM8Pt+puoi3BU3KlbQAH1lAcV+/O4saF26qokrBqIDotmGonfWwoRbUmdxZkM9MBmA0K39ZTG1h4sA==", - "dev": true, - "requires": { - "async-each-series": "0.1.1", - "connect-history-api-fallback": "^1", - "immutable": "^3", - "server-destroy": "1.0.1", - "socket.io-client": "^2.0.4", - "stream-throttle": "^0.1.3" - } - }, - "browserify": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.3.0.tgz", - "integrity": "sha512-BWaaD7alyGZVEBBwSTYx4iJF5DswIGzK17o8ai9w4iKRbYpk3EOiprRHMRRA8DCZFmFeOdx7A385w2XdFvxWmg==", - "dev": true, - "requires": { - "JSONStream": "^1.0.3", - "assert": "^1.4.0", - "browser-pack": "^6.0.1", - "browser-resolve": "^1.11.0", - "browserify-zlib": "~0.2.0", - "buffer": "^5.0.2", - "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.0", - "domain-browser": "^1.2.0", - "duplexer2": "~0.1.2", - "events": "^2.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.0.0", - "labeled-stream-splicer": "^2.0.0", - "mkdirp": "^0.5.0", - "module-deps": "^6.0.0", - "os-browserify": "~0.3.0", - "parents": "^1.0.1", - "path-browserify": "~0.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": "^1.0.0", - "shell-quote": "^1.6.1", - "stream-browserify": "^2.0.0", - "stream-http": "^2.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.10.1", - "vm-browserify": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "string_decoder": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", - "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "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, - "requires": { - "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" - } - }, - "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, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "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, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "dev": true, - "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" - } - }, - "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, - "requires": { - "pako": "~1.0.5" - } - }, - "bs-recipes": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/bs-recipes/-/bs-recipes-1.3.4.tgz", - "integrity": "sha1-DS1NSKcYyMBEdp/cT4lZLci2lYU=", - "dev": true - }, - "bs-snippet-injector": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/bs-snippet-injector/-/bs-snippet-injector-2.0.1.tgz", - "integrity": "sha1-YbU5PxH1JVntEgaTEANDtu2wTdU=", - "dev": true - }, - "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, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", - "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", - "dev": true - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "cached-path-relative": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz", - "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==", - "dev": true - }, - "callsite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", - "dev": true - }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "chokidar": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", - "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "chownr": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", - "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==" - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "dev": true - }, - "clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", - "dev": true - }, - "clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", - "dev": true - }, - "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, - "requires": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, - "collection-map": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", - "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=", - "dev": true, - "requires": { - "arr-map": "^2.0.2", - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "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 - }, - "combine-source-map": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", - "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", - "dev": true, - "requires": { - "convert-source-map": "~1.1.0", - "inline-source-map": "~0.6.0", - "lodash.memoize": "~3.0.3", - "source-map": "~0.5.3" - } - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", - "dev": true - }, - "component-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", - "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", - "dev": true - }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, - "component-inherit": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", - "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "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, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "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, - "requires": { - "source-map": "^0.6.1" - }, - "dependencies": { - "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 - } - } - }, - "config-chain": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", - "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", - "dev": true, - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "connect": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", - "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", - "dev": true, - "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.0", - "parseurl": "~1.3.2", - "utils-merge": "1.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "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 - }, - "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "dev": true, - "requires": { - "date-now": "^0.1.4" - } - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "convert-source-map": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", - "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", - "dev": true - }, - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", - "dev": true - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "copy-props": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz", - "integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==", - "dev": true, - "requires": { - "each-props": "^1.3.0", - "is-plain-object": "^2.0.1" - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - } - }, - "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, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "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, - "requires": { - "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" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "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 - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "decomment": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/decomment/-/decomment-0.9.2.tgz", - "integrity": "sha512-sblyUmOJZxiL7oJ2ogJS6jtl/67+CTOW87SrYE/96u3PhDYikYoLCdLzcnceToiQejOLlqNnLCkaxx/+nE/ehg==", - "dev": true, - "requires": { - "esprima": "4.0.1" - } - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "requires": { - "mimic-response": "^1.0.0" - } - }, - "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==" - }, - "default-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", - "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", - "dev": true, - "requires": { - "kind-of": "^5.0.2" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "default-resolution": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", - "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", - "dev": true - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "deps-sort": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", - "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", - "dev": true, - "requires": { - "JSONStream": "^1.0.3", - "shasum": "^1.0.0", - "subarg": "^1.0.0", - "through2": "^2.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "des.js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", - "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", - "dev": true - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" - }, - "detective": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", - "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", - "dev": true, - "requires": { - "acorn-node": "^1.6.1", - "defined": "^1.0.0", - "minimist": "^1.1.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "dev-ip": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dev-ip/-/dev-ip-1.0.1.tgz", - "integrity": "sha1-p2o+0YVb56ASu4rBbLgPPADcKPA=", - "dev": true - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "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, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "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, - "requires": { - "path-type": "^4.0.0" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "each-props": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", - "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.1", - "object.defaults": "^1.1.0" - } - }, - "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, - "requires": { - "lodash": "^4.17.10" - } - }, - "eazy-logger": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-3.0.2.tgz", - "integrity": "sha1-oyWqXlPROiIliJsqxBE7K5Y29Pw=", - "dev": true, - "requires": { - "tfunk": "^3.0.1" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "editions": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", - "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==", - "dev": true - }, - "editorconfig": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", - "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", - "dev": true, - "requires": { - "commander": "^2.19.0", - "lru-cache": "^4.1.5", - "semver": "^5.6.0", - "sigmund": "^1.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true - } - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "elliptic": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.0.tgz", - "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "engine.io": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz", - "integrity": "sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "base64id": "1.0.0", - "cookie": "0.3.1", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.0", - "ws": "~3.3.1" - }, - "dependencies": { - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - } - } - }, - "engine.io-client": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.3.2.tgz", - "integrity": "sha512-y0CPINnhMvPuwtqXfsGuWE8BB66+B6wTtCofQDRecMQPYX3MYUZXFNKDhdrSe3EVjgOu4V3rxdeqN/Tr91IgbQ==", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.1", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "~6.1.0", - "xmlhttprequest-ssl": "~1.5.4", - "yeast": "0.1.2" - } - }, - "engine.io-parser": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", - "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", - "dev": true, - "requires": { - "after": "0.8.2", - "arraybuffer.slice": "~0.0.7", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.5", - "has-binary2": "~1.0.2" - } - }, - "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, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es5-ext": { - "version": "0.10.50", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.50.tgz", - "integrity": "sha512-KMzZTPBkeQV/JcSQhI5/z6d9VWJ3EnQ194USTUwIYZ2ZbpN8+SGXQKt1h68EX44+qt+Fzr8DO17vnxrw7c3agw==", - "dev": true, - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.1", - "next-tick": "^1.0.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "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 - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, - "eventemitter3": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz", - "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=", - "dev": true - }, - "events": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", - "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", - "dev": true - }, - "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, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "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==" - }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "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, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "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, - "requires": { - "ansi-gray": "^0.1.1", - "color-support": "^1.1.3", - "parse-node-version": "^1.0.0", - "time-stamp": "^1.0.0" - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.0.4.tgz", - "integrity": "sha512-wkIbV6qg37xTJwqSsdnIphL1e+LaGz4AIQqr00mIubMaEhv1/HEmJ0uuCGZRNRUkZZmOB5mJKO0ZUTVq+SxMQg==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.1", - "@nodelib/fs.walk": "^1.2.1", - "glob-parent": "^5.0.0", - "is-glob": "^4.0.1", - "merge2": "^1.2.3", - "micromatch": "^4.0.2" - }, - "dependencies": { - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "glob-parent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", - "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "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 - }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - }, - "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, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "fastq": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz", - "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==", - "dev": true, - "requires": { - "reusify": "^1.0.0" - } - }, - "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==" - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "finalhandler": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", - "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "findup-sync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", - "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "fined": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", - "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "is-plain-object": "^2.0.3", - "object.defaults": "^1.1.0", - "object.pick": "^1.2.0", - "parse-filepath": "^1.0.1" - } - }, - "flagged-respawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", - "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", - "dev": true - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "dev": true, - "requires": { - "debug": "=3.1.0" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "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==" - }, - "fs-extra": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", - "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^3.0.0", - "universalify": "^0.1.0" - } - }, - "fs-minipass": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.6.tgz", - "integrity": "sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ==", - "requires": { - "minipass": "^2.2.1" - } - }, - "fs-mkdirp-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", - "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "through2": "^2.0.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.3.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.3.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^4.1.0", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.12.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "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" - } - }, - "rimraf": { - "version": "2.6.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "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 - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" - }, - "gl": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/gl/-/gl-4.4.0.tgz", - "integrity": "sha512-4FIq5tqiltTsadrLh6DGY4R9+aQwj25OM2WlXEv81N6YN1q1C0qR7ct0SKp1uUJdnBqbKhUJP3zQ1td40AVeJg==", - "requires": { - "bindings": "^1.5.0", - "bit-twiddle": "^1.0.2", - "glsl-tokenizer": "^2.0.2", - "nan": "^2.14.0", - "node-gyp": "^4.0.0", - "prebuild-install": "^5.1.0" - } - }, - "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==" - }, - "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", - "dev": true, - "requires": { - "extend": "^3.0.0", - "glob": "^7.1.1", - "glob-parent": "^3.1.0", - "is-negated-glob": "^1.0.0", - "ordered-read-streams": "^1.0.0", - "pumpify": "^1.3.5", - "readable-stream": "^2.1.5", - "remove-trailing-separator": "^1.0.1", - "to-absolute-glob": "^2.0.0", - "unique-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "glob-watcher": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.3.tgz", - "integrity": "sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-done": "^1.2.0", - "chokidar": "^2.0.0", - "is-negated-glob": "^1.0.0", - "just-debounce": "^1.0.0", - "object.defaults": "^1.1.0" - } - }, - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - } - }, - "globby": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", - "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - } - }, - "glogg": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", - "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", - "dev": true, - "requires": { - "sparkles": "^1.0.0" - } - }, - "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==", - "requires": { - "through2": "^0.6.3" - } - }, - "gpu-mock.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/gpu-mock.js/-/gpu-mock.js-1.1.0.tgz", - "integrity": "sha512-kDMvQ04qIqbrpGyYCShx8NhZYMiolb1XUkjnJn92/jcMsxjcPF7KFfDMJEg0VUwxVJzD4djzJNWbmJCs00YEVg==" - }, - "graceful-fs": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", - "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==" - }, - "gulp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", - "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", - "dev": true, - "requires": { - "glob-watcher": "^5.0.3", - "gulp-cli": "^2.2.0", - "undertaker": "^1.2.1", - "vinyl-fs": "^3.0.0" - }, - "dependencies": { - "gulp-cli": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.2.0.tgz", - "integrity": "sha512-rGs3bVYHdyJpLqR0TUBnlcZ1O5O++Zs4bA0ajm+zr3WFCfiSLjGwoCBqFs18wzN+ZxahT9DkOK5nDf26iDsWjA==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "archy": "^1.0.0", - "array-sort": "^1.0.0", - "color-support": "^1.1.3", - "concat-stream": "^1.6.0", - "copy-props": "^2.0.1", - "fancy-log": "^1.3.2", - "gulplog": "^1.0.0", - "interpret": "^1.1.0", - "isobject": "^3.0.1", - "liftoff": "^3.1.0", - "matchdep": "^2.0.0", - "mute-stdout": "^1.0.0", - "pretty-hrtime": "^1.0.0", - "replace-homedir": "^1.0.0", - "semver-greatest-satisfied-range": "^1.1.0", - "v8flags": "^3.0.1", - "yargs": "^7.1.0" - } - }, - "yargs": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", - "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^5.0.0" - } - }, - "yargs-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", - "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", - "dev": true, - "requires": { - "camelcase": "^3.0.0" - } - } - } - }, - "gulp-concat": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz", - "integrity": "sha1-Yz0WyV2IUEYorQJmVmPO5aR5M1M=", - "dev": true, - "requires": { - "concat-with-sourcemaps": "^1.0.0", - "through2": "^2.0.0", - "vinyl": "^2.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "gulp-header": { - "version": "1.8.12", - "resolved": "https://registry.npmjs.org/gulp-header/-/gulp-header-1.8.12.tgz", - "integrity": "sha512-lh9HLdb53sC7XIZOYzTXM4lFuXElv3EVkSDhsd7DoJBj7hm+Ni7D3qYbb+Rr8DuM8nRanBvkVO9d7askreXGnQ==", - "dev": true, - "requires": { - "concat-with-sourcemaps": "*", - "lodash.template": "^4.4.0", - "through2": "^2.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "gulp-jsbeautifier": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/gulp-jsbeautifier/-/gulp-jsbeautifier-2.1.2.tgz", - "integrity": "sha512-tZUk4c11zF8xzCCTOEmktxGitv/H2vpAcflZNVU8nxL+G5XxQyLJUJVUKylz7/dax+FXb3YwQYByaJ+yxmo8iw==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "fancy-log": "^1.3.2", - "js-beautify": "^1.7.5", - "lodash": "^4.17.4", - "plugin-error": "^0.1.2", - "rc": "^1.2.2", - "through2": "^2.0.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "gulp-rename": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-1.4.0.tgz", - "integrity": "sha512-swzbIGb/arEoFK89tPY58vg3Ok1bw+d35PfUNwWqdo7KM4jkmuGA78JiDNqR+JeZFaeeHnRg9N7aihX3YPmsyg==", - "dev": true - }, - "gulp-replace": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulp-replace/-/gulp-replace-1.0.0.tgz", - "integrity": "sha512-lgdmrFSI1SdhNMXZQbrC75MOl1UjYWlOWNbNRnz+F/KHmgxt3l6XstBoAYIdadwETFyG/6i+vWUSCawdC3pqOw==", - "dev": true, - "requires": { - "istextorbinary": "2.2.1", - "readable-stream": "^2.0.1", - "replacestream": "^4.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "gulp-strip-comments": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/gulp-strip-comments/-/gulp-strip-comments-2.5.2.tgz", - "integrity": "sha512-lb1bW7rsPWDD8f4ZPSguDvmCdjKmjr5HR4yZb9ros3sLl5AfW7oUj8KzY9/VRisT7dG8dL7hVHzNpQEVxfwZGQ==", - "dev": true, - "requires": { - "decomment": "^0.9.0", - "plugin-error": "^0.1.2", - "through2": "^2.0.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "gulp-uglify-es": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/gulp-uglify-es/-/gulp-uglify-es-1.0.4.tgz", - "integrity": "sha512-UMRufZsBmQizCYpftutaiVoLswpbzFEfY90EJLU4YlTgculeHnanb794s88TMd5tpCZVC638sAX6JrLVYTP/Wg==", - "dev": true, - "requires": { - "o-stream": "^0.2.2", - "plugin-error": "^1.0.1", - "terser": "^3.7.5", - "vinyl": "^2.1.0", - "vinyl-sourcemaps-apply": "^0.2.1" - }, - "dependencies": { - "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, - "requires": { - "ansi-colors": "^1.0.1", - "arr-diff": "^4.0.0", - "arr-union": "^3.1.0", - "extend-shallow": "^3.0.2" - } - } - } - }, - "gulplog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", - "dev": true, - "requires": { - "glogg": "^1.0.0" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-binary2": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", - "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", - "dev": true, - "requires": { - "isarray": "2.0.1" - }, - "dependencies": { - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", - "dev": true - } - } - }, - "has-cors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "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, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "requires": { - "parse-passwd": "^1.0.0" - } - }, - "hosted-git-info": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", - "dev": true - }, - "htmlescape": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", - "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", - "dev": true - }, - "http-errors": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", - "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - } - } - }, - "http-proxy": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.15.2.tgz", - "integrity": "sha1-ZC/cr/5S00SNK9o7AHnpQJBk2jE=", - "dev": true, - "requires": { - "eventemitter3": "1.x.x", - "requires-port": "1.x.x" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "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, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "ignore": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.2.tgz", - "integrity": "sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ==", - "dev": true - }, - "immutable": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", - "integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM=", - "dev": true - }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" - }, - "inline-source-map": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", - "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", - "dev": true, - "requires": { - "source-map": "~0.5.3" - } - }, - "insert-module-globals": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz", - "integrity": "sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw==", - "dev": true, - "requires": { - "JSONStream": "^1.0.3", - "acorn-node": "^1.5.2", - "combine-source-map": "^0.8.0", - "concat-stream": "^1.6.1", - "is-buffer": "^1.1.0", - "path-is-absolute": "^1.0.1", - "process": "~0.11.0", - "through2": "^2.0.0", - "undeclared-identifiers": "^1.1.2", - "xtend": "^4.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "interpret": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", - "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", - "dev": true - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "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, - "requires": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "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 - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negated-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "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, - "requires": { - "lodash.isfinite": "^3.3.2" - } - }, - "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 - }, - "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, - "requires": { - "is-path-inside": "^3.0.1" - } - }, - "is-path-inside": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.1.tgz", - "integrity": "sha512-CKstxrctq1kUesU6WhtZDbYKzzYBuRH0UYInAVrkc/EYdB9ltbfE0gOoayG9nhohG6447sOOVGhHqsdmBvkbNg==", - "dev": true - }, - "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, - "requires": { - "isobject": "^3.0.1" - } - }, - "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, - "requires": { - "is-unc-path": "^1.0.0" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "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, - "requires": { - "unc-path-regex": "^0.1.2" - } - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, - "is-valid-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", - "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", - "dev": true - }, - "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 - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "istextorbinary": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-2.2.1.tgz", - "integrity": "sha512-TS+hoFl8Z5FAFMK38nhBkdLt44CclNRgDHWeMgsV8ko3nDlr/9UI2Sf839sW7enijf8oKsZYXRvM8g0it9Zmcw==", - "dev": true, - "requires": { - "binaryextensions": "2", - "editions": "^1.3.3", - "textextensions": "2" - } - }, - "js-beautify": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.10.1.tgz", - "integrity": "sha512-4y8SHOIRC+/YQ2gs3zJEKBUraQerq49FJYyXRpdzUGYQzCq8q9xtIh0YXial1S5KmonVui4aiUb6XaGyjE51XA==", - "dev": true, - "requires": { - "config-chain": "^1.1.12", - "editorconfig": "^0.15.3", - "glob": "^7.1.3", - "mkdirp": "~0.5.1", - "nopt": "~4.0.1" - }, - "dependencies": { - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "dev": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - } - } - }, - "js-reporters": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/js-reporters/-/js-reporters-1.2.1.tgz", - "integrity": "sha1-+IxgjjJKM3OpW8xFrTBeXJecRZs=", - "dev": true - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stable-stringify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", - "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", - "dev": true, - "requires": { - "jsonify": "~0.0.0" - } - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "jsonfile": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", - "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, - "jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", - "dev": true - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "just-debounce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz", - "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=", - "dev": true - }, - "just-extend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", - "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "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, - "requires": { - "inherits": "^2.0.1", - "stream-splicer": "^2.0.0" - } - }, - "last-run": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", - "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=", - "dev": true, - "requires": { - "default-resolution": "^2.0.0", - "es6-weak-map": "^2.0.1" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "lead": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", - "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", - "dev": true, - "requires": { - "flush-write-stream": "^1.0.2" - } - }, - "liftoff": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", - "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", - "dev": true, - "requires": { - "extend": "^3.0.0", - "findup-sync": "^3.0.0", - "fined": "^1.0.1", - "flagged-respawn": "^1.0.0", - "is-plain-object": "^2.0.4", - "object.map": "^1.0.0", - "rechoir": "^0.6.2", - "resolve": "^1.1.7" - } - }, - "limiter": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.4.tgz", - "integrity": "sha512-XCpr5bElgDI65vVgstP8TWjv6/QKWm9GU5UG0Pr5sLQ3QLo8NVKsioe+Jed5/3vFOe3IQuqE7DKwTvKQkjTHvg==", - "dev": true - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "localtunnel": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-1.9.2.tgz", - "integrity": "sha512-NEKF7bDJE9U3xzJu3kbayF0WTvng6Pww7tzqNb/XtEARYwqw7CKEX7BvOMg98FtE9es2CRizl61gkV3hS8dqYg==", - "dev": true, - "requires": { - "axios": "0.19.0", - "debug": "4.1.1", - "openurl": "1.1.1", - "yargs": "6.6.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "yargs": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", - "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^4.2.0" - } - } - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, - "lodash.isfinite": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz", - "integrity": "sha1-+4m2WpqAKBgz8LdHizpRBPiY67M=", - "dev": true - }, - "lodash.memoize": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", - "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", - "dev": true - }, - "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==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "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, - "requires": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "lolex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-4.1.0.tgz", - "integrity": "sha512-BYxIEXiVq5lGIXeVHnsFzqa1TxN5acnKnPCdlZSpzm8viNEOhiigupA4vTQ9HEFQ6nLTQ9wQOgBknJgzUYQ9Aw==", - "dev": true - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - }, - "dependencies": { - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - } - } - }, - "make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "matchdep": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", - "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=", - "dev": true, - "requires": { - "findup-sync": "^2.0.0", - "micromatch": "^3.0.4", - "resolve": "^1.4.0", - "stack-trace": "0.0.10" - }, - "dependencies": { - "findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^3.1.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "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, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "merge-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", - "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "merge2": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz", - "integrity": "sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "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, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", - "dev": true - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" - }, - "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 - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "minipass": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.5.1.tgz", - "integrity": "sha512-dmpSnLJtNQioZFI5HfQ55Ad0DzzsMAb+HfokwRTNXwEQjepbTkl5mtIlSVxGIkOkxlpX7wIn5ET/oAd9fZ/Y/Q==", - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", - "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", - "requires": { - "minipass": "^2.2.1" - } - }, - "mitt": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.1.3.tgz", - "integrity": "sha512-mUDCnVNsAi+eD6qA0HkRkwYczbLHJ49z17BGe2PYRhZL4wpZUFZGJHU7/5tmvohoma+Hdn0Vh/oJTiPEmgSruA==", - "dev": true - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "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, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - } - }, - "module-deps": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.1.tgz", - "integrity": "sha512-UnEn6Ah36Tu4jFiBbJVUtt0h+iXqxpLqDvPS8nllbw5RZFmNJ1+Mz5BjYnM9ieH80zyxHkARGLnMIHlPK5bu6A==", - "dev": true, - "requires": { - "JSONStream": "^1.0.3", - "browser-resolve": "^1.7.0", - "cached-path-relative": "^1.0.2", - "concat-stream": "~1.6.0", - "defined": "^1.0.0", - "detective": "^5.0.2", - "duplexer2": "^0.1.2", - "inherits": "^2.0.1", - "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" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "mute-stdout": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", - "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", - "dev": true - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "napi-build-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.1.tgz", - "integrity": "sha512-boQj1WFgQH3v4clhu3mTNfP+vOBxorDlE8EKiMjUlLG3C4qAESnn9AxIOkFgTR2c9LtzNjPrjS60cT27ZKBhaA==" - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true - }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", - "dev": true - }, - "nise": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.0.tgz", - "integrity": "sha512-Z3sfYEkLFzFmL8KY6xnSJLRxwQwYBjOXi/24lb62ZnZiGA0JUzGGTI6TBIgfCSMIDl9Jlu8SRmHNACLTemDHww==", - "dev": true, - "requires": { - "@sinonjs/formatio": "^3.1.0", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "lolex": "^4.1.0", - "path-to-regexp": "^1.7.0" - } - }, - "node-abi": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.11.0.tgz", - "integrity": "sha512-kuy/aEg75u40v378WRllQ4ZexaXJiCvB68D2scDXclp/I4cRq6togpbOoKhmN07tns9Zldu51NNERo0wehfX9g==", - "requires": { - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "node-gyp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-4.0.0.tgz", - "integrity": "sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA==", - "requires": { - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", - "request": "^2.87.0", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^4.4.8", - "which": "1" - } - }, - "node-watch": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.6.0.tgz", - "integrity": "sha512-XAgTL05z75ptd7JSVejH1a2Dm1zmXYhuDr9l230Qk6Z7/7GPcnAs/UyJJ4ggsXSvWil8iOzwQLW0zuGUvHpG8g==", - "dev": true - }, - "noop-logger": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", - "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" - }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "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 - }, - "now-and-later": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", - "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", - "dev": true, - "requires": { - "once": "^1.3.2" - } - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, - "o-stream": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/o-stream/-/o-stream-0.2.2.tgz", - "integrity": "sha512-V3j76KU3g/Gyl8rpdi2z72rn5zguMvTCQgAXfBe3pxEefKqXmOUOD7mvx/mNjykdxGqDVfpSoo8r+WdrkWg/1Q==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-component": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", - "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "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 - }, - "object-path": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.9.2.tgz", - "integrity": "sha1-D9mnT8X60a45aLWGvaXGMr1sBaU=", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", - "dev": true, - "requires": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "object.map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "object.reduce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", - "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "openurl": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/openurl/-/openurl-1.1.1.tgz", - "integrity": "sha1-OHW0sO96UsFW8NtB1GCduw+Us4c=", - "dev": true - }, - "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, - "requires": { - "is-wsl": "^1.1.0" - } - }, - "ordered-read-streams": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", - "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "pako": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", - "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", - "dev": true - }, - "parents": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", - "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", - "dev": true, - "requires": { - "path-platform": "~0.11.15" - } - }, - "parse-asn1": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", - "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==", - "dev": true, - "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-filepath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "map-cache": "^0.2.0", - "path-root": "^0.1.1" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "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 - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true - }, - "parseqs": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", - "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseuri": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", - "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "path-platform": { - "version": "0.11.15", - "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", - "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", - "dev": true - }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", - "dev": true, - "requires": { - "path-root-regex": "^0.1.0" - } - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", - "dev": true - }, - "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 - }, - "path-to-regexp": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", - "dev": true, - "requires": { - "isarray": "0.0.1" - } - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.7.tgz", - "integrity": "sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "platform": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.5.tgz", - "integrity": "sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q==", - "dev": true - }, - "plugin-error": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", - "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", - "dev": true, - "requires": { - "ansi-cyan": "^0.1.1", - "ansi-red": "^0.1.1", - "arr-diff": "^1.0.1", - "arr-union": "^2.0.1", - "extend-shallow": "^1.1.2" - }, - "dependencies": { - "arr-diff": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", - "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1", - "array-slice": "^0.2.3" - } - }, - "arr-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", - "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=", - "dev": true - }, - "array-slice": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", - "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", - "dev": true - }, - "extend-shallow": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", - "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", - "dev": true, - "requires": { - "kind-of": "^1.1.0" - } - }, - "kind-of": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", - "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", - "dev": true - } - } - }, - "portscanner": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.1.1.tgz", - "integrity": "sha1-6rtAnk3iSVD1oqUW01rnaTQ/u5Y=", - "dev": true, - "requires": { - "async": "1.5.2", - "is-number-like": "^1.0.3" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "prebuild-install": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.1.tgz", - "integrity": "sha512-lRLBU0JPXBbpC/ER9PtVYYk1y9Rme1WiMA3WKEQ4v78A5kTsqQtrEyYlbghvXCA6Uhr/769SkhibQznjDBRZpg==", - "requires": { - "detect-libc": "^1.0.3", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "napi-build-utils": "^1.0.1", - "node-abi": "^2.7.0", - "noop-logger": "^0.1.1", - "npmlog": "^4.0.1", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^3.0.3", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0", - "which-pm-runs": "^1.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", - "dev": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "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==" - }, - "proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "psl": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", - "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "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" - } - }, - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "qunit": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.9.2.tgz", - "integrity": "sha512-wTOYHnioWHcx5wa85Wl15IE7D6zTZe2CQlsodS14yj7s2FZ3MviRnQluspBZsueIDEO7doiuzKlv05yfky1R7w==", - "dev": true, - "requires": { - "commander": "2.12.2", - "js-reporters": "1.2.1", - "minimatch": "3.0.4", - "node-watch": "0.6.0", - "resolve": "1.9.0" - }, - "dependencies": { - "commander": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz", - "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==", - "dev": true - }, - "resolve": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz", - "integrity": "sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "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, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "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 - }, - "raw-body": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", - "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.3", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } - } - }, - "read-dir-deep": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-dir-deep/-/read-dir-deep-7.0.1.tgz", - "integrity": "sha512-w99fvgqJm3cJ5Vb7b3oGKRDnm/m11q7w5LQ9uBCXe+repIEf1rFtkXLlPAxNrSwlp4skyPyvKd4DNNiIuc0geg==", - "dev": true, - "requires": { - "globby": "^10.0.1", - "is-path-cwd": "^2.2.0", - "is-path-in-cwd": "^3.0.0", - "path-sort2": "^1.0.0", - "slash": "^3.0.0" - } - }, - "read-only-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", - "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "^1.1.6" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-bom-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", - "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5", - "is-utf8": "^0.2.1" - } - }, - "remove-bom-stream": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", - "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", - "dev": true, - "requires": { - "remove-bom-buffer": "^3.0.0", - "safe-buffer": "^5.1.0", - "through2": "^2.0.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", - "dev": true - }, - "replace-homedir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", - "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1", - "is-absolute": "^1.0.0", - "remove-trailing-separator": "^1.1.0" - } - }, - "replacestream": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/replacestream/-/replacestream-4.0.3.tgz", - "integrity": "sha512-AC0FiLS352pBBiZhd4VXB1Ab/lh0lEgpP+GGvZqbQh8a5cmXVoTe5EX/YeTFArnp4SRGTHh1qCHu9lGs1qG8sA==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.3", - "object-assign": "^4.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", - "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - } - }, - "resolve-options": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", - "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", - "dev": true, - "requires": { - "value-or-function": "^3.0.0" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "resp-modifier": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/resp-modifier/-/resp-modifier-6.0.2.tgz", - "integrity": "sha1-sSTeXE+6/LpUH0j/pzlw9KpFa08=", - "dev": true, - "requires": { - "debug": "^2.2.0", - "minimatch": "^3.0.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", - "dev": true - }, - "rx": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", - "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", - "dev": true - }, - "rxjs": { - "version": "5.5.12", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", - "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", - "dev": true, - "requires": { - "symbol-observable": "1.0.1" - } - }, - "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==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" - }, - "semver-greatest-satisfied-range": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", - "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=", - "dev": true, - "requires": { - "sver-compat": "^1.5.0" - } - }, - "send": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", - "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - }, - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", - "dev": true - } - } - }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - } - } - }, - "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, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.2", - "send": "0.16.2" - } - }, - "server-destroy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", - "integrity": "sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0=", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "dev": true - }, - "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, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shasum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", - "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", - "dev": true, - "requires": { - "json-stable-stringify": "~0.0.0", - "sha.js": "~2.4.4" - } - }, - "shell-quote": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", - "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", - "dev": true, - "requires": { - "array-filter": "~0.0.0", - "array-map": "~0.0.0", - "array-reduce": "~0.0.0", - "jsonify": "~0.0.0" - } - }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "simple-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", - "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" - }, - "simple-get": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.0.3.tgz", - "integrity": "sha512-Wvre/Jq5vgoz31Z9stYWPLn0PqRqmBDpFSdypAnHu5AvRVCYPRYGnvryNLiXu8GOBNDH82J2FRHUGMjjHUpXFw==", - "requires": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "sinon": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.3.2.tgz", - "integrity": "sha512-thErC1z64BeyGiPvF8aoSg0LEnptSaWE7YhdWWbWXgelOyThent7uKOnnEh9zBxDbKixtr5dEko+ws1sZMuFMA==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.4.0", - "@sinonjs/formatio": "^3.2.1", - "@sinonjs/samsam": "^3.3.1", - "diff": "^3.5.0", - "lolex": "^4.0.1", - "nise": "^1.4.10", - "supports-color": "^5.5.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "socket.io": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz", - "integrity": "sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==", - "dev": true, - "requires": { - "debug": "~3.1.0", - "engine.io": "~3.2.0", - "has-binary2": "~1.0.2", - "socket.io-adapter": "~1.1.0", - "socket.io-client": "2.1.1", - "socket.io-parser": "~3.2.0" - }, - "dependencies": { - "engine.io-client": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", - "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.1", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "~3.3.1", - "xmlhttprequest-ssl": "~1.5.4", - "yeast": "0.1.2" - } - }, - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", - "dev": true - }, - "socket.io-client": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz", - "integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==", - "dev": true, - "requires": { - "backo2": "1.0.2", - "base64-arraybuffer": "0.1.5", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "engine.io-client": "~3.2.0", - "has-binary2": "~1.0.2", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "socket.io-parser": "~3.2.0", - "to-array": "0.1.4" - } - }, - "socket.io-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", - "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "isarray": "2.0.1" - } - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - } - } - }, - "socket.io-adapter": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", - "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=", - "dev": true - }, - "socket.io-client": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.2.0.tgz", - "integrity": "sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA==", - "dev": true, - "requires": { - "backo2": "1.0.2", - "base64-arraybuffer": "0.1.5", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "engine.io-client": "~3.3.1", - "has-binary2": "~1.0.2", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "socket.io-parser": "~3.3.0", - "to-array": "0.1.4" - } - }, - "socket.io-parser": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", - "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "isarray": "2.0.1" - }, - "dependencies": { - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", - "dev": true - } - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, - "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.12", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", - "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "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 - } - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "sparkles": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", - "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", - "dev": true - }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", - "dev": true - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", - "dev": true - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-combiner2": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", - "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", - "dev": true, - "requires": { - "duplexer2": "~0.1.0", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "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 - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", - "dev": true - }, - "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, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-throttle": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/stream-throttle/-/stream-throttle-0.1.3.tgz", - "integrity": "sha1-rdV8jXzHOoFjDTHNVdOWHPr7qcM=", - "dev": true, - "requires": { - "commander": "^2.2.0", - "limiter": "^1.0.5" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "sver-compat": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", - "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=", - "dev": true, - "requires": { - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, - "symbol-observable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", - "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=", - "dev": true - }, - "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, - "requires": { - "acorn-node": "^1.2.0" - } - }, - "tar": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", - "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.5", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - }, - "tar-fs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz", - "integrity": "sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==", - "requires": { - "chownr": "^1.1.1", - "mkdirp": "^0.5.1", - "pump": "^3.0.0", - "tar-stream": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "tar-stream": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.0.tgz", - "integrity": "sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==", - "requires": { - "bl": "^3.0.0", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "dependencies": { - "bl": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz", - "integrity": "sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==", - "requires": { - "readable-stream": "^3.0.1" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "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==", - "requires": { - "safe-buffer": "~5.2.0" - } - } - } - }, - "terser": { - "version": "3.17.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz", - "integrity": "sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ==", - "dev": true, - "requires": { - "commander": "^2.19.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.10" - }, - "dependencies": { - "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 - } - } - }, - "textextensions": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-2.4.0.tgz", - "integrity": "sha512-qftQXnX1DzpSV8EddtHIT0eDDEiBF8ywhFYR2lI9xrGtxqKN+CvLXhACeCIGbCpQfxxERbrkZEFb8cZcDKbVZA==", - "dev": true - }, - "tfunk": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tfunk/-/tfunk-3.1.0.tgz", - "integrity": "sha1-OORBT8ZJd9h6/apy+sttKfgve1s=", - "dev": true, - "requires": { - "chalk": "^1.1.1", - "object-path": "^0.9.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } - }, - "through2-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", - "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", - "dev": true, - "requires": { - "through2": "~2.0.0", - "xtend": "~4.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", - "dev": true - }, - "timers-browserify": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", - "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", - "dev": true, - "requires": { - "process": "~0.11.0" - } - }, - "to-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "is-negated-glob": "^1.0.0" - } - }, - "to-array": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", - "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", - "dev": true - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "to-through": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", - "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", - "dev": true, - "requires": { - "through2": "^2.0.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "dev": true - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "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 - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "type": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/type/-/type-1.0.1.tgz", - "integrity": "sha512-MAM5dBMJCJNKs9E7JXo4CXRAansRfG0nlJxW7Wf6GZzSOvH31zClSaHdIMWLehe/EGMBkqeC55rrkaOr5Oo7Nw==", - "dev": true - }, - "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 - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "ua-parser-js": { - "version": "0.7.17", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz", - "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g==", - "dev": true - }, - "ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", - "dev": true - }, - "umd": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", - "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", - "dev": true - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", - "dev": true - }, - "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, - "requires": { - "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" - } - }, - "undertaker": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.1.tgz", - "integrity": "sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "bach": "^1.0.0", - "collection-map": "^1.0.0", - "es6-weak-map": "^2.0.1", - "last-run": "^1.1.0", - "object.defaults": "^1.0.0", - "object.reduce": "^1.0.0", - "undertaker-registry": "^1.0.0" - } - }, - "undertaker-registry": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", - "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=", - "dev": true - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", - "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", - "dev": true, - "requires": { - "json-stable-stringify-without-jsonify": "^1.0.1", - "through2-filter": "^3.0.0" - } - }, - "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 - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - } - } - }, - "upath": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", - "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true - }, - "uuid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", - "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" - }, - "v8flags": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", - "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "value-or-function": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", - "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vinyl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", - "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", - "dev": true, - "requires": { - "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" - } - }, - "vinyl-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vinyl-buffer/-/vinyl-buffer-1.0.1.tgz", - "integrity": "sha1-lsGjR5uMU5JULGEgKQE7Wyf4i78=", - "dev": true, - "requires": { - "bl": "^1.2.1", - "through2": "^2.0.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "vinyl-fs": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", - "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", - "dev": true, - "requires": { - "fs-mkdirp-stream": "^1.0.0", - "glob-stream": "^6.1.0", - "graceful-fs": "^4.0.0", - "is-valid-glob": "^1.0.0", - "lazystream": "^1.0.0", - "lead": "^1.0.0", - "object.assign": "^4.0.4", - "pumpify": "^1.3.5", - "readable-stream": "^2.3.3", - "remove-bom-buffer": "^3.0.0", - "remove-bom-stream": "^1.2.0", - "resolve-options": "^1.1.0", - "through2": "^2.0.0", - "to-through": "^2.0.0", - "value-or-function": "^3.0.0", - "vinyl": "^2.0.0", - "vinyl-sourcemap": "^1.1.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "vinyl-source-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/vinyl-source-stream/-/vinyl-source-stream-2.0.0.tgz", - "integrity": "sha1-84pa+53R6Ttl1VBGmsYYKsT1S44=", - "dev": true, - "requires": { - "through2": "^2.0.3", - "vinyl": "^2.1.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "vinyl-sourcemap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", - "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", - "dev": true, - "requires": { - "append-buffer": "^1.0.2", - "convert-source-map": "^1.5.0", - "graceful-fs": "^4.1.6", - "normalize-path": "^2.1.1", - "now-and-later": "^2.0.0", - "remove-bom-buffer": "^3.0.0", - "vinyl": "^2.0.0" - }, - "dependencies": { - "convert-source-map": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "vinyl-sourcemaps-apply": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", - "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", - "dev": true, - "requires": { - "source-map": "^0.5.1" - } - }, - "vm-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", - "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", - "dev": true - }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "window-size": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", - "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=", - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "ws": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", - "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } - }, - "xmlhttprequest-ssl": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", - "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" - }, - "yargs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.4.0.tgz", - "integrity": "sha1-gW4ahm1VmMzzTlWW3c4i2S2kkNQ=", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "window-size": "^0.2.0", - "y18n": "^3.2.1", - "yargs-parser": "^4.1.0" - } - }, - "yargs-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", - "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", - "dev": true, - "requires": { - "camelcase": "^3.0.0" - } - }, - "yeast": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", - "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", - "dev": true - } - } -} +{ + "name": "gpu.js", + "version": "2.0.5", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.1.tgz", + "integrity": "sha512-NT/skIZjgotDSiXs0WqYhgcuBKhUMgfekCmCGtkUAiLqZdOnrdjmZr9wRl3ll64J9NF79uZ4fk16Dx0yMc/Xbg==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.1", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.1.tgz", + "integrity": "sha512-+RqhBlLn6YRBGOIoVYthsG0J9dfpO79eJyN7BYBkZJtfqrBwf2KK+rD/M/yjZR6WBmIhAgOV7S60eCgaSWtbFw==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.2.tgz", + "integrity": "sha512-J/DR3+W12uCzAJkw7niXDcqcKBg6+5G5Q/ZpThpGNzAUz70eOR6RV4XnnSN01qHZiVl0eavoxJsBypQoKsV2QQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.1", + "fastq": "^1.6.0" + } + }, + "@sinonjs/commons": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.6.0.tgz", + "integrity": "sha512-w4/WHG7C4WWFyE5geCieFJF6MZkbW4VAriol5KlmQXpAQdxvV0p26sqNZOW6Qyw6Y0l9K4g+cHvvczR2sEEpqg==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/formatio": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.1.tgz", + "integrity": "sha512-tsHvOB24rvyvV2+zKMmPkZ7dXX6LSLKZ7aOtXY6Edklp0uRcgGpOsQTTGTcWViFyx4uhWc6GV8QdnALbIbIdeQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1", + "@sinonjs/samsam": "^3.1.0" + } + }, + "@sinonjs/samsam": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", + "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.3.0", + "array-from": "^2.1.1", + "lodash": "^4.17.15" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "dev": true + }, + "@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dev": true, + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "@types/node": { + "version": "12.6.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.8.tgz", + "integrity": "sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg==", + "dev": true + }, + "@types/resolve": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", + "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==" + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", + "dev": true + }, + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "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" + } + }, + "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==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-from": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", + "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", + "dev": true + }, + "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 + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "async-each-series": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-0.1.1.tgz", + "integrity": "sha1-dhfBkXQB/Yykooqtzj266Yr+tDI=", + "dev": true + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + }, + "axios": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz", + "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==", + "dev": true, + "requires": { + "follow-redirects": "1.5.10", + "is-buffer": "^2.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", + "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==", + "dev": true + } + } + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", + "dev": true + }, + "base64id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "benchmark": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", + "integrity": "sha1-CfPeMckWQl1JjMLuVloOvzwqVik=", + "dev": true, + "requires": { + "lodash": "^4.17.4", + "platform": "^1.3.3" + } + }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "dev": true, + "requires": { + "callsite": "1.0.0" + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bit-twiddle": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bit-twiddle/-/bit-twiddle-1.0.2.tgz", + "integrity": "sha1-DGwfq+KyPRcXPZpht7cJPrnhdp4=" + }, + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "browser-sync": { + "version": "2.26.7", + "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.26.7.tgz", + "integrity": "sha512-lY3emme0OyvA2ujEMpRmyRy9LY6gHLuTr2/ABxhIm3lADOiRXzP4dgekvnDrQqZ/Ec2Fz19lEjm6kglSG5766w==", + "dev": true, + "requires": { + "browser-sync-client": "^2.26.6", + "browser-sync-ui": "^2.26.4", + "bs-recipes": "1.3.4", + "bs-snippet-injector": "^2.0.1", + "chokidar": "^2.0.4", + "connect": "3.6.6", + "connect-history-api-fallback": "^1", + "dev-ip": "^1.0.1", + "easy-extender": "^2.3.4", + "eazy-logger": "^3", + "etag": "^1.8.1", + "fresh": "^0.5.2", + "fs-extra": "3.0.1", + "http-proxy": "1.15.2", + "immutable": "^3", + "localtunnel": "1.9.2", + "micromatch": "^3.1.10", + "opn": "5.3.0", + "portscanner": "2.1.1", + "qs": "6.2.3", + "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": "2.1.1", + "ua-parser-js": "0.7.17", + "yargs": "6.4.0" + }, + "dependencies": { + "qs": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz", + "integrity": "sha1-HPyyXBCpsrSDBT/zn138kjOQjP4=", + "dev": true + } + } + }, + "browser-sync-client": { + "version": "2.26.6", + "resolved": "https://registry.npmjs.org/browser-sync-client/-/browser-sync-client-2.26.6.tgz", + "integrity": "sha512-mGrkZdNzttKdf/16I+y+2dTQxoMCIpKbVIMJ/uP8ZpnKu9f9qa/2CYVtLtbjZG8nsM14EwiCrjuFTGBEnT3Gjw==", + "dev": true, + "requires": { + "etag": "1.8.1", + "fresh": "0.5.2", + "mitt": "^1.1.3", + "rxjs": "^5.5.6" + } + }, + "browser-sync-ui": { + "version": "2.26.4", + "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-2.26.4.tgz", + "integrity": "sha512-u20P3EsZoM8Pt+puoi3BU3KlbQAH1lAcV+/O4saF26qokrBqIDotmGonfWwoRbUmdxZkM9MBmA0K39ZTG1h4sA==", + "dev": true, + "requires": { + "async-each-series": "0.1.1", + "connect-history-api-fallback": "^1", + "immutable": "^3", + "server-destroy": "1.0.1", + "socket.io-client": "^2.0.4", + "stream-throttle": "^0.1.3" + } + }, + "bs-recipes": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/bs-recipes/-/bs-recipes-1.3.4.tgz", + "integrity": "sha1-DS1NSKcYyMBEdp/cT4lZLci2lYU=", + "dev": true + }, + "bs-snippet-injector": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bs-snippet-injector/-/bs-snippet-injector-2.0.1.tgz", + "integrity": "sha1-YbU5PxH1JVntEgaTEANDtu2wTdU=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "builtin-modules": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", + "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==", + "dev": true + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", + "dev": true + }, + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "chownr": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", + "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==" + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "dev": true + }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", + "dev": true + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "connect": { + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", + "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", + "dev": true, + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.0", + "parseurl": "~1.3.2", + "utils-merge": "1.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "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 + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "dev": true + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "requires": { + "mimic-response": "^2.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "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==" + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + }, + "dev-ip": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dev-ip/-/dev-ip-1.0.1.tgz", + "integrity": "sha1-p2o+0YVb56ASu4rBbLgPPADcKPA=", + "dev": true + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "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, + "requires": { + "path-type": "^4.0.0" + }, + "dependencies": { + "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 + } + } + }, + "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, + "requires": { + "lodash": "^4.17.10" + } + }, + "eazy-logger": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-3.0.2.tgz", + "integrity": "sha1-oyWqXlPROiIliJsqxBE7K5Y29Pw=", + "dev": true, + "requires": { + "tfunk": "^3.0.1" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "requires": { + "once": "^1.4.0" + } + }, + "engine.io": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz", + "integrity": "sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.0", + "ws": "~3.3.1" + }, + "dependencies": { + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + } + } + }, + "engine.io-client": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.3.2.tgz", + "integrity": "sha512-y0CPINnhMvPuwtqXfsGuWE8BB66+B6wTtCofQDRecMQPYX3MYUZXFNKDhdrSe3EVjgOu4V3rxdeqN/Tr91IgbQ==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.1", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~6.1.0", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + } + }, + "engine.io-parser": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", + "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", + "dev": true, + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, + "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, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.14.2.tgz", + "integrity": "sha512-DgoQmbpFNOofkjJtKwr87Ma5EW4Dc8fWhD0R+ndq7Oc456ivUfGOOP6oAZTTKl5/CcNMP+EN+e3/iUzgE0veZg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.0", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-inspect": "^1.6.0", + "object-keys": "^1.1.1", + "string.prototype.trimleft": "^2.0.0", + "string.prototype.trimright": "^2.0.0" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "estree-walker": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "eventemitter3": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz", + "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "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==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "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, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "fast-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.0.4.tgz", + "integrity": "sha512-wkIbV6qg37xTJwqSsdnIphL1e+LaGz4AIQqr00mIubMaEhv1/HEmJ0uuCGZRNRUkZZmOB5mJKO0ZUTVq+SxMQg==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.1", + "@nodelib/fs.walk": "^1.2.1", + "glob-parent": "^5.0.0", + "is-glob": "^4.0.1", + "merge2": "^1.2.3", + "micromatch": "^4.0.2" + }, + "dependencies": { + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "glob-parent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", + "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "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 + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "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, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "fastq": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz", + "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==", + "dev": true, + "requires": { + "reusify": "^1.0.0" + } + }, + "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==" + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "finalhandler": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "dev": true, + "requires": { + "debug": "=3.1.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "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==" + }, + "fs-extra": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", + "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^3.0.0", + "universalify": "^0.1.0" + } + }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "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" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" + }, + "gl": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/gl/-/gl-4.4.0.tgz", + "integrity": "sha512-4FIq5tqiltTsadrLh6DGY4R9+aQwj25OM2WlXEv81N6YN1q1C0qR7ct0SKp1uUJdnBqbKhUJP3zQ1td40AVeJg==", + "requires": { + "bindings": "^1.5.0", + "bit-twiddle": "^1.0.2", + "glsl-tokenizer": "^2.0.2", + "nan": "^2.14.0", + "node-gyp": "^4.0.0", + "prebuild-install": "^5.1.0" + } + }, + "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==" + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "globby": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", + "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, + "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==", + "requires": { + "through2": "^0.6.3" + } + }, + "gpu-mock.js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/gpu-mock.js/-/gpu-mock.js-1.1.0.tgz", + "integrity": "sha512-kDMvQ04qIqbrpGyYCShx8NhZYMiolb1XUkjnJn92/jcMsxjcPF7KFfDMJEg0VUwxVJzD4djzJNWbmJCs00YEVg==" + }, + "graceful-fs": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", + "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==" + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "dev": true, + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hosted-git-info": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", + "dev": true + }, + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + } + } + }, + "http-proxy": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.15.2.tgz", + "integrity": "sha1-ZC/cr/5S00SNK9o7AHnpQJBk2jE=", + "dev": true, + "requires": { + "eventemitter3": "1.x.x", + "requires-port": "1.x.x" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "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, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.2.tgz", + "integrity": "sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ==", + "dev": true + }, + "immutable": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", + "integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM=", + "dev": true + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "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 + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "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, + "requires": { + "lodash.isfinite": "^3.3.2" + } + }, + "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 + }, + "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, + "requires": { + "is-path-inside": "^3.0.1" + } + }, + "is-path-inside": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.1.tgz", + "integrity": "sha512-CKstxrctq1kUesU6WhtZDbYKzzYBuRH0UYInAVrkc/EYdB9ltbfE0gOoayG9nhohG6447sOOVGhHqsdmBvkbNg==", + "dev": true + }, + "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, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-reference": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.3.tgz", + "integrity": "sha512-W1iHHv/oyBb2pPxkBxtaewxa1BC58Pn5J0hogyCdefwUIvb6R+TGbAcIa4qPNYLqLhb3EnOgUf2MQkkF76BcKw==", + "dev": true, + "requires": { + "@types/estree": "0.0.39" + } + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "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 + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "jest-worker": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", + "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^6.1.0" + }, + "dependencies": { + "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 + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "js-cleanup": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/js-cleanup/-/js-cleanup-1.0.1.tgz", + "integrity": "sha512-wyHeWKqbcQV78/tiMJ6pgJrkG7p2u3b2xX9IJFvvurpJL9/++89dHfkUebhWvSMS84LG0uQ7BnG5GGyAzY21Ag==", + "dev": true, + "requires": { + "magic-string": "^0.25.1", + "perf-regexes": "^1.0.1", + "skip-regex": "^1.0.2" + } + }, + "js-reporters": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/js-reporters/-/js-reporters-1.2.1.tgz", + "integrity": "sha1-+IxgjjJKM3OpW8xFrTBeXJecRZs=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "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 + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "just-extend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", + "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, + "limiter": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.4.tgz", + "integrity": "sha512-XCpr5bElgDI65vVgstP8TWjv6/QKWm9GU5UG0Pr5sLQ3QLo8NVKsioe+Jed5/3vFOe3IQuqE7DKwTvKQkjTHvg==", + "dev": true + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "localtunnel": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-1.9.2.tgz", + "integrity": "sha512-NEKF7bDJE9U3xzJu3kbayF0WTvng6Pww7tzqNb/XtEARYwqw7CKEX7BvOMg98FtE9es2CRizl61gkV3hS8dqYg==", + "dev": true, + "requires": { + "axios": "0.19.0", + "debug": "4.1.1", + "openurl": "1.1.1", + "yargs": "6.6.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "yargs": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", + "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", + "dev": true, + "requires": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^4.2.0" + } + } + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "lodash.isfinite": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz", + "integrity": "sha1-+4m2WpqAKBgz8LdHizpRBPiY67M=", + "dev": true + }, + "lolex": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-4.2.0.tgz", + "integrity": "sha512-gKO5uExCXvSm6zbF562EvM+rd1kQDnB9AZBbiQVzf1ZmdDpxUSvpnAaVOP83N/31mRK8Ml8/VE8DMvsAZQ+7wg==", + "dev": true + }, + "magic-string": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.3.tgz", + "integrity": "sha512-6QK0OpF/phMz0Q2AxILkX2mFhi7m+WMwTRg0LQKq/WBB0cDP4rYH3Wp4/d3OTXlrPLVJT/RFqj8tFeAR4nk8AA==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.4" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", + "dev": true + }, + "merge2": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz", + "integrity": "sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", + "dev": true + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "requires": { + "mime-db": "1.40.0" + } + }, + "mimic-response": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.0.0.tgz", + "integrity": "sha512-8ilDoEapqA4uQ3TwS0jakGONKXVJqpy+RpM+3b7pLdOjghCrEiGp9SRkFbUHAmZW9vdnrENWHjaweIoTIJExSQ==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "minipass": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.6.5.tgz", + "integrity": "sha512-ewSKOPFH9blOLXx0YSE+mbrNMBFPS+11a2b03QZ+P4LVrUHW/GAlqeYC7DBknDyMWkHzrzTpDhUvy7MUxqyrPA==", + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.2.tgz", + "integrity": "sha512-hR3At21uSrsjjDTWrbu0IMLTpnkpv8IIMFDFaoz43Tmu4LkmAXfH44vNNzpTnf+OAQQCHrb91y/wc2J4x5XgSQ==", + "requires": { + "minipass": "^2.2.1" + } + }, + "mitt": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.1.3.tgz", + "integrity": "sha512-mUDCnVNsAi+eD6qA0HkRkwYczbLHJ49z17BGe2PYRhZL4wpZUFZGJHU7/5tmvohoma+Hdn0Vh/oJTiPEmgSruA==", + "dev": true + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "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, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "napi-build-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.1.tgz", + "integrity": "sha512-boQj1WFgQH3v4clhu3mTNfP+vOBxorDlE8EKiMjUlLG3C4qAESnn9AxIOkFgTR2c9LtzNjPrjS60cT27ZKBhaA==" + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "nise": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.2.tgz", + "integrity": "sha512-/6RhOUlicRCbE9s+94qCUsyE+pKlVJ5AhIv+jEE7ESKwnbXqulKZ1FYU+XAtHHWE9TinYvAxDUJAb912PwPoWA==", + "dev": true, + "requires": { + "@sinonjs/formatio": "^3.2.1", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "lolex": "^4.1.0", + "path-to-regexp": "^1.7.0" + } + }, + "node-abi": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.11.0.tgz", + "integrity": "sha512-kuy/aEg75u40v378WRllQ4ZexaXJiCvB68D2scDXclp/I4cRq6togpbOoKhmN07tns9Zldu51NNERo0wehfX9g==", + "requires": { + "semver": "^5.4.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "node-gyp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-4.0.0.tgz", + "integrity": "sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA==", + "requires": { + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "^2.87.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^4.4.8", + "which": "1" + } + }, + "node-watch": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.6.0.tgz", + "integrity": "sha512-XAgTL05z75ptd7JSVejH1a2Dm1zmXYhuDr9l230Qk6Z7/7GPcnAs/UyJJ4ggsXSvWil8iOzwQLW0zuGUvHpG8g==", + "dev": true + }, + "noop-logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", + "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "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 + }, + "npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "dev": true + }, + "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 + }, + "object-path": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.9.2.tgz", + "integrity": "sha1-D9mnT8X60a45aLWGvaXGMr1sBaU=", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "openurl": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/openurl/-/openurl-1.1.1.tgz", + "integrity": "sha1-OHW0sO96UsFW8NtB1GCduw+Us4c=", + "dev": true + }, + "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, + "requires": { + "is-wsl": "^1.1.0" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "^1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "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 + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "perf-regexes": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/perf-regexes/-/perf-regexes-1.0.1.tgz", + "integrity": "sha512-L7MXxUDtqr4PUaLFCDCXBfGV/6KLIuSEccizDI7JxT+c9x1G1v04BQ4+4oag84SHaCdrBgQAIs/Cqn+flwFPng==", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "picomatch": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.7.tgz", + "integrity": "sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==", + "dev": true + }, + "pidtree": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.0.tgz", + "integrity": "sha512-9CT4NFlDcosssyg8KVFltgokyKZIFjoBxw8CTGy+5F38Y1eQWrt8tRayiUOXE+zVKQnYu5BR8JjCtvK3BcnBhg==", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "platform": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.5.tgz", + "integrity": "sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q==", + "dev": true + }, + "portscanner": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.1.1.tgz", + "integrity": "sha1-6rtAnk3iSVD1oqUW01rnaTQ/u5Y=", + "dev": true, + "requires": { + "async": "1.5.2", + "is-number-like": "^1.0.3" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "prebuild-install": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.2.tgz", + "integrity": "sha512-INDfXzTPnhT+WYQemqnAXlP7SvfiFMopMozSgXCZ+RDLb279gKfIuLk4o7PgEawLp3WrMgIYGBpkxpraROHsSA==", + "requires": { + "detect-libc": "^1.0.3", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "napi-build-utils": "^1.0.1", + "node-abi": "^2.7.0", + "noop-logger": "^0.1.1", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^3.0.3", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0", + "which-pm-runs": "^1.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "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==" + }, + "psl": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", + "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==" + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "qunit": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.9.2.tgz", + "integrity": "sha512-wTOYHnioWHcx5wa85Wl15IE7D6zTZe2CQlsodS14yj7s2FZ3MviRnQluspBZsueIDEO7doiuzKlv05yfky1R7w==", + "dev": true, + "requires": { + "commander": "2.12.2", + "js-reporters": "1.2.1", + "minimatch": "3.0.4", + "node-watch": "0.6.0", + "resolve": "1.9.0" + }, + "dependencies": { + "commander": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz", + "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==", + "dev": true + }, + "resolve": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz", + "integrity": "sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "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 + }, + "raw-body": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", + "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.3", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, + "read-dir-deep": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-dir-deep/-/read-dir-deep-7.0.1.tgz", + "integrity": "sha512-w99fvgqJm3cJ5Vb7b3oGKRDnm/m11q7w5LQ9uBCXe+repIEf1rFtkXLlPAxNrSwlp4skyPyvKd4DNNiIuc0geg==", + "dev": true, + "requires": { + "globby": "^10.0.1", + "is-path-cwd": "^2.2.0", + "is-path-in-cwd": "^3.0.0", + "path-sort2": "^1.0.0", + "slash": "^3.0.0" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "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" + } + }, + "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, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", + "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "resp-modifier": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/resp-modifier/-/resp-modifier-6.0.2.tgz", + "integrity": "sha1-sSTeXE+6/LpUH0j/pzlw9KpFa08=", + "dev": true, + "requires": { + "debug": "^2.2.0", + "minimatch": "^3.0.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + }, + "rollup": { + "version": "1.21.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.21.4.tgz", + "integrity": "sha512-Pl512XVCmVzgcBz5h/3Li4oTaoDcmpuFZ+kdhS/wLreALz//WuDAMfomD3QEYl84NkDu6Z6wV9twlcREb4qQsw==", + "dev": true, + "requires": { + "@types/estree": "0.0.39", + "@types/node": "^12.7.5", + "acorn": "^7.0.0" + }, + "dependencies": { + "@types/node": { + "version": "12.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.5.tgz", + "integrity": "sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w==", + "dev": true + }, + "acorn": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", + "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==", + "dev": true + } + } + }, + "rollup-plugin-cleanup": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-cleanup/-/rollup-plugin-cleanup-3.1.1.tgz", + "integrity": "sha512-wMS9JQm4ShvlMqno1pOfqvh0yYgNLO2ZgmzDsVvKuDt4XCn+9DcMoUwRQ5t9p9b113dR5FhPFFUHnvvQ/yuEtA==", + "dev": true, + "requires": { + "js-cleanup": "^1.0.1", + "rollup-pluginutils": "^2.3.3" + } + }, + "rollup-plugin-commonjs": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz", + "integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==", + "dev": true, + "requires": { + "estree-walker": "^0.6.1", + "is-reference": "^1.1.2", + "magic-string": "^0.25.2", + "resolve": "^1.11.0", + "rollup-pluginutils": "^2.8.1" + } + }, + "rollup-plugin-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-json/-/rollup-plugin-json-4.0.0.tgz", + "integrity": "sha512-hgb8N7Cgfw5SZAkb3jf0QXii6QX/FOkiIq2M7BAQIEydjHvTyxXHQiIzZaTFgx1GK0cRCHOCBHIyEkkLdWKxow==", + "dev": true, + "requires": { + "rollup-pluginutils": "^2.5.0" + } + }, + "rollup-plugin-node-resolve": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz", + "integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==", + "dev": true, + "requires": { + "@types/resolve": "0.0.8", + "builtin-modules": "^3.1.0", + "is-module": "^1.0.0", + "resolve": "^1.11.1", + "rollup-pluginutils": "^2.8.1" + } + }, + "rollup-plugin-terser": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-5.1.2.tgz", + "integrity": "sha512-sWKBCOS+vUkRtHtEiJPAf+WnBqk/C402fBD9AVHxSIXMqjsY7MnYWKYEUqGixtr0c8+1DjzUEPlNgOYQPVrS1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "jest-worker": "^24.6.0", + "rollup-pluginutils": "^2.8.1", + "serialize-javascript": "^1.7.0", + "terser": "^4.1.0" + }, + "dependencies": { + "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 + }, + "terser": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.3.1.tgz", + "integrity": "sha512-pnzH6dnFEsR2aa2SJaKb1uSCl3QmIsJ8dEkj0Fky+2AwMMcC9doMqLOQIH6wVTEKaVfKVvLSk5qxPBEZT9mywg==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + } + } + } + }, + "rollup-pluginutils": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.1.tgz", + "integrity": "sha512-J5oAoysWar6GuZo0s+3bZ6sVZAC0pfqKz68De7ZgDi5z63jOVZn1uJL/+z1jeKHNbGII8kAyHF5q8LnxSX5lQg==", + "dev": true, + "requires": { + "estree-walker": "^0.6.1" + } + }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, + "rx": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", + "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", + "dev": true + }, + "rxjs": { + "version": "5.5.12", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", + "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", + "dev": true, + "requires": { + "symbol-observable": "1.0.1" + } + }, + "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==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", + "dev": true + } + } + }, + "serialize-javascript": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz", + "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==", + "dev": true + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + } + } + }, + "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, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.2" + } + }, + "server-destroy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", + "integrity": "sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0=", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shell-quote": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", + "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" + }, + "simple-get": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", + "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "requires": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "sinon": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.4.2.tgz", + "integrity": "sha512-pY5RY99DKelU3pjNxcWo6XqeB1S118GBcVIIdDi6V+h6hevn1izcg2xv1hTHW/sViRXU7sUOxt4wTUJ3gsW2CQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.4.0", + "@sinonjs/formatio": "^3.2.1", + "@sinonjs/samsam": "^3.3.3", + "diff": "^3.5.0", + "lolex": "^4.2.0", + "nise": "^1.5.2", + "supports-color": "^5.5.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "skip-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/skip-regex/-/skip-regex-1.0.2.tgz", + "integrity": "sha512-pEjMUbwJ5Pl/6Vn6FsamXHXItJXSRftcibixDmNCWbWhic0hzHrwkMZo0IZ7fMRH9KxcWDFSkzhccB4285PutA==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "socket.io": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz", + "integrity": "sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==", + "dev": true, + "requires": { + "debug": "~3.1.0", + "engine.io": "~3.2.0", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.1.1", + "socket.io-parser": "~3.2.0" + }, + "dependencies": { + "engine.io-client": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", + "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.1", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~3.3.1", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + }, + "socket.io-client": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz", + "integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==", + "dev": true, + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "engine.io-client": "~3.2.0", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.2.0", + "to-array": "0.1.4" + } + }, + "socket.io-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", + "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + } + }, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + } + } + }, + "socket.io-adapter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", + "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=", + "dev": true + }, + "socket.io-client": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.2.0.tgz", + "integrity": "sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA==", + "dev": true, + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "engine.io-client": "~3.3.1", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + } + }, + "socket.io-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", + "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", + "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "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 + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "sourcemap-codec": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.6.tgz", + "integrity": "sha512-1ZooVLYFxC448piVLBbtOxFcXwnymH9oUF8nRd3CuYDVvkRBxRl6pB4Mtas5a4drtL+E8LDgFkQNcgIw6tc8Hg==", + "dev": true + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true + }, + "stream-throttle": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/stream-throttle/-/stream-throttle-0.1.3.tgz", + "integrity": "sha1-rdV8jXzHOoFjDTHNVdOWHPr7qcM=", + "dev": true, + "requires": { + "commander": "^2.2.0", + "limiter": "^1.0.5" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string.prototype.padend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz", + "integrity": "sha1-86rvfBcZ8XDF6rHDK/eA2W4h8vA=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.4.3", + "function-bind": "^1.0.2" + } + }, + "string.prototype.trimleft": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", + "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", + "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "symbol-observable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", + "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=", + "dev": true + }, + "tar": { + "version": "4.4.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.11.tgz", + "integrity": "sha512-iI4zh3ktLJKaDNZKZc+fUONiQrSn9HkCFzamtb7k8FFmVilHVob7QsLX/VySAW8lAviMzMbFw4QtFb4errwgYA==", + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.6.4", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "tar-fs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz", + "integrity": "sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==", + "requires": { + "chownr": "^1.1.1", + "mkdirp": "^0.5.1", + "pump": "^3.0.0", + "tar-stream": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "tar-stream": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.0.tgz", + "integrity": "sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==", + "requires": { + "bl": "^3.0.0", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "bl": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz", + "integrity": "sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==", + "requires": { + "readable-stream": "^3.0.1" + } + }, + "readable-stream": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" + }, + "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==", + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "tfunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tfunk/-/tfunk-3.1.0.tgz", + "integrity": "sha1-OORBT8ZJd9h6/apy+sttKfgve1s=", + "dev": true, + "requires": { + "chalk": "^1.1.1", + "object-path": "^0.9.0" + } + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "requires": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + } + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "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 + }, + "ua-parser-js": { + "version": "0.7.17", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz", + "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g==", + "dev": true + }, + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "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 + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "window-size": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", + "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", + "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + }, + "yargs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.4.0.tgz", + "integrity": "sha1-gW4ahm1VmMzzTlWW3c4i2S2kkNQ=", + "dev": true, + "requires": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "window-size": "^0.2.0", + "y18n": "^3.2.1", + "yargs-parser": "^4.1.0" + } + }, + "yargs-parser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", + "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", + "dev": true, + "requires": { + "camelcase": "^3.0.0" + } + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", + "dev": true + } + } +} diff --git a/package.json b/package.json index 730f872c..e421fc55 100644 --- a/package.json +++ b/package.json @@ -1,65 +1,60 @@ -{ - "name": "gpu.js", - "version": "2.0.5", - "description": "GPU Accelerated JavaScript", - "engines": { - "node": ">=8.0.0" - }, - "main": "./src/index.js", - "files": [ - "src", - "dist" - ], - "unpkg": "./dist/gpu-browser.min.js", - "jsdelivr": "./dist/gpu-browser.min.js", - "browser": "./dist/gpu-browser.js", - "directories": { - "doc": "doc", - "test": "test" - }, - "dependencies": { - "acorn": "^5.1.1", - "gl": "^4.4.0", - "gl-wiretap": "^0.6.2", - "gpu-mock.js": "^1.1.0" - }, - "devDependencies": { - "benchmark": "^2.1.4", - "browser-sync": "^2.26.7", - "browserify": "^16.2.3", - "gulp": "^4.0.0", - "gulp-concat": "^2.6.0", - "gulp-header": "^1.7.1", - "gulp-jsbeautifier": "^2.1.0", - "gulp-rename": "^1.2.2", - "gulp-replace": "^1.0.0", - "gulp-strip-comments": "^2.4.5", - "gulp-uglify-es": "^1.0.4", - "merge-stream": "^1.0.1", - "qunit": "^2.9.1", - "read-dir-deep": "^7.0.1", - "sinon": "^7.3.2", - "vinyl-buffer": "^1.0.0", - "vinyl-source-stream": "^2.0.0" - }, - "scripts": { - "test": "qunit", - "setup": "npm i -g gulp-cli", - "make": "gulp make" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/gpujs/gpu.js.git" - }, - "keywords": [ - "gpgpu", - "webgl" - ], - "author": "The gpu.js Team", - "license": "MIT", - "bugs": { - "url": "https://github.com/gpujs/gpu.js/issues" - }, - "homepage": "http://gpu.rocks/", - "typings": "./src/index.d.ts" -} +{ + "name": "gpu.js", + "version": "2.0.5", + "description": "GPU Accelerated JavaScript", + "author": "The gpu.js Team", + "license": "MIT", + "homepage": "https://gpu.rocks/", + "main": "./dist/gpu.js", + "browser": "./dist/gpu-browser.min.js", + "unpkg": "./dist/gpu-browser.min.js", + "jsdelivr": "./dist/gpu-browser.min.js", + "module": "./dist/gpu.mjs", + "typings": "./src/index.d.ts", + "files": [ + "dist" + ], + "engines": { + "node": ">=8.0.0" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/gpujs/gpu.js.git" + }, + "keywords": [ + "gpgpu", + "webgl" + ], + "bugs": { + "url": "https://github.com/gpujs/gpu.js/issues" + }, + "scripts": { + "build-tests": "node build-tests", + "build": "rollup -c", + "pretest": "npm run build && npm run build-tests", + "prewatch": "npm run build-tests", + "test": "qunit", + "watch": "rollup -c -w" + }, + "dependencies": { + "acorn": "^5.1.1", + "gl": "^4.4.0", + "gl-wiretap": "^0.6.2", + "gpu-mock.js": "^1.1.0" + }, + "devDependencies": { + "benchmark": "^2.1.4", + "browser-sync": "^2.26.7", + "chai": "^4.2.0", + "npm-run-all": "^4.1.5", + "qunit": "^2.9.1", + "read-dir-deep": "^7.0.1", + "rollup": "^1.21.4", + "rollup-plugin-cleanup": "^3.1.1", + "rollup-plugin-commonjs": "^10.1.0", + "rollup-plugin-json": "^4.0.0", + "rollup-plugin-node-resolve": "^5.2.0", + "rollup-plugin-terser": "^5.1.2", + "sinon": "^7.4.2" + } +} diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 00000000..ea33ec50 --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,113 @@ +import BrowserSync from 'browser-sync'; +import cleanup from 'rollup-plugin-cleanup'; +import commonjs from 'rollup-plugin-commonjs'; +import json from 'rollup-plugin-json'; +import pkg from './package.json'; +import resolve from 'rollup-plugin-node-resolve'; +import { terser } from 'rollup-plugin-terser'; + +const production = !process.env.ROLLUP_WATCH; + +const browsersyncOptions = { + server: '.', + open: true, + startPath: './test/all.html', + host: '0.0.0.0', + port: 9005, + tunnel: true +}; + +const bs = BrowserSync.create('rollup'); + +function browsersync(options) { + if (!bs.active) { + bs.init(options || { server: '.' }); + process.on('SIGTERM', () => { + bs.exit(); + process.exit(0); + }); + } + + return { + name: 'browsersync', + generateBundle: function({}, bundle, isWrite) { + if (isWrite) { + bs.io && bs.reload(bundle.dest); + } + } + } +}; + +const terserOptions = { + include: [/^.+\.min\.js$/] +}; + +const banner = `/** + * ${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 + */`; + +const output = (file, format, core = false) => ({ + 'esm': { file, format, banner, sourcemap: true }, + 'cjs': { file, format, banner, sourcemap: true }, + 'iife': { file, format, banner, sourcemap: true, name: 'GPU', globals: core ? { acorn: 'acorn' } : {} } +}[format]); + +const main = { + input: './src/index.js', + output: [ + output('./dist/gpu.js', 'cjs'), + output('./dist/gpu.mjs', 'esm') + ], + external: [ 'gl', 'acorn' ], + plugins: [ + json(), + resolve(), + commonjs(), + cleanup(), + terser(terserOptions), + ] +} + +const browser = { + input: './src/browser.js', + output: [ + output('./dist/gpu-browser.js', 'iife'), + output('./dist/gpu-browser.min.js', 'iife') + ], + plugins: [ + json(), + resolve(), + commonjs(), + production && cleanup(), + production ? terser(terserOptions) : browsersync(browsersyncOptions) + ] +} + +const core = { + input: './src/browser.js', + output: [ + output('./dist/gpu-browser-core.js', 'iife', true), + output('./dist/gpu-browser-core.min.js', 'iife', true) + ], + external: [ 'acorn' ], + plugins: [ + json(), + resolve(), + commonjs(), + cleanup(), + terser(terserOptions) + ] +} + +export default production ? [ main, browser, core ] : browser diff --git a/src/alias.js b/src/alias.js index 4a279099..958431ac 100644 --- a/src/alias.js +++ b/src/alias.js @@ -1,18 +1,13 @@ -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 +import { utils } from './utils'; + +/** + * @param name + * @param source + * @returns {Function} + */ +export function alias(name, source) { + const fnString = source.toString(); + return new Function(`return function ${ name } (${ utils.getArgumentNamesFromString(fnString).join(', ') }) { + ${ utils.getFunctionBodyFromString(fnString) } +}`)(); +} diff --git a/src/backend/cpu/function-node.js b/src/backend/cpu/function-node.js index b3c38d12..bd48ed3f 100644 --- a/src/backend/cpu/function-node.js +++ b/src/backend/cpu/function-node.js @@ -1,649 +1,645 @@ -const { FunctionNode } = require('../function-node'); - -/** - * @desc [INTERNAL] Represents a single function, inside JS - * - *

This handles all the raw state, converted state, etc. Of a single function.

- */ -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) { - if (varDecNode.kind === 'var' && this.warnVarUsage) { - this.varWarn(); - } - retArr.push(`${varDecNode.kind} `); - const { declarations } = varDecNode; - for (let i = 0; i < declarations.length; i++) { - if (i > 0) { - retArr.push(','); - } - this.astGeneric(declarations[i], 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') { - 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; - 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 '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 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) - } - retArr.push('])'); - - return retArr; - } - - astDebuggerStatement(arrNode, retArr) { - retArr.push('debugger;'); - return retArr; - } -} - -module.exports = { - CPUFunctionNode -}; \ No newline at end of file +import { FunctionNode } from '../function-node'; + +/** + * @desc [INTERNAL] Represents a single function, inside JS + * + *

This handles all the raw state, converted state, etc. Of a single function.

+ */ +export 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 new 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) { + if (varDecNode.kind === 'var' && this.warnVarUsage) { + this.varWarn(); + } + retArr.push(`${varDecNode.kind} `); + const { declarations } = varDecNode; + for (let i = 0; i < declarations.length; i++) { + if (i > 0) { + retArr.push(','); + } + this.astGeneric(declarations[i], 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') { + 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; + 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 '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 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) + } + retArr.push('])'); + + return retArr; + } + + astDebuggerStatement(arrNode, retArr) { + retArr.push('debugger;'); + return retArr; + } +} diff --git a/src/backend/cpu/kernel-string.js b/src/backend/cpu/kernel-string.js index 166e124d..ddc3851c 100644 --- a/src/backend/cpu/kernel-string.js +++ b/src/backend/cpu/kernel-string.js @@ -1,179 +1,175 @@ -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)': - 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)': - 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 +import { utils } from '../../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)': + results.push(`${name}:new ${constant.constructor.name}(${JSON.stringify(Array.from(constant))})`); + break; + } + } + return `{ ${ results.join() } }`; +} + +export 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)': + 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; +}`; +} diff --git a/src/backend/cpu/kernel.js b/src/backend/cpu/kernel.js index 07242dde..b0c853c5 100644 --- a/src/backend/cpu/kernel.js +++ b/src/backend/cpu/kernel.js @@ -1,536 +1,532 @@ -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() { - return null; - } - - static combineKernels(combinedKernel) { - return combinedKernel; - } - - constructor(source, settings) { - super(source, settings); - this.mergeSettings(source.settings || settings); - - this._imageData = null; - this._colorData = null; - this._kernelString = null; - 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() { - 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); - } - } - - 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._processConstants() } - return (${ this.argumentNames.map(argumentName => 'user_' + argumentName).join(', ') }) => { - ${ 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 'HTMLImage': - 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(''); - } - - _processArguments() { - const result = []; - for (let i = 0; i < this.argumentTypes.length; i++) { - const variableName = `user_${this.argumentNames[i]}`; - switch (this.argumentTypes[i]) { - case 'HTMLImage': - 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; - ctx.drawImage(media, 0, 0, width, height); - const 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; - } - - 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; - } - - _resultKernelBody(kernelString) { - switch (this.output.length) { - case 1: - return this._resultKernel1DLoop(kernelString) + this._kernelOutput(); - case 2: - return this._resultKernel2DLoop(kernelString) + this._kernelOutput(); - case 3: - return this._resultKernel3DLoop(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 }`); - } - } - - _resultKernel1DLoop(kernelString) { - const { - output - } = this; - 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 } - }`; - } - - _resultKernel2DLoop(kernelString) { - const { - output - } = this; - 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 } - } - }`; - } - - _graphicalKernel2DLoop(kernelString) { - const { - output - } = this; - const constructorString = this._getKernelResultTypeConstructorString(); - return ` const outputX = _this.output[0]; - const outputY = _this.output[1]; - ${ 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; - ${ 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 } - } - }`; - } - - _resultKernel3DLoop(kernelString) { - const { - output - } = this; - 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 } - } - } - }`; - } - - _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); - } - } -} - -module.exports = { - CPUKernel -}; \ No newline at end of file +import { Kernel } from '../kernel'; +import { FunctionBuilder } from '../function-builder'; +import { CPUFunctionNode } from './function-node'; +import { utils } from '../../utils'; +import { cpuKernelString } from './kernel-string'; + +/** + * @desc Kernel Implementation for CPU. + *

Instantiates properties to the CPU Kernel.

+ */ +export 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() { + return null; + } + + static combineKernels(combinedKernel) { + return combinedKernel; + } + + constructor(source, settings) { + super(source, settings); + this.mergeSettings(source.settings || settings); + + this._imageData = null; + this._colorData = null; + this._kernelString = null; + 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() { + 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); + } + } + + 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._processConstants() } + return (${ this.argumentNames.map(argumentName => 'user_' + argumentName).join(', ') }) => { + ${ 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 'HTMLImage': + 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(''); + } + + _processArguments() { + const result = []; + for (let i = 0; i < this.argumentTypes.length; i++) { + const variableName = `user_${this.argumentNames[i]}`; + switch (this.argumentTypes[i]) { + case 'HTMLImage': + 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; + ctx.drawImage(media, 0, 0, width, height); + const 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; + } + + 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; + } + + _resultKernelBody(kernelString) { + switch (this.output.length) { + case 1: + return this._resultKernel1DLoop(kernelString) + this._kernelOutput(); + case 2: + return this._resultKernel2DLoop(kernelString) + this._kernelOutput(); + case 3: + return this._resultKernel3DLoop(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 }`); + } + } + + _resultKernel1DLoop(kernelString) { + const { + output + } = this; + 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 } + }`; + } + + _resultKernel2DLoop(kernelString) { + const { + output + } = this; + 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 } + } + }`; + } + + _graphicalKernel2DLoop(kernelString) { + const { + output + } = this; + const constructorString = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const outputY = _this.output[1]; + ${ 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; + ${ 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 } + } + }`; + } + + _resultKernel3DLoop(kernelString) { + const { + output + } = this; + 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 } + } + } + }`; + } + + _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); + } + } +} diff --git a/src/backend/function-builder.js b/src/backend/function-builder.js index 89bb3c07..610e7705 100644 --- a/src/backend/function-builder.js +++ b/src/backend/function-builder.js @@ -1,621 +1,664 @@ -/** - * @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, - warnVarUsage, - } = 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, returnType) => { - const argumentNames = []; - for (let i = 0; i < ast.params.length; i++) { - argumentNames.push(ast.params[i].name); - } - const nestedFunction = new FunctionNode(null, Object.assign({}, nodeOptions, { - returnType: null, - ast, - name: ast.id.name, - argumentNames, - lookupReturnType, - lookupFunctionArgumentTypes, - lookupFunctionArgumentName, - lookupFunctionArgumentBitRatio, - needsArgumentType, - assignArgumentType, - triggerImplyArgumentType, - triggerImplyArgumentBitRatio, - onFunctionCall, - warnVarUsage, - })); - 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.argumentChain = []; - 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) { - if (retList.indexOf(functionName) === -1) { - retList.push(functionName); - } - 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 +/** + * @desc This handles all the raw state, converted state, etc. of a single function. + * [INTERNAL] A collection of functionNodes. + * @class + */ +export 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, + warnVarUsage, + } = 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 triggerTrackArgumentSynonym = (functionName, argumentName, calleeFunctionName, argumentIndex) => { + functionBuilder.trackArgumentSynonym(functionName, argumentName, calleeFunctionName, argumentIndex); + }; + + const lookupArgumentSynonym = (originFunctionName, functionName, argumentName) => { + return functionBuilder.lookupArgumentSynonym(originFunctionName, functionName, argumentName); + }; + + const onFunctionCall = (functionName, calleeFunctionName, args) => { + functionBuilder.trackFunctionCall(functionName, calleeFunctionName, args); + }; + + const onNestedFunction = (ast, returnType) => { + const argumentNames = []; + for (let i = 0; i < ast.params.length; i++) { + argumentNames.push(ast.params[i].name); + } + const nestedFunction = new FunctionNode(null, Object.assign({}, nodeOptions, { + returnType: null, + ast, + name: ast.id.name, + argumentNames, + lookupReturnType, + lookupFunctionArgumentTypes, + lookupFunctionArgumentName, + lookupFunctionArgumentBitRatio, + needsArgumentType, + assignArgumentType, + triggerImplyArgumentType, + triggerTrackArgumentSynonym, + lookupArgumentSynonym, + onFunctionCall, + warnVarUsage, + })); + nestedFunction.traceFunctionAST(ast); + functionBuilder.addFunctionNode(nestedFunction); + }; + + const nodeOptions = Object.assign({ + isRootKernel: false, + onNestedFunction, + lookupReturnType, + lookupFunctionArgumentTypes, + lookupFunctionArgumentName, + lookupFunctionArgumentBitRatio, + needsArgumentType, + assignArgumentType, + triggerImplyArgumentType, + triggerTrackArgumentSynonym, + lookupArgumentSynonym, + 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, + triggerTrackArgumentSynonym, + lookupArgumentSynonym, + onFunctionCall, + })); + } + + 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.argumentChain = []; + 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) { + if (retList.indexOf(functionName) === -1) { + retList.push(functionName); + } + 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; + } + } + + // function not found, maybe native? + return null; + + /** + * first iteration + * kernel.outputs = Array + * kernel.targets = Array + * kernel.returns = null + * kernel.calls.calcErrorOutput = [kernel.output, kernel.targets] + * kernel.calls.calcDeltas = [calcErrorOutput.returns, kernel.output] + * calcErrorOutput.output = null + * calcErrorOutput.targets = null + * calcErrorOutput.returns = null + * calcDeltasSigmoid.error = null + * calcDeltasSigmoid.output = Number + * calcDeltasSigmoid.returns = null + * + * resolvable are: + * calcErrorOutput.output + * calcErrorOutput.targets + * calcErrorOutput.returns + * + * second iteration + * kernel.outputs = Array + * kernel.targets = Array + * kernel.returns = null + * kernel.calls.calcErrorOutput = [kernel.output, kernel.targets] + * kernel.calls.calcDeltas = [calcErrorOutput.returns, kernel.output] + * calcErrorOutput.output = Number + * calcErrorOutput.targets = Array + * calcErrorOutput.returns = Number + * calcDeltasSigmoid.error = null + * calcDeltasSigmoid.output = Number + * calcDeltasSigmoid.returns = null + * + * resolvable are: + * calcDeltasSigmoid.error + * calcDeltasSigmoid.returns + * kernel.returns + * + * third iteration + * kernel.outputs = Array + * kernel.targets = Array + * kernel.returns = Number + * kernel.calls.calcErrorOutput = [kernel.output, kernel.targets] + * kernel.calls.calcDeltas = [calcErrorOutput.returns, kernel.output] + * calcErrorOutput.output = Number + * calcErrorOutput.targets = Array + * calcErrorOutput.returns = Number + * calcDeltasSigmoid.error = Number + * calcDeltasSigmoid.output = Number + * calcDeltasSigmoid.returns = Number + * + * + */ + } + + _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]; + } else { + throw new Error('argument bit ratio not found'); + } + } else { + const node = this._getFunction(functionName); + const argumentSynonym = node.argumentSynonym[node.synonymIndex]; + if (!argumentSynonym) { + throw new Error('argument synonym not found'); + } + return this.lookupFunctionArgumentBitRatio(argumentSynonym.functionName, argumentSynonym.argumentName); + } + } + + 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; + } + } + + trackArgumentSynonym(functionName, argumentName, calleeFunctionName, argumentIndex) { + if (!this._isFunction(calleeFunctionName)) return; + const node = this._getFunction(calleeFunctionName); + if (!node.argumentSynonym) { + node.argumentSynonym = {}; + } + const calleeArgumentName = node.argumentNames[argumentIndex]; + if (!node.argumentSynonym[calleeArgumentName]) { + node.argumentSynonym[calleeArgumentName] = {}; + } + node.synonymIndex++; + node.argumentSynonym[node.synonymIndex] = { + functionName, + argumentName, + calleeArgumentName, + calleeFunctionName, + }; + } + + lookupArgumentSynonym(originFunctionName, functionName, argumentName) { + if (originFunctionName === functionName) return argumentName; + if (!this._isFunction(functionName)) return null; + const node = this._getFunction(functionName); + const argumentSynonym = node.argumentSynonym[node.synonymUseIndex]; + if (!argumentSynonym) return null; + if (argumentSynonym.calleeArgumentName !== argumentName) return null; + node.synonymUseIndex++; + if (originFunctionName !== functionName) { + return this.lookupArgumentSynonym(originFunctionName, argumentSynonym.functionName, argumentSynonym.argumentName); + } + return argumentSynonym.argumentName; + } + + 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; + } +} diff --git a/src/backend/function-node.js b/src/backend/function-node.js index 8ffd1da9..14b39132 100644 --- a/src/backend/function-node.js +++ b/src/backend/function-node.js @@ -1,1509 +1,1510 @@ -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.declarations = 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; - this.warnVarUsage = true; - - 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[0] === '_') { - 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.declarations = []; - this.functions = functions; - for (let i = 0; i < declarations.length; i++) { - const declaration = declarations[i]; - const { ast, context, name, origin, forceInteger, assignable } = declaration; - const { init } = ast; - const dependencies = this.getDependencies(init); - let valueType = null; - - if (forceInteger) { - 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; - } - } - } - this.declarations.push({ - valueType, - dependencies, - isSafe: this.isSafeDependencies(dependencies), - ast, - name, - context, - origin, - assignable, - }); - } - - for (let i = 0; i < functions.length; i++) { - this.onNestedFunction(functions[i]); - } - } - - getDeclaration(ast) { - for (let i = 0; i < this.identifiers.length; i++) { - const identifier = this.identifiers[i]; - if (ast === identifier.ast && identifier.context.hasOwnProperty(ast.name)) { - for (let j = 0; j < this.declarations.length; j++) { - const declaration = this.declarations[j]; - if (declaration.name === ast.name && declaration.context[ast.name] === identifier.context[ast.name]) { - return 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': - return `Array(${ ast.elements.length })`; - case 'Literal': - const literalKey = `${ast.start},${ast.end}`; - 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); - } - 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 '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') { - const type = this.getVariableType(ast); - if (!type) { - throw this.astErrorOutput(`Unable to find identifier valueType`, ast); - } - return type; - } - } - 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.getVariableType(ast.object)); - case 'value[][]': - return this.getLookupType(this.getVariableType(ast.object.object)); - case 'value[][][]': - return this.getLookupType(this.getVariableType(ast.object.object.object)); - case 'value[][][][]': - return this.getLookupType(this.getVariableType(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()[]': - return this.getLookupType(this.getType(ast.object)); - case 'fn()[][]': - return this.getLookupType(this.getType(ast.object)); - case 'fn()[][][]': - return this.getLookupType(this.getType(ast.object)); - case 'value.value': - if (this.isAstMathVariable(ast)) { - return 'Number'; - } - switch (ast.property.name) { - case 'r': - return this.getLookupType(this.getVariableType(ast.object)); - case 'g': - return this.getLookupType(this.getVariableType(ast.object)); - case 'b': - return this.getLookupType(this.getVariableType(ast.object)); - case 'a': - return this.getLookupType(this.getVariableType(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); - default: - throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast); - } - } - - 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', - 'asin', - 'atan', - 'atan2', - 'ceil', - 'cos', - 'exp', - 'floor', - 'log', - 'log2', - 'max', - 'min', - 'pow', - 'random', - 'round', - 'sign', - 'sin', - 'sqrt', - 'tan', - ]; - 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': - 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; - } - default: - throw this.astErrorOutput(`Unhandled type ${ ast.type } in getDependencies`, ast); - } - return dependencies; - } - - getVariableSignature(ast) { - 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('.value'); - } else if ( - ast.property.name === 'constants' || - ast.property.name === 'thread' || - ast.property.name === 'output' - ) { - signature.unshift('.' + ast.property.name); - } else { - signature.unshift('.value'); - } - } else if (ast.name) { - signature.unshift('value'); - } else if (ast.callee && ast.callee.name) { - signature.unshift('fn()'); - } else if (ast.elements) { - signature.unshift('[]'); - } else { - signature.unshift('unknown'); - } - ast = ast.object; - } - - const signatureString = signature.join(''); - 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[`${ast.start},${ast.end}`] = '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 Declaration* - * @param {Object} varDecNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astVariableDeclaration(varDecNode, retArr) { - const declarations = varDecNode.declarations; - if (!declarations || !declarations[0] || !declarations[0].init) { - throw this.astErrorOutput('Unexpected expression', varDecNode); - } - const result = []; - const firstDeclaration = declarations[0]; - const init = firstDeclaration.init; - let type = this.isState('in-for-loop-init') ? 'Integer' : this.getType(init); - if (type === 'LiteralInteger') { - // We had the choice to go either float or int, choosing float - type = 'Number'; - } - const markupType = typeMap[type]; - if (!markupType) { - throw this.astErrorOutput(`Markup type ${ markupType } not handled`, varDecNode); - } - let dependencies = this.getDependencies(firstDeclaration.init); - throw new Error('remove me'); - this.declarations[firstDeclaration.id.name] = Object.freeze({ - type, - dependencies, - isSafe: dependencies.every(dependency => dependency.isSafe) - }); - const initResult = [`${type} user_${firstDeclaration.id.name}=`]; - this.astGeneric(init, initResult); - result.push(initResult.join('')); - - // first declaration is done, now any added ones setup - for (let i = 1; i < declarations.length; i++) { - const declaration = declarations[i]; - dependencies = this.getDependencies(declaration); - throw new Error('Remove me'); - this.declarations[declaration.id.name] = Object.freeze({ - type, - dependencies, - isSafe: false - }); - this.astGeneric(declaration, result); - } - - retArr.push(retArr, result.join(',')); - retArr.push(';'); - 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) { - for (let i = 0; i < sNode.expressions.length; i++) { - if (i > 0) { - retArr.push(','); - } - this.astGeneric(sNode.expressions, retArr); - } - 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 '[][]': - 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]; - } - - varWarn() { - console.warn('var declarations are deprecated, weird things happen when falling back to CPU because var scope differs in javascript than in most languages. Use const or let'); - } -} - -const typeLookupMap = { - 'Number': 'Number', - 'Float': 'Float', - 'Integer': 'Integer', - 'Array': 'Number', - 'Array(2)': 'Number', - 'Array(3)': 'Number', - 'Array(4)': 'Number', - 'Array2D': 'Number', - 'Array3D': 'Number', - 'Input': 'Number', - 'HTMLImage': '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 +import { parse } from 'acorn'; +import { FunctionTracer } from './function-tracer'; +import { + getArgumentNamesFromString, + getAstString, + getFunctionNameFromString, + isFunctionString, +} from '../common'; + +/** + * + * @desc Represents a single function, inside JS, webGL, or openGL. + *

This handles all the raw state, converted state, etc. Of a single function.

+ */ +export 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 || getFunctionNameFromString(source)) : null; + this.calledFunctions = []; + this.constants = {}; + this.constantTypes = {}; + this.constantBitRatios = {}; + this.isRootKernel = false; + this.isSubKernel = false; + this.debug = null; + this.declarations = 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' ? 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; + this.warnVarUsage = true; + + 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 && !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[0] === '_') { + 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; + } + + const parser = inParser && inParser.hasOwnProperty('parse') ? inParser.parse : parse + if (inParser === null) { + throw new Error('Missing JS to AST parser'); + } + + const ast = Object.freeze(parser(`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.declarations = []; + this.functions = functions; + for (let i = 0; i < declarations.length; i++) { + const declaration = declarations[i]; + const { ast, context, name, origin, forceInteger, assignable } = declaration; + const { init } = ast; + const dependencies = this.getDependencies(init); + let valueType = null; + + if (forceInteger) { + 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; + } + } + } + this.declarations.push({ + valueType, + dependencies, + isSafe: this.isSafeDependencies(dependencies), + ast, + name, + context, + origin, + assignable, + }); + } + + for (let i = 0; i < functions.length; i++) { + this.onNestedFunction(functions[i]); + } + } + + getDeclaration(ast) { + for (let i = 0; i < this.identifiers.length; i++) { + const identifier = this.identifiers[i]; + if (ast === identifier.ast && identifier.context.hasOwnProperty(ast.name)) { + for (let j = 0; j < this.declarations.length; j++) { + const declaration = this.declarations[j]; + if (declaration.name === ast.name && declaration.context[ast.name] === identifier.context[ast.name]) { + return 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': + return `Array(${ ast.elements.length })`; + case 'Literal': + const literalKey = `${ast.start},${ast.end}`; + 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); + } + 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 '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') { + const type = this.getVariableType(ast); + if (!type) { + throw this.astErrorOutput(`Unable to find identifier valueType`, ast); + } + return type; + } + } + 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.getVariableType(ast.object)); + case 'value[][]': + return this.getLookupType(this.getVariableType(ast.object.object)); + case 'value[][][]': + return this.getLookupType(this.getVariableType(ast.object.object.object)); + case 'value[][][][]': + return this.getLookupType(this.getVariableType(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()[]': + return this.getLookupType(this.getType(ast.object)); + case 'fn()[][]': + return this.getLookupType(this.getType(ast.object)); + case 'fn()[][][]': + return this.getLookupType(this.getType(ast.object)); + case 'value.value': + if (this.isAstMathVariable(ast)) { + return 'Number'; + } + switch (ast.property.name) { + case 'r': + return this.getLookupType(this.getVariableType(ast.object)); + case 'g': + return this.getLookupType(this.getVariableType(ast.object)); + case 'b': + return this.getLookupType(this.getVariableType(ast.object)); + case 'a': + return this.getLookupType(this.getVariableType(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); + default: + throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast); + } + } + + 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', + 'asin', + 'atan', + 'atan2', + 'ceil', + 'cos', + 'exp', + 'floor', + 'log', + 'log2', + 'max', + 'min', + 'pow', + 'random', + 'round', + 'sign', + 'sin', + 'sqrt', + 'tan', + ]; + 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': + 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; + } + default: + throw this.astErrorOutput(`Unhandled type ${ ast.type } in getDependencies`, ast); + } + return dependencies; + } + + getVariableSignature(ast) { + 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('.value'); + } else if ( + ast.property.name === 'constants' || + ast.property.name === 'thread' || + ast.property.name === 'output' + ) { + signature.unshift('.' + ast.property.name); + } else { + signature.unshift('.value'); + } + } else if (ast.name) { + signature.unshift('value'); + } else if (ast.callee && ast.callee.name) { + signature.unshift('fn()'); + } else if (ast.elements) { + signature.unshift('[]'); + } else { + signature.unshift('unknown'); + } + ast = ast.object; + } + + const signatureString = signature.join(''); + 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 = 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[`${ast.start},${ast.end}`] = '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 Declaration* + * @param {Object} varDecNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astVariableDeclaration(varDecNode, retArr) { + const declarations = varDecNode.declarations; + if (!declarations || !declarations[0] || !declarations[0].init) { + throw this.astErrorOutput('Unexpected expression', varDecNode); + } + const result = []; + const firstDeclaration = declarations[0]; + const init = firstDeclaration.init; + let type = this.isState('in-for-loop-init') ? 'Integer' : this.getType(init); + if (type === 'LiteralInteger') { + // We had the choice to go either float or int, choosing float + type = 'Number'; + } + const markupType = typeMap[type]; + if (!markupType) { + throw this.astErrorOutput(`Markup type ${ markupType } not handled`, varDecNode); + } + let dependencies = this.getDependencies(firstDeclaration.init); + throw new Error('remove me'); + this.declarations[firstDeclaration.id.name] = Object.freeze({ + type, + dependencies, + isSafe: dependencies.every(dependency => dependency.isSafe) + }); + const initResult = [`${type} user_${firstDeclaration.id.name}=`]; + this.astGeneric(init, initResult); + result.push(initResult.join('')); + + // first declaration is done, now any added ones setup + for (let i = 1; i < declarations.length; i++) { + const declaration = declarations[i]; + dependencies = this.getDependencies(declaration); + throw new Error('Remove me'); + this.declarations[declaration.id.name] = Object.freeze({ + type, + dependencies, + isSafe: false + }); + this.astGeneric(declaration, result); + } + + retArr.push(retArr, result.join(',')); + retArr.push(';'); + 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) { + for (let i = 0; i < sNode.expressions.length; i++) { + if (i > 0) { + retArr.push(','); + } + this.astGeneric(sNode.expressions, retArr); + } + 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 '[][]': + 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]; + } + + varWarn() { + console.warn('var declarations are deprecated, weird things happen when falling back to CPU because var scope differs in javascript than in most languages. Use const or let'); + } +} + +const typeLookupMap = { + 'Number': 'Number', + 'Float': 'Float', + 'Integer': 'Integer', + 'Array': 'Number', + 'Array(2)': 'Number', + 'Array(3)': 'Number', + 'Array(4)': 'Number', + 'Array2D': 'Number', + 'Array3D': 'Number', + 'Input': 'Number', + 'HTMLImage': '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)', +}; diff --git a/src/backend/function-tracer.js b/src/backend/function-tracer.js index a464a796..38a59358 100644 --- a/src/backend/function-tracer.js +++ b/src/backend/function-tracer.js @@ -1,167 +1,163 @@ -class FunctionTracer { - constructor(ast) { - this.runningContexts = []; - this.contexts = []; - this.functionCalls = []; - this.declarations = []; - this.identifiers = []; - this.functions = []; - this.returnStatements = []; - this.inLoopInit = false; - this.scan(ast); - } - - get currentContext() { - return this.runningContexts.length > 0 ? this.runningContexts[this.runningContexts.length - 1] : null; - } - - newContext(run) { - const newContext = Object.assign({}, this.currentContext); - this.contexts.push(newContext); - this.runningContexts.push(newContext); - run(); - this.runningContexts.pop(); - } - - /** - * 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.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': - case 'UnaryExpression': - this.scan(ast.argument); - break; - case 'VariableDeclaration': - this.scan(ast.declarations); - break; - case 'VariableDeclarator': - const { currentContext } = this; - const declaration = { - ast: ast, - context: currentContext, - name: ast.id.name, - origin: 'declaration', - forceInteger: this.inLoopInit, - assignable: !this.inLoopInit && !currentContext.hasOwnProperty(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': - this.newContext(() => { - this.inLoopInit = true; - this.scan(ast.init); - this.inLoopInit = false; - this.scan(ast.test); - this.scan(ast.update); - this.newContext(() => { - this.scan(ast.body); - }); - }); - break; - case 'DoWhileStatement': - case 'WhileStatement': - this.newContext(() => { - this.scan(ast.body); - this.scan(ast.test); - }); - break; - case 'Identifier': - this.identifiers.push({ - context: this.currentContext, - ast, - }); - break; - case 'ReturnStatement': - this.returnStatements.push(ast); - this.scan(ast.argument); - break; - case 'MemberExpression': - this.scan(ast.object); - this.scan(ast.property); - break; - case 'ExpressionStatement': - this.scan(ast.expression); - 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 +export class FunctionTracer { + constructor(ast) { + this.runningContexts = []; + this.contexts = []; + this.functionCalls = []; + this.declarations = []; + this.identifiers = []; + this.functions = []; + this.returnStatements = []; + this.inLoopInit = false; + this.scan(ast); + } + + get currentContext() { + return this.runningContexts.length > 0 ? this.runningContexts[this.runningContexts.length - 1] : null; + } + + newContext(run) { + const newContext = Object.assign({}, this.currentContext); + this.contexts.push(newContext); + this.runningContexts.push(newContext); + run(); + this.runningContexts.pop(); + } + + /** + * Recursively scans AST for declarations and functions, and add them to their respective context + * @param ast + */ + scan(ast) { + if (Array.isArray(ast)) { + for (let i = 0; i < ast.length; i++) { + this.scan(ast[i]); + } + return; + } + switch (ast.type) { + case 'Program': + 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': + case 'UnaryExpression': + this.scan(ast.argument); + break; + case 'VariableDeclaration': + this.scan(ast.declarations); + break; + case 'VariableDeclarator': + const { currentContext } = this; + const declaration = { + ast: ast, + context: currentContext, + name: ast.id.name, + origin: 'declaration', + forceInteger: this.inLoopInit, + assignable: !this.inLoopInit && !currentContext.hasOwnProperty(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': + this.newContext(() => { + this.inLoopInit = true; + this.scan(ast.init); + this.inLoopInit = false; + this.scan(ast.test); + this.scan(ast.update); + this.newContext(() => { + this.scan(ast.body); + }); + }); + break; + case 'DoWhileStatement': + case 'WhileStatement': + this.newContext(() => { + this.scan(ast.body); + this.scan(ast.test); + }); + break; + case 'Identifier': + this.identifiers.push({ + context: this.currentContext, + ast, + }); + break; + case 'ReturnStatement': + this.returnStatements.push(ast); + this.scan(ast.argument); + break; + case 'MemberExpression': + this.scan(ast.object); + this.scan(ast.property); + break; + case 'ExpressionStatement': + this.scan(ast.expression); + 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': + this.scan(ast.left); + this.scan(ast.right); + break; + case 'Literal': + case 'DebuggerStatement': + case 'EmptyStatement': + case 'BreakStatement': + case 'ContinueStatement': + break; + default: + throw new Error(`unhandled type "${ast.type}"`); + } + } +} diff --git a/src/backend/gl/kernel-string.js b/src/backend/gl/kernel-string.js index db5b7a12..7f21dad6 100644 --- a/src/backend/gl/kernel-string.js +++ b/src/backend/gl/kernel-string.js @@ -1,341 +1,337 @@ -const { glWiretap } = require('gl-wiretap'); -const { utils } = require('../../utils'); - -function toStringWithoutUtils(fn) { - return fn.toString() - .replace('=>', '') - .replace(/^function /, '') - .replace(/utils[.]/g, '/*utils.*/'); -} - -/** - * - * @param {Kernel} Kernel - * @param {KernelVariable[]} args - * @param {Kernel} originKernel - * @param {string} [setupContextString] - * @param {string} [destroyContextString] - * @returns {string} - */ -function glKernelString(Kernel, args, originKernel, setupContextString, destroyContextString) { - 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, - } = originKernel; - const kernel = new Kernel(source, { - canvas, - context, - checkContext: false, - output, - pipeline, - graphical, - loopMaxIterations, - constants, - optimizeFloatMemory, - precision, - fixIntegerDivisionAccuracy, - functions, - nativeFunctions, - subKernels, - immutable, - argumentTypes, - constantTypes, - }); - 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 '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 results = kernel.renderKernels(); - const textureName = context.getContextVariableName(kernel.outputTexture); - result.push(` return { - result: { - texture: ${ textureName }, - type: '${ results.result.type }', - toArray: ${ getToArrayString(results.result, textureName) } - },`); - const { subKernels, subKernelOutputTextures } = kernel; - for (let i = 0; i < subKernels.length; i++) { - const texture = subKernelOutputTextures[i]; - const subKernel = subKernels[i]; - const subKernelResult = results[subKernel.property]; - const subKernelTextureName = context.getContextVariableName(texture); - result.push(` - ${subKernel.property}: { - texture: ${ subKernelTextureName }, - type: '${ subKernelResult.type }', - toArray: ${ getToArrayString(subKernelResult, subKernelTextureName) } - },`); - } - result.push(` };`); - } - 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) { - 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') { - return `${useFunctionKeyword ? 'function ' : ''}${kernelResult[name].toString()}`; - } else { - throw new Error('unhandled fromObject'); - } - }, - thisLookup: (property) => { - if (property === 'texture') { - return textureName; - } - if (kernelResult.hasOwnProperty(property)) { - return JSON.stringify(kernelResult[property]); - } - throw new Error(`unhandled thisLookup ${ property }`); - } - }); - return `() => { - ${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; - 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') 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; - } - return null; - } - - 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 +import { glWiretap } from 'gl-wiretap'; +import { utils } from '../../utils'; + +function toStringWithoutUtils(fn) { + return fn.toString() + .replace('=>', '') + .replace(/^function /, '') + .replace(/utils[.]/g, '/*utils.*/'); +} + +/** + * + * @param {Kernel} Kernel + * @param {KernelVariable[]} args + * @param {Kernel} originKernel + * @param {string} [setupContextString] + * @param {string} [destroyContextString] + * @returns {string} + */ +export function glKernelString(Kernel, args, originKernel, setupContextString, destroyContextString) { + 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, + } = originKernel; + const kernel = new Kernel(source, { + canvas, + context, + checkContext: false, + output, + pipeline, + graphical, + loopMaxIterations, + constants, + optimizeFloatMemory, + precision, + fixIntegerDivisionAccuracy, + functions, + nativeFunctions, + subKernels, + immutable, + argumentTypes, + constantTypes, + }); + 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 '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 results = kernel.renderKernels(); + const textureName = context.getContextVariableName(kernel.outputTexture); + result.push(` return { + result: { + texture: ${ textureName }, + type: '${ results.result.type }', + toArray: ${ getToArrayString(results.result, textureName) } + },`); + const { subKernels, subKernelOutputTextures } = kernel; + for (let i = 0; i < subKernels.length; i++) { + const texture = subKernelOutputTextures[i]; + const subKernel = subKernels[i]; + const subKernelResult = results[subKernel.property]; + const subKernelTextureName = context.getContextVariableName(texture); + result.push(` + ${subKernel.property}: { + texture: ${ subKernelTextureName }, + type: '${ subKernelResult.type }', + toArray: ${ getToArrayString(subKernelResult, subKernelTextureName) } + },`); + } + result.push(` };`); + } + 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) { + 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') { + return `${useFunctionKeyword ? 'function ' : ''}${kernelResult[name].toString()}`; + } else { + throw new Error('unhandled fromObject'); + } + }, + thisLookup: (property) => { + if (property === 'texture') { + return textureName; + } + if (kernelResult.hasOwnProperty(property)) { + return JSON.stringify(kernelResult[property]); + } + throw new Error(`unhandled thisLookup ${ property }`); + } + }); + return `() => { + ${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; + 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') 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; + } + return null; + } + + 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; +} diff --git a/src/backend/gl/kernel.js b/src/backend/gl/kernel.js index 9f40045a..02081258 100644 --- a/src/backend/gl/kernel.js +++ b/src/backend/gl/kernel.js @@ -1,1001 +1,995 @@ -const { Kernel } = require('../kernel'); -const { Texture } = require('../../texture'); -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; - } - - /** - * @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 }`); - } - - /** - * @type {IKernelFeatures} - */ - static get features() { - throw new Error(`"features" not defined on ${ this.name }`); - } - - /** - * @abstract - */ - static setupFeatureChecks() { - throw new Error(`"setupFeatureChecks" not defined on ${ this.name }`); - } - - /** - * @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; - this.TextureConstructor = null; - this.renderOutput = null; - this.renderRawOutput = null; - this.texSize = null; - this.translatedSource = null; - this.renderStrategy = null; - this.compiledFragmentShader = null; - this.compiledVertexShader = 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; - this.renderStrategy = renderStrategy.PackedPixelTo3DFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureUnsigned2D; - this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; - return null; - } else { - this.TextureConstructor = GLTextureUnsigned; - this.renderStrategy = renderStrategy.PackedPixelToFloat; - return null; - } - break; - 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.renderStrategy = renderStrategy.PackedPixelTo3DFloat; - this.formatValues = utils.erect3DPackedFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureUnsigned2D; - this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; - this.formatValues = utils.erect2DPackedFloat; - return null; - } else { - this.TextureConstructor = GLTextureUnsigned; - this.renderStrategy = renderStrategy.PackedPixelToFloat; - this.formatValues = utils.erectPackedFloat; - return null; - } - - break; - 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.renderStrategy = renderStrategy.FloatTexture; - 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; - } - } - break; - 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; - } - break; - 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; - } - break; - 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.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized3DFloat; - this.formatValues = utils.erectMemoryOptimized3DFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureMemoryOptimized2D; - this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized2DFloat; - this.formatValues = utils.erectMemoryOptimized2DFloat; - return null; - } else { - this.TextureConstructor = GLTextureMemoryOptimized; - this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimizedFloat; - this.formatValues = utils.erectMemoryOptimizedFloat; - return null; - } - break; - case 'Array(2)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray2Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; - this.formatValues = utils.erect3DArray2; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray2Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; - this.formatValues = utils.erect2DArray2; - return null; - } else { - this.TextureConstructor = GLTextureArray2Float; - this.renderStrategy = renderStrategy.FloatPixelToArray2; - this.formatValues = utils.erectArray2; - return null; - } - break; - case 'Array(3)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray3Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; - this.formatValues = utils.erect3DArray3; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray3Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; - this.formatValues = utils.erect2DArray3; - return null; - } else { - this.TextureConstructor = GLTextureArray3Float; - this.renderStrategy = renderStrategy.FloatPixelToArray3; - this.formatValues = utils.erectArray3; - return null; - } - break; - case 'Array(4)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray4Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; - this.formatValues = utils.erect3DArray4; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray4Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; - this.formatValues = utils.erect2DArray4; - return null; - } else { - this.TextureConstructor = GLTextureArray4Float; - this.renderStrategy = renderStrategy.FloatPixelToArray4; - 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.renderStrategy = renderStrategy.FloatPixelTo3DFloat; - this.formatValues = utils.erect3DFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureFloat2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DFloat; - this.formatValues = utils.erect2DFloat; - return null; - } else { - this.TextureConstructor = GLTextureFloat; - this.renderStrategy = renderStrategy.FloatPixelToFloat; - this.formatValues = utils.erectFloat; - return null; - } - break; - case 'Array(2)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray2Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; - this.formatValues = utils.erect3DArray2; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray2Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; - this.formatValues = utils.erect2DArray2; - return null; - } else { - this.TextureConstructor = GLTextureArray2Float; - this.renderStrategy = renderStrategy.FloatPixelToArray2; - this.formatValues = utils.erectArray2; - return null; - } - break; - case 'Array(3)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray3Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; - this.formatValues = utils.erect3DArray3; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray3Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; - this.formatValues = utils.erect2DArray3; - return null; - } else { - this.TextureConstructor = GLTextureArray3Float; - this.renderStrategy = renderStrategy.FloatPixelToArray3; - this.formatValues = utils.erectArray3; - return null; - } - break; - case 'Array(4)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray4Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; - this.formatValues = utils.erect3DArray4; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray4Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; - this.formatValues = utils.erect2DArray4; - return null; - } else { - this.TextureConstructor = GLTextureArray4Float; - this.renderStrategy = renderStrategy.FloatPixelToArray4; - 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() { - switch (this.tactic) { - case 'speed': - return 'precision lowp float;\n'; - case 'performance': - return 'precision highp float;\n'; - case 'balanced': - default: - return 'precision mediump float;\n'; - } - } - - /** - * - * @return {string} - */ - getIntTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp int;\n'; - case 'performance': - return 'precision highp int;\n'; - case 'balanced': - default: - return 'precision mediump int;\n'; - } - } - - /** - * - * @return {string} - */ - getSampler2DTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp sampler2D;\n'; - case 'performance': - return 'precision highp sampler2D;\n'; - case 'balanced': - default: - return 'precision mediump sampler2D;\n'; - } - } - - getSampler2DArrayTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp sampler2DArray;\n'; - case 'performance': - return 'precision highp sampler2DArray;\n'; - case 'balanced': - default: - return 'precision mediump sampler2DArray;\n'; - } - } - - renderTexture() { - return new this.TextureConstructor({ - texture: this.outputTexture, - size: this.texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }); - } - 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; - } - - readMemoryOptimizedFloatPixelsToFloat32Array() { - 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 {Uint8Array} - */ - 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] = new this.TextureConstructor({ - texture: this.subKernelOutputTextures[i], - size: this.texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }).toArray(); - } - return result; - } - - renderKernelsToTextures() { - const result = { - result: this.renderOutput(), - }; - for (let i = 0; i < this.subKernels.length; i++) { - result[this.subKernels[i].property] = new this.TextureConstructor({ - texture: this.subKernelOutputTextures[i], - size: this.texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }); - } - return result; - } - - setOutput(output) { - super.setOutput(output); - if (this.program) { - this.threadDim = [this.output[0], this.output[1] || 1, this.output[2] || 1]; - this.texSize = utils.getKernelTextureSize({ - optimizeFloatMemory: this.optimizeFloatMemory, - precision: this.precision, - }, this.output); - const { context: gl } = this; - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - this.updateMaxTexSize(); - this.framebuffer.width = this.texSize[0]; - this.framebuffer.height = this.texSize[1]; - this.context.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); - this.canvas.width = this.maxTexSize[0]; - this.canvas.height = this.maxTexSize[1]; - this._setupOutputTexture(); - if (this.subKernels && this.subKernels.length > 0) { - this._setupSubOutputTextures(); - } - } - return this; - } - renderValues() { - return this.formatValues( - this.transferValues(), - this.output[0], - this.output[1], - this.output[2] - ); - } -} - -const renderStrategy = Object.freeze({ - PackedPixelToUint8Array: Symbol('PackedPixelToUint8Array'), - PackedPixelToFloat: Symbol('PackedPixelToFloat'), - PackedPixelTo2DFloat: Symbol('PackedPixelTo2DFloat'), - PackedPixelTo3DFloat: Symbol('PackedPixelTo3DFloat'), - PackedTexture: Symbol('PackedTexture'), - FloatPixelToFloat32Array: Symbol('FloatPixelToFloat32Array'), - FloatPixelToFloat: Symbol('FloatPixelToFloat'), - FloatPixelTo2DFloat: Symbol('FloatPixelTo2DFloat'), - FloatPixelTo3DFloat: Symbol('FloatPixelTo3DFloat'), - FloatPixelToArray2: Symbol('FloatPixelToArray2'), - FloatPixelTo2DArray2: Symbol('FloatPixelTo2DArray2'), - FloatPixelTo3DArray2: Symbol('FloatPixelTo3DArray2'), - FloatPixelToArray3: Symbol('FloatPixelToArray3'), - FloatPixelTo2DArray3: Symbol('FloatPixelTo2DArray3'), - FloatPixelTo3DArray3: Symbol('FloatPixelTo3DArray3'), - FloatPixelToArray4: Symbol('FloatPixelToArray4'), - FloatPixelTo2DArray4: Symbol('FloatPixelTo2DArray4'), - FloatPixelTo3DArray4: Symbol('FloatPixelTo3DArray4'), - FloatTexture: Symbol('FloatTexture'), - MemoryOptimizedFloatPixelToMemoryOptimizedFloat: Symbol('MemoryOptimizedFloatPixelToFloat'), - MemoryOptimizedFloatPixelToMemoryOptimized2DFloat: Symbol('MemoryOptimizedFloatPixelTo2DFloat'), - MemoryOptimizedFloatPixelToMemoryOptimized3DFloat: Symbol('MemoryOptimizedFloatPixelTo3DFloat'), -}); - -const typeMap = { - int: 'Integer', - float: 'Number', - vec2: 'Array(2)', - vec3: 'Array(3)', - vec4: 'Array(4)', -}; - -module.exports = { - GLKernel, - renderStrategy -}; \ No newline at end of file +import { Kernel } from '../kernel'; +import { utils } from '../../utils'; +import { GLTextureArray2Float } from './texture/array-2-float'; +import { GLTextureArray2Float2D } from './texture/array-2-float-2d'; +import { GLTextureArray2Float3D } from './texture/array-2-float-3d'; +import { GLTextureArray3Float } from './texture/array-3-float'; +import { GLTextureArray3Float2D } from './texture/array-3-float-2d'; +import { GLTextureArray3Float3D } from './texture/array-3-float-3d'; +import { GLTextureArray4Float } from './texture/array-4-float'; +import { GLTextureArray4Float2D } from './texture/array-4-float-2d'; +import { GLTextureArray4Float3D } from './texture/array-4-float-3d'; +import { GLTextureFloat } from './texture/float'; +import { GLTextureFloat2D } from './texture/float-2d'; +import { GLTextureFloat3D } from './texture/float-3d'; +import { GLTextureMemoryOptimized } from './texture/memory-optimized'; +import { GLTextureMemoryOptimized2D } from './texture/memory-optimized-2d'; +import { GLTextureMemoryOptimized3D } from './texture/memory-optimized-3d'; +import { GLTextureUnsigned } from './texture/unsigned'; +import { GLTextureUnsigned2D } from './texture/unsigned-2d'; +import { GLTextureUnsigned3D } from './texture/unsigned-3d'; +import { GLTextureGraphical } from './texture/graphical'; + +/** + * @abstract + * @extends Kernel + */ +export 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; + } + + /** + * @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 }`); + } + + /** + * @type {IKernelFeatures} + */ + static get features() { + throw new Error(`"features" not defined on ${ this.name }`); + } + + /** + * @abstract + */ + static setupFeatureChecks() { + throw new Error(`"setupFeatureChecks" not defined on ${ this.name }`); + } + + /** + * @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; + this.TextureConstructor = null; + this.renderOutput = null; + this.renderRawOutput = null; + this.texSize = null; + this.translatedSource = null; + this.renderStrategy = null; + this.compiledFragmentShader = null; + this.compiledVertexShader = 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; + this.renderStrategy = renderStrategy.PackedPixelTo3DFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureUnsigned2D; + this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; + return null; + } else { + this.TextureConstructor = GLTextureUnsigned; + this.renderStrategy = renderStrategy.PackedPixelToFloat; + return null; + } + break; + 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.renderStrategy = renderStrategy.PackedPixelTo3DFloat; + this.formatValues = utils.erect3DPackedFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureUnsigned2D; + this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; + this.formatValues = utils.erect2DPackedFloat; + return null; + } else { + this.TextureConstructor = GLTextureUnsigned; + this.renderStrategy = renderStrategy.PackedPixelToFloat; + this.formatValues = utils.erectPackedFloat; + return null; + } + + break; + 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.renderStrategy = renderStrategy.FloatTexture; + 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; + } + } + break; + 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; + } + break; + 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; + } + break; + 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.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized3DFloat; + this.formatValues = utils.erectMemoryOptimized3DFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureMemoryOptimized2D; + this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized2DFloat; + this.formatValues = utils.erectMemoryOptimized2DFloat; + return null; + } else { + this.TextureConstructor = GLTextureMemoryOptimized; + this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimizedFloat; + this.formatValues = utils.erectMemoryOptimizedFloat; + return null; + } + break; + case 'Array(2)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray2Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; + this.formatValues = utils.erect3DArray2; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray2Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; + this.formatValues = utils.erect2DArray2; + return null; + } else { + this.TextureConstructor = GLTextureArray2Float; + this.renderStrategy = renderStrategy.FloatPixelToArray2; + this.formatValues = utils.erectArray2; + return null; + } + break; + case 'Array(3)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray3Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; + this.formatValues = utils.erect3DArray3; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray3Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; + this.formatValues = utils.erect2DArray3; + return null; + } else { + this.TextureConstructor = GLTextureArray3Float; + this.renderStrategy = renderStrategy.FloatPixelToArray3; + this.formatValues = utils.erectArray3; + return null; + } + break; + case 'Array(4)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray4Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; + this.formatValues = utils.erect3DArray4; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray4Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; + this.formatValues = utils.erect2DArray4; + return null; + } else { + this.TextureConstructor = GLTextureArray4Float; + this.renderStrategy = renderStrategy.FloatPixelToArray4; + 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.renderStrategy = renderStrategy.FloatPixelTo3DFloat; + this.formatValues = utils.erect3DFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureFloat2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DFloat; + this.formatValues = utils.erect2DFloat; + return null; + } else { + this.TextureConstructor = GLTextureFloat; + this.renderStrategy = renderStrategy.FloatPixelToFloat; + this.formatValues = utils.erectFloat; + return null; + } + break; + case 'Array(2)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray2Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; + this.formatValues = utils.erect3DArray2; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray2Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; + this.formatValues = utils.erect2DArray2; + return null; + } else { + this.TextureConstructor = GLTextureArray2Float; + this.renderStrategy = renderStrategy.FloatPixelToArray2; + this.formatValues = utils.erectArray2; + return null; + } + break; + case 'Array(3)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray3Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; + this.formatValues = utils.erect3DArray3; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray3Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; + this.formatValues = utils.erect2DArray3; + return null; + } else { + this.TextureConstructor = GLTextureArray3Float; + this.renderStrategy = renderStrategy.FloatPixelToArray3; + this.formatValues = utils.erectArray3; + return null; + } + break; + case 'Array(4)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray4Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; + this.formatValues = utils.erect3DArray4; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray4Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; + this.formatValues = utils.erect2DArray4; + return null; + } else { + this.TextureConstructor = GLTextureArray4Float; + this.renderStrategy = renderStrategy.FloatPixelToArray4; + 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() { + switch (this.tactic) { + case 'speed': + return 'precision lowp float;\n'; + case 'performance': + return 'precision highp float;\n'; + case 'balanced': + default: + return 'precision mediump float;\n'; + } + } + + /** + * + * @return {string} + */ + getIntTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp int;\n'; + case 'performance': + return 'precision highp int;\n'; + case 'balanced': + default: + return 'precision mediump int;\n'; + } + } + + /** + * + * @return {string} + */ + getSampler2DTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp sampler2D;\n'; + case 'performance': + return 'precision highp sampler2D;\n'; + case 'balanced': + default: + return 'precision mediump sampler2D;\n'; + } + } + + getSampler2DArrayTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp sampler2DArray;\n'; + case 'performance': + return 'precision highp sampler2DArray;\n'; + case 'balanced': + default: + return 'precision mediump sampler2DArray;\n'; + } + } + + renderTexture() { + return new this.TextureConstructor({ + texture: this.outputTexture, + size: this.texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }); + } + 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; + } + + readMemoryOptimizedFloatPixelsToFloat32Array() { + 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 {Uint8Array} + */ + 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] = new this.TextureConstructor({ + texture: this.subKernelOutputTextures[i], + size: this.texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }).toArray(); + } + return result; + } + + renderKernelsToTextures() { + const result = { + result: this.renderOutput(), + }; + for (let i = 0; i < this.subKernels.length; i++) { + result[this.subKernels[i].property] = new this.TextureConstructor({ + texture: this.subKernelOutputTextures[i], + size: this.texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }); + } + return result; + } + + setOutput(output) { + super.setOutput(output); + if (this.program) { + this.threadDim = [this.output[0], this.output[1] || 1, this.output[2] || 1]; + this.texSize = utils.getKernelTextureSize({ + optimizeFloatMemory: this.optimizeFloatMemory, + precision: this.precision, + }, this.output); + const { context: gl } = this; + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + this.updateMaxTexSize(); + this.framebuffer.width = this.texSize[0]; + this.framebuffer.height = this.texSize[1]; + this.context.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); + this.canvas.width = this.maxTexSize[0]; + this.canvas.height = this.maxTexSize[1]; + this._setupOutputTexture(); + if (this.subKernels && this.subKernels.length > 0) { + this._setupSubOutputTextures(); + } + } + return this; + } + renderValues() { + return this.formatValues( + this.transferValues(), + this.output[0], + this.output[1], + this.output[2] + ); + } +} + +export const renderStrategy = Object.freeze({ + PackedPixelToUint8Array: Symbol('PackedPixelToUint8Array'), + PackedPixelToFloat: Symbol('PackedPixelToFloat'), + PackedPixelTo2DFloat: Symbol('PackedPixelTo2DFloat'), + PackedPixelTo3DFloat: Symbol('PackedPixelTo3DFloat'), + PackedTexture: Symbol('PackedTexture'), + FloatPixelToFloat32Array: Symbol('FloatPixelToFloat32Array'), + FloatPixelToFloat: Symbol('FloatPixelToFloat'), + FloatPixelTo2DFloat: Symbol('FloatPixelTo2DFloat'), + FloatPixelTo3DFloat: Symbol('FloatPixelTo3DFloat'), + FloatPixelToArray2: Symbol('FloatPixelToArray2'), + FloatPixelTo2DArray2: Symbol('FloatPixelTo2DArray2'), + FloatPixelTo3DArray2: Symbol('FloatPixelTo3DArray2'), + FloatPixelToArray3: Symbol('FloatPixelToArray3'), + FloatPixelTo2DArray3: Symbol('FloatPixelTo2DArray3'), + FloatPixelTo3DArray3: Symbol('FloatPixelTo3DArray3'), + FloatPixelToArray4: Symbol('FloatPixelToArray4'), + FloatPixelTo2DArray4: Symbol('FloatPixelTo2DArray4'), + FloatPixelTo3DArray4: Symbol('FloatPixelTo3DArray4'), + FloatTexture: Symbol('FloatTexture'), + MemoryOptimizedFloatPixelToMemoryOptimizedFloat: Symbol('MemoryOptimizedFloatPixelToFloat'), + MemoryOptimizedFloatPixelToMemoryOptimized2DFloat: Symbol('MemoryOptimizedFloatPixelTo2DFloat'), + MemoryOptimizedFloatPixelToMemoryOptimized3DFloat: Symbol('MemoryOptimizedFloatPixelTo3DFloat'), +}); + +const typeMap = { + int: 'Integer', + float: 'Number', + vec2: 'Array(2)', + vec3: 'Array(3)', + vec4: 'Array(4)', +}; diff --git a/src/backend/gl/texture/array-2-float-2d.js b/src/backend/gl/texture/array-2-float-2d.js index a0e7defd..60e14603 100644 --- a/src/backend/gl/texture/array-2-float-2d.js +++ b/src/backend/gl/texture/array-2-float-2d.js @@ -1,16 +1,12 @@ -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 +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureArray2Float2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(2)'; + } + toArray() { + return utils.erect2DArray2(this.renderValues(), this.output[0], this.output[1]); + } +} diff --git a/src/backend/gl/texture/array-2-float-3d.js b/src/backend/gl/texture/array-2-float-3d.js index 28f5b092..fb960a2f 100644 --- a/src/backend/gl/texture/array-2-float-3d.js +++ b/src/backend/gl/texture/array-2-float-3d.js @@ -1,16 +1,12 @@ -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 +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export 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]); + } +} diff --git a/src/backend/gl/texture/array-2-float.js b/src/backend/gl/texture/array-2-float.js index fab1a2ae..122ed4e6 100644 --- a/src/backend/gl/texture/array-2-float.js +++ b/src/backend/gl/texture/array-2-float.js @@ -1,16 +1,12 @@ -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 +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureArray2Float extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(2)'; + } + toArray() { + return utils.erectArray2(this.renderValues(), this.output[0], this.output[1]); + } +} diff --git a/src/backend/gl/texture/array-3-float-2d.js b/src/backend/gl/texture/array-3-float-2d.js index 4f615879..d5292524 100644 --- a/src/backend/gl/texture/array-3-float-2d.js +++ b/src/backend/gl/texture/array-3-float-2d.js @@ -1,16 +1,12 @@ -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 +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureArray3Float2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(3)'; + } + toArray() { + return utils.erect2DArray3(this.renderValues(), this.output[0], this.output[1]); + } +} diff --git a/src/backend/gl/texture/array-3-float-3d.js b/src/backend/gl/texture/array-3-float-3d.js index ea53aee0..ad8910ad 100644 --- a/src/backend/gl/texture/array-3-float-3d.js +++ b/src/backend/gl/texture/array-3-float-3d.js @@ -1,16 +1,12 @@ -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 +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export 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]); + } +} diff --git a/src/backend/gl/texture/array-3-float.js b/src/backend/gl/texture/array-3-float.js index 5f99396b..009ea8d4 100644 --- a/src/backend/gl/texture/array-3-float.js +++ b/src/backend/gl/texture/array-3-float.js @@ -1,16 +1,12 @@ -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 +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureArray3Float extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(3)'; + } + toArray() { + return utils.erectArray3(this.renderValues(), this.output[0]); + } +} diff --git a/src/backend/gl/texture/array-4-float-2d.js b/src/backend/gl/texture/array-4-float-2d.js index a370eaa2..2c1a2bbe 100644 --- a/src/backend/gl/texture/array-4-float-2d.js +++ b/src/backend/gl/texture/array-4-float-2d.js @@ -1,16 +1,12 @@ -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 +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureArray4Float2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return utils.erect2DArray4(this.renderValues(), this.output[0], this.output[1]); + } +} diff --git a/src/backend/gl/texture/array-4-float-3d.js b/src/backend/gl/texture/array-4-float-3d.js index 21e09249..6319565a 100644 --- a/src/backend/gl/texture/array-4-float-3d.js +++ b/src/backend/gl/texture/array-4-float-3d.js @@ -1,16 +1,12 @@ -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 +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export 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]); + } +} diff --git a/src/backend/gl/texture/array-4-float.js b/src/backend/gl/texture/array-4-float.js index 80553d15..4ac9d45a 100644 --- a/src/backend/gl/texture/array-4-float.js +++ b/src/backend/gl/texture/array-4-float.js @@ -1,16 +1,12 @@ -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 +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureArray4Float extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return utils.erectArray4(this.renderValues(), this.output[0]); + } +} diff --git a/src/backend/gl/texture/float-2d.js b/src/backend/gl/texture/float-2d.js index 1fb927e9..441e7d71 100644 --- a/src/backend/gl/texture/float-2d.js +++ b/src/backend/gl/texture/float-2d.js @@ -1,16 +1,12 @@ -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 +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureFloat2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(1)'; + } + toArray() { + return utils.erect2DFloat(this.renderValues(), this.output[0], this.output[1]); + } +} diff --git a/src/backend/gl/texture/float-3d.js b/src/backend/gl/texture/float-3d.js index 9a8a536f..61a19039 100644 --- a/src/backend/gl/texture/float-3d.js +++ b/src/backend/gl/texture/float-3d.js @@ -1,16 +1,12 @@ -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 +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export 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]); + } +} diff --git a/src/backend/gl/texture/float.js b/src/backend/gl/texture/float.js index 8f0b172f..8e050d08 100644 --- a/src/backend/gl/texture/float.js +++ b/src/backend/gl/texture/float.js @@ -1,34 +1,30 @@ -const { utils } = require('../../../utils'); -const { Texture } = require('../../../texture'); - -class GLTextureFloat extends Texture { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(1)'; - } - renderRawOutput() { - const { context: gl } = this; - const framebuffer = gl.createFramebuffer(); - gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); - gl.framebufferTexture2D( - gl.FRAMEBUFFER, - gl.COLOR_ATTACHMENT0, - gl.TEXTURE_2D, - this.texture, - 0 - ); - const result = new Float32Array(this.size[0] * this.size[1] * 4); - gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.FLOAT, result); - return result; - } - renderValues() { - return this.renderRawOutput(); - } - toArray() { - return utils.erectFloat(this.renderValues(), this.output[0]); - } -} - -module.exports = { - GLTextureFloat -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { Texture } from '../../../texture'; + +export class GLTextureFloat extends Texture { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(1)'; + } + renderRawOutput() { + const { context: gl } = this; + const framebuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_2D, + this.texture, + 0 + ); + const result = new Float32Array(this.size[0] * this.size[1] * 4); + gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.FLOAT, result); + return result; + } + renderValues() { + return this.renderRawOutput(); + } + toArray() { + return utils.erectFloat(this.renderValues(), this.output[0]); + } +} diff --git a/src/backend/gl/texture/graphical.js b/src/backend/gl/texture/graphical.js index 18360021..d2d8b98e 100644 --- a/src/backend/gl/texture/graphical.js +++ b/src/backend/gl/texture/graphical.js @@ -1,15 +1,11 @@ -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 +import { GLTextureUnsigned } from './unsigned'; + +export class GLTextureGraphical extends GLTextureUnsigned { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return this.renderValues(); + } +} diff --git a/src/backend/gl/texture/memory-optimized-2d.js b/src/backend/gl/texture/memory-optimized-2d.js index 20234ee3..f271274f 100644 --- a/src/backend/gl/texture/memory-optimized-2d.js +++ b/src/backend/gl/texture/memory-optimized-2d.js @@ -1,16 +1,12 @@ -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 +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureMemoryOptimized2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'MemoryOptimizedNumberTexture'; + } + toArray() { + return utils.erectMemoryOptimized2DFloat(this.renderValues(), this.output[0], this.output[1]); + } +} diff --git a/src/backend/gl/texture/memory-optimized-3d.js b/src/backend/gl/texture/memory-optimized-3d.js index f65e5f9f..847b7975 100644 --- a/src/backend/gl/texture/memory-optimized-3d.js +++ b/src/backend/gl/texture/memory-optimized-3d.js @@ -1,16 +1,12 @@ -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 +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export 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]); + } +} diff --git a/src/backend/gl/texture/memory-optimized.js b/src/backend/gl/texture/memory-optimized.js index 03474f58..f686b15a 100644 --- a/src/backend/gl/texture/memory-optimized.js +++ b/src/backend/gl/texture/memory-optimized.js @@ -1,16 +1,12 @@ -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 +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureMemoryOptimized extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'MemoryOptimizedNumberTexture'; + } + toArray() { + return utils.erectMemoryOptimizedFloat(this.renderValues(), this.output[0]); + } +} diff --git a/src/backend/gl/texture/unsigned-2d.js b/src/backend/gl/texture/unsigned-2d.js index 3adba8b1..ab717c9a 100644 --- a/src/backend/gl/texture/unsigned-2d.js +++ b/src/backend/gl/texture/unsigned-2d.js @@ -1,16 +1,12 @@ -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 +import { utils } from '../../../utils'; +import { GLTextureUnsigned } from './unsigned'; + +export class GLTextureUnsigned2D extends GLTextureUnsigned { + constructor(settings) { + super(settings); + this.type = 'NumberTexture'; + } + toArray() { + return utils.erect2DPackedFloat(this.renderValues(), this.output[0], this.output[1]); + } +} diff --git a/src/backend/gl/texture/unsigned-3d.js b/src/backend/gl/texture/unsigned-3d.js index ccedf143..343aff56 100644 --- a/src/backend/gl/texture/unsigned-3d.js +++ b/src/backend/gl/texture/unsigned-3d.js @@ -1,16 +1,12 @@ -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 +import { utils } from '../../../utils'; +import { GLTextureUnsigned } from './unsigned'; + +export 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]); + } +} diff --git a/src/backend/gl/texture/unsigned.js b/src/backend/gl/texture/unsigned.js index e67de8db..294b4f28 100644 --- a/src/backend/gl/texture/unsigned.js +++ b/src/backend/gl/texture/unsigned.js @@ -1,34 +1,30 @@ -const { utils } = require('../../../utils'); -const { Texture } = require('../../../texture'); - -class GLTextureUnsigned extends Texture { - constructor(settings) { - super(settings); - this.type = 'NumberTexture'; - } - renderRawOutput() { - const { context: gl } = this; - const framebuffer = gl.createFramebuffer(); - gl.bindFramebuffer(gl.FRAMEBUFFER, 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() { - return new Float32Array(this.renderRawOutput().buffer); - } - toArray() { - return utils.erectPackedFloat(this.renderValues(), this.output[0]); - } -} - -module.exports = { - GLTextureUnsigned -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { Texture } from '../../../texture'; + +export class GLTextureUnsigned extends Texture { + constructor(settings) { + super(settings); + this.type = 'NumberTexture'; + } + renderRawOutput() { + const { context: gl } = this; + const framebuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, 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() { + return new Float32Array(this.renderRawOutput().buffer); + } + toArray() { + return utils.erectPackedFloat(this.renderValues(), this.output[0]); + } +} diff --git a/src/backend/headless-gl/kernel.js b/src/backend/headless-gl/kernel.js index 2b3ee845..8f208e82 100644 --- a/src/backend/headless-gl/kernel.js +++ b/src/backend/headless-gl/kernel.js @@ -1,157 +1,154 @@ -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'), - }; - features = this.getFeatures(); - } catch (e) { - console.warn(e); - } - } - - static isContextMatch(context) { - try { - return context.getParameter(context.RENDERER) === 'ANGLE'; - } catch (e) { - return false; - } - } - - static getFeatures() { - const isDrawBuffers = this.getIsDrawBuffers(); - return Object.freeze({ - isFloatRead: this.getIsFloatRead(), - isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), - isTextureFloat: this.getIsTextureFloat(), - isDrawBuffers, - kernelMap: isDrawBuffers, - channelCount: this.getChannelCount(), - maxTextureSize: this.getMaxTextureSize(), - }); - } - - 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() { - const context = getContext(2, 2, { - preserveDrawingBuffer: true - }); - return context; - } - - 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]); - } - } -} - -module.exports = { - HeadlessGLKernel -}; \ No newline at end of file +import getContext from 'gl' +import { WebGLKernel } from '../web-gl/kernel'; +import { glKernelString } from '../gl/kernel-string'; + +let isSupported = null; +let testCanvas = null; +let testContext = null; +let testExtensions = null; +let features = null; + +export 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 { + // Edge cases (just in case) + 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'), + }; + features = this.getFeatures(); + } catch (e) { + console.warn(e); + } + } + + static isContextMatch(context) { + try { + return context.getParameter(context.RENDERER) === 'ANGLE'; + } catch (e) { + return false; + } + } + + static getFeatures() { + const isDrawBuffers = this.getIsDrawBuffers(); + return Object.freeze({ + isFloatRead: this.getIsFloatRead(), + isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), + isTextureFloat: this.getIsTextureFloat(), + isDrawBuffers, + kernelMap: isDrawBuffers, + channelCount: this.getChannelCount(), + maxTextureSize: this.getMaxTextureSize(), + }); + } + + 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 get testCanvas() { + return testCanvas; + } + + static getMaxTextureSize() { + return testContext.getParameter(testContext.MAX_TEXTURE_SIZE); + } + + static get testContext() { + return testContext; + } + + static get features() { + return features; + } + + initCanvas() { + return {}; + } + + initContext() { + const context = getContext(2, 2, { + preserveDrawingBuffer: true + }); + return context; + } + + 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]); + } + } +}; diff --git a/src/backend/kernel-value.js b/src/backend/kernel-value.js index ca1f9211..826de1f8 100644 --- a/src/backend/kernel-value.js +++ b/src/backend/kernel-value.js @@ -1,70 +1,67 @@ -/** - * @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 (!tactic) { - throw new Error('tactic 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.id = `${this.origin}_${name}`; - 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; - } - - 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 +/** + * @class KernelValue + */ +export 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 (!tactic) { + throw new Error('tactic 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.id = `${this.origin}_${name}`; + 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; + } + + getSource() { + throw new Error(`"getSource" not defined on ${ this.constructor.name }`); + } + + updateValue(value) { + throw new Error(`"updateValue" not defined on ${ this.constructor.name }`); + } +} diff --git a/src/backend/kernel.js b/src/backend/kernel.js index ebcb48c4..58d9fcb6 100644 --- a/src/backend/kernel.js +++ b/src/backend/kernel.js @@ -1,736 +1,738 @@ -const { utils } = require('../utils'); -const { Input } = require('../input'); - -class Kernel { - /** - * @type {Boolean} - */ - static get isSupported() { - throw new Error(`"isSupported" not implemented on ${ this.name }`); - } - - /** - * @type {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|object} 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} - */ - 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; - this.constantTypes = null; - this.constantBitRatios = null; - this.dynamicArguments = false; - this.dynamicOutput = false; - - /** - * - * @type {Object} - */ - this.canvas = null; - - /** - * - * @type {WebGLRenderingContext} - */ - 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 precison 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 = 'balanced'; - - this.plugins = null; - - this.returnType = null; - this.leadingReturnStatement = null; - this.followingReturnStatement = null; - this.optimizeFloatMemory = null; - this.strictIntegers = false; - this.fixIntegerDivisionAccuracy = null; - this.warnVarUsage = true; - } - - 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': - if (typeof settings.functions[0] === 'function') { - this.functions = settings.functions.map(source => utils.functionToIFunction(source)); - continue; - } - break; - case 'graphical': - if (settings[p] && !settings.hasOwnProperty('precision')) { - this.precision = 'unsigned'; - } - this[p] = settings[p]; - 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 {IFunctionSettings} settings - * @return {Object}; - * @abstract - */ - initPlugins(settings) { - throw new Error(`"initPlugins" not defined on ${ this.constructor.name }`); - } - - /** - * @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 {Kernel} - */ - setOptimizeFloatMemory(flag) { - this.optimizeFloatMemory = flag; - return this; - } - - /** - * @desc Set output 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; - } - - /** - * @desc Toggle debug mode - * @param {Boolean} flag - true to enable debug - */ - setDebug(flag) { - this.debug = flag; - return this; - } - - /** - * @desc Toggle graphical output mode - * @param {Boolean} flag - true to enable graphical output - */ - setGraphical(flag) { - this.graphical = flag; - this.precision = 'unsigned'; - return this; - } - - /** - * @desc Set the maximum number of loop iterations - * @param {number} max - iterations count - * - */ - setLoopMaxIterations(max) { - this.loopMaxIterations = max; - return this; - } - - /** - * @desc Set Constants - */ - setConstants(constants) { - this.constants = constants; - return this; - } - - /** - * - * @param [IKernelValueTypes] constantTypes - * @return {Kernel} - */ - setConstantTypes(constantTypes) { - this.constantTypes = constantTypes; - return this; - } - - /** - * - * @param {IFunction[]|KernelFunction[]} functions - * @return {Kernel} - */ - setFunctions(functions) { - if (typeof functions[0] === 'function') { - this.functions = functions.map(source => utils.functionToIFunction(source)); - } else { - this.functions = functions; - } - return this; - } - - /** - * - * @param {IGPUNativeFunction} nativeFunctions - * @return {Kernel} - */ - setNativeFunctions(nativeFunctions) { - this.nativeFunctions = nativeFunctions; - return this; - } - - /** - * - * @param {String} injectedNative - * @return {Kernel} - */ - setInjectedNative(injectedNative) { - this.injectedNative = injectedNative; - return this; - } - - /** - * Set writing to texture on/off - * @param flag - * @return {Kernel} - */ - setPipeline(flag) { - this.pipeline = flag; - return this; - } - - /** - * Set precision to 'unsigned' or 'single' - * @param {String} flag 'unsigned' or 'single' - * @return {Kernel} - */ - setPrecision(flag) { - this.precision = flag; - return this; - } - - /** - * @param flag - * @return {Kernel} - * @deprecated - */ - setOutputToTexture(flag) { - utils.warnDeprecated('method', 'setOutputToTexture', 'setPipeline'); - this.pipeline = flag; - return this; - } - - /** - * Set to immutable - * @param flag - * @return {Kernel} - */ - setImmutable(flag) { - this.immutable = flag; - return this; - } - - /** - * @desc Bind the canvas to kernel - * @param {Object} canvas - */ - setCanvas(canvas) { - this.canvas = canvas; - return this; - } - - /** - * @param {Boolean} flag - * @return {Kernel} - */ - setStrictIntegers(flag) { - this.strictIntegers = flag; - return this; - } - - /** - * - * @param flag - * @return {Kernel} - */ - setDynamicOutput(flag) { - this.dynamicOutput = flag; - return this; - } - - /** - * @deprecated - * @param flag - * @return {Kernel} - */ - setHardcodeConstants(flag) { - utils.warnDeprecated('method', 'setHardcodeConstants'); - this.setDynamicOutput(flag); - this.setDynamicArguments(flag); - return this; - } - - /** - * - * @param flag - * @return {Kernel} - */ - setDynamicArguments(flag) { - this.dynamicArguments = flag; - return this; - } - - /** - * @param {Boolean} flag - * @return {Kernel} - */ - setUseLegacyEncoder(flag) { - this.useLegacyEncoder = flag; - return this; - } - - /** - * - * @param {Boolean} flag - * @return {Kernel} - */ - setWarnVarUsage(flag) { - this.warnVarUsage = flag; - 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 {Kernel} - */ - setArgumentTypes(argumentTypes) { - if (Array.isArray(argumentTypes)) { - this.argumentTypes = argumentTypes; - } else { - this.argumentTypes = []; - for (const p in argumentTypes) { - 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 {Kernel} - */ - 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 upconverted 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; - } - } - - /** - * @returns {number[]} - */ - getPixels() { - 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`); - } - } - } - - toJSON() { - const settings = { - output: this.output, - threadDim: this.threadDim, - 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, - }; - return { - settings - }; - } -} - -module.exports = { - Kernel -}; \ No newline at end of file +import { Input } from '../input'; +import { + functionToIFunction, + getArgumentNamesFromString, + isArray, + isFunctionString, + warnDeprecated +} from '../common'; +import { getVariableType } from '../utils'; + +export class Kernel { + /** + * @type {Boolean} + */ + static get isSupported() { + throw new Error(`"isSupported" not implemented on ${ this.name }`); + } + + /** + * @type {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|object} source + * @param [settings] + */ + constructor(source, settings) { + if (typeof source !== 'object') { + if (typeof source !== 'string') { + throw new Error('source not a string'); + } + if (!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' ? getArgumentNamesFromString(source) : null; + this.argumentTypes = null; + this.argumentSizes = null; + this.argumentBitRatios = null; + this.kernelArguments = null; + this.kernelConstants = null; + + + /** + * The function source + * @type {String} + */ + 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; + this.constantTypes = null; + this.constantBitRatios = null; + this.dynamicArguments = false; + this.dynamicOutput = false; + + /** + * + * @type {Object} + */ + this.canvas = null; + + /** + * + * @type {WebGLRenderingContext} + */ + 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 precison 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 = 'balanced'; + + this.plugins = null; + + this.returnType = null; + this.leadingReturnStatement = null; + this.followingReturnStatement = null; + this.optimizeFloatMemory = null; + this.strictIntegers = false; + this.fixIntegerDivisionAccuracy = null; + this.warnVarUsage = true; + } + + 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': + if (typeof settings.functions[0] === 'function') { + this.functions = settings.functions.map(source => functionToIFunction(source)); + continue; + } + break; + case 'graphical': + if (settings[p] && !settings.hasOwnProperty('precision')) { + this.precision = 'unsigned'; + } + this[p] = settings[p]; + 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 {IFunctionSettings} settings + * @return {Object}; + * @abstract + */ + initPlugins(settings) { + throw new Error(`"initPlugins" not defined on ${ this.constructor.name }`); + } + + /** + * @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 = 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 = 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 {Kernel} + */ + setOptimizeFloatMemory(flag) { + this.optimizeFloatMemory = flag; + return this; + } + + /** + * @desc Set output 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; + } + + /** + * @desc Toggle debug mode + * @param {Boolean} flag - true to enable debug + */ + setDebug(flag) { + this.debug = flag; + return this; + } + + /** + * @desc Toggle graphical output mode + * @param {Boolean} flag - true to enable graphical output + */ + setGraphical(flag) { + this.graphical = flag; + this.precision = 'unsigned'; + return this; + } + + /** + * @desc Set the maximum number of loop iterations + * @param {number} max - iterations count + * + */ + setLoopMaxIterations(max) { + this.loopMaxIterations = max; + return this; + } + + /** + * @desc Set Constants + */ + setConstants(constants) { + this.constants = constants; + return this; + } + + /** + * + * @param [IKernelValueTypes] constantTypes + * @return {Kernel} + */ + setConstantTypes(constantTypes) { + this.constantTypes = constantTypes; + return this; + } + + /** + * + * @param {IFunction[]|KernelFunction[]} functions + * @return {Kernel} + */ + setFunctions(functions) { + if (typeof functions[0] === 'function') { + this.functions = functions.map(source => functionToIFunction(source)); + } else { + this.functions = functions; + } + return this; + } + + /** + * + * @param {IGPUNativeFunction} nativeFunctions + * @return {Kernel} + */ + setNativeFunctions(nativeFunctions) { + this.nativeFunctions = nativeFunctions; + return this; + } + + /** + * + * @param {String} injectedNative + * @return {Kernel} + */ + setInjectedNative(injectedNative) { + this.injectedNative = injectedNative; + return this; + } + + /** + * Set writing to texture on/off + * @param flag + * @return {Kernel} + */ + setPipeline(flag) { + this.pipeline = flag; + return this; + } + + /** + * Set precision to 'unsigned' or 'single' + * @param {String} flag 'unsigned' or 'single' + * @return {Kernel} + */ + setPrecision(flag) { + this.precision = flag; + return this; + } + + /** + * @param flag + * @return {Kernel} + * @deprecated + */ + setOutputToTexture(flag) { + warnDeprecated('method', 'setOutputToTexture', 'setPipeline'); + this.pipeline = flag; + return this; + } + + /** + * Set to immutable + * @param flag + * @return {Kernel} + */ + setImmutable(flag) { + this.immutable = flag; + return this; + } + + /** + * @desc Bind the canvas to kernel + * @param {Object} canvas + */ + setCanvas(canvas) { + this.canvas = canvas; + return this; + } + + /** + * @param {Boolean} flag + * @return {Kernel} + */ + setStrictIntegers(flag) { + this.strictIntegers = flag; + return this; + } + + /** + * + * @param flag + * @return {Kernel} + */ + setDynamicOutput(flag) { + this.dynamicOutput = flag; + return this; + } + + /** + * @deprecated + * @param flag + * @return {Kernel} + */ + setHardcodeConstants(flag) { + warnDeprecated('method', 'setHardcodeConstants'); + this.setDynamicOutput(flag); + this.setDynamicArguments(flag); + return this; + } + + /** + * + * @param flag + * @return {Kernel} + */ + setDynamicArguments(flag) { + this.dynamicArguments = flag; + return this; + } + + /** + * @param {Boolean} flag + * @return {Kernel} + */ + setUseLegacyEncoder(flag) { + this.useLegacyEncoder = flag; + return this; + } + + /** + * + * @param {Boolean} flag + * @return {Kernel} + */ + setWarnVarUsage(flag) { + this.warnVarUsage = flag; + return this; + } + + /** + * @deprecated + * @returns {Object} + */ + getCanvas() { + warnDeprecated('method', 'getCanvas'); + return this.canvas; + } + + /** + * @deprecated + * @returns {Object} + */ + getWebGl() { + 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 {Kernel} + */ + setArgumentTypes(argumentTypes) { + if (Array.isArray(argumentTypes)) { + this.argumentTypes = argumentTypes; + } else { + this.argumentTypes = []; + for (const p in argumentTypes) { + 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 {Kernel} + */ + 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 upconverted 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; + } + } + + /** + * @returns {number[]} + */ + getPixels() { + throw new Error(`"getPixels" called on ${ this.constructor.name }`); + } + + checkOutput() { + if (!this.output || !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`); + } + } + } + + toJSON() { + const settings = { + output: this.output, + threadDim: this.threadDim, + 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, + }; + return { + settings + }; + } +} diff --git a/src/backend/web-gl/fragment-shader.js b/src/backend/web-gl/fragment-shader.js index e281035a..5d8f0366 100644 --- a/src/backend/web-gl/fragment-shader.js +++ b/src/backend/web-gl/fragment-shader.js @@ -1,407 +1,403 @@ -// 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; - -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); -} - -__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 +// language=GLSL +export const fragmentShader = `__HEADER__; +__FLOAT_TACTIC_DECLARATION__; +__INT_TACTIC_DECLARATION__; +__SAMPLER_2D_TACTIC_DECLARATION__; + +const int LOOP_MAX = __LOOP_MAX__; + +__PLUGINS__; +__CONSTANTS__; + +varying vec2 vTexCoord; + +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); +} + +__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__; +}`; diff --git a/src/backend/web-gl/function-node.js b/src/backend/web-gl/function-node.js index bac93d1b..79e5b8a6 100644 --- a/src/backend/web-gl/function-node.js +++ b/src/backend/web-gl/function-node.js @@ -1,1537 +1,1530 @@ -const { utils } = require('../../utils'); -const { FunctionNode } = require('../function-node'); -// Closure capture for the ast function, prevent collision with existing AST functions -// The prefixes to use -const jsMathPrefix = 'Math.'; -const localPrefix = 'this.'; - -/** - * @desc [INTERNAL] Takes in a function node, and does all the AST voodoo required to toString its respective WebGL code - * @extends FunctionNode - * @returns the converted WebGL function string - */ -class WebGLFunctionNode extends FunctionNode { - constructor(source, settings) { - super(source, settings); - if (settings && settings.hasOwnProperty('fixIntegerDivisionAccuracy')) { - this.fixIntegerDivisionAccuracy = settings.fixIntegerDivisionAccuracy; - } - } - - /** - * @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 - let lastReturn = null; - 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 descide 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); - } - - if (type === 'sampler2D' || type === 'sampler2DArray') { - // mash needed arguments together, since now we have end to end inference - retArr.push(`${type} user_${argumentName},ivec2 user_${argumentName}Size,ivec3 user_${argumentName}Dim`); - } else { - retArr.push(`${type} user_${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'); - } - - // 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 '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 = `${ast.start},${ast.end}`; - if (Number.isInteger(ast.value)) { - if (this.isState('in-for-loop-init') || 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('div_with_int_check('); - 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': - if (this.isState('in-for-loop-test')) { - this.pushState('building-integer'); - retArr.push('int('); - this.astGeneric(ast.left, retArr); - retArr.push(')'); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.castLiteralToInteger(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.castLiteralToFloat(ast.right, retArr); - this.popState('building-float'); - } - break; - case 'LiteralInteger & Float': - case 'LiteralInteger & Number': - if (this.isState('in-for-loop-test') || this.isState('in-for-loop-init') || 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 = { - '%': 'mod', - '**': '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); - - if (idtNode.name === 'Infinity') { - // https://stackoverflow.com/a/47543127/1324039 - retArr.push('3.402823466e+38'); - } else if (type === 'Boolean') { - if (this.argumentNames.indexOf(idtNode.name) > -1) { - retArr.push(`bool(user_${idtNode.name})`); - } else { - retArr.push(`user_${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); - const { declarations } = forNode.init; - for (let i = 0; i < declarations.length; i++) { - if (declarations[i].init && declarations[i].init.type !== 'Literal') { - isSafe = false; - } - } - if (isSafe) { - 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.pushState('in-for-loop-test'); - this.astGeneric(forNode.test, testArr); - this.popState('in-for-loop-test'); - } 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 (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} 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; - } - switch (property) { - case 'r': - retArr.push(`user_${ name }.r`); - return retArr; - case 'g': - retArr.push(`user_${ name }.g`); - return retArr; - case 'b': - retArr.push(`user_${ name }.b`); - return retArr; - case 'a': - retArr.push(`user_${ name }.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_${ 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 '[][]': - 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}_${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)': - // 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 'HTMLImage': - 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; - 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 - if (functionName === 'atan2') { - functionName = 'atan'; - } - - // 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 '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') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast); - this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i); - retArr.push(`user_${argument.name}`); - continue; - } - break; - case 'HTMLImage': - 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); - retArr.push(`user_${argument.name},user_${argument.name}Size,user_${argument.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 arrLen = arrNode.elements.length; - - retArr.push('vec' + arrLen + '('); - for (let i = 0; i < arrLen; ++i) { - if (i > 0) { - retArr.push(', '); - } - const subNode = arrNode.elements[i]; - 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', - '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', - 'HTMLImage': 'sampler2D', - 'HTMLImageArray': 'sampler2DArray', -}; - -const operatorMap = { - '===': '==', - '!==': '!=' -}; - -module.exports = { - WebGLFunctionNode -}; \ No newline at end of file +import { utils } from '../../utils'; +import { FunctionNode } from '../function-node'; +// Closure capture for the ast function, prevent collision with existing AST functions +// The prefixes to use +const jsMathPrefix = 'Math.'; +const localPrefix = 'this.'; + +/** + * @desc [INTERNAL] Takes in a function node, and does all the AST voodoo required to toString its respective WebGL code + * @extends FunctionNode + * @returns the converted WebGL function string + */ +export class WebGLFunctionNode extends FunctionNode { + constructor(source, settings) { + super(source, settings); + if (settings && settings.hasOwnProperty('fixIntegerDivisionAccuracy')) { + this.fixIntegerDivisionAccuracy = settings.fixIntegerDivisionAccuracy; + } + } + + /** + * @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 + let lastReturn = null; + 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 descide 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); + } + retArr.push(type); + 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'); + } + + // 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 '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 = `${ast.start},${ast.end}`; + if (Number.isInteger(ast.value)) { + if (this.isState('in-for-loop-init') || 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('div_with_int_check('); + 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': + if (this.isState('in-for-loop-test')) { + this.pushState('building-integer'); + retArr.push('int('); + this.astGeneric(ast.left, retArr); + retArr.push(')'); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToInteger(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.castLiteralToFloat(ast.right, retArr); + this.popState('building-float'); + } + break; + case 'LiteralInteger & Float': + case 'LiteralInteger & Number': + if (this.isState('in-for-loop-test') || this.isState('in-for-loop-init') || 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 = { + '%': 'mod', + '**': '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); + + if (idtNode.name === 'Infinity') { + // https://stackoverflow.com/a/47543127/1324039 + retArr.push('3.402823466e+38'); + } else if (type === 'Boolean') { + if (this.argumentNames.indexOf(idtNode.name) > -1) { + retArr.push(`bool(user_${idtNode.name})`); + } else { + retArr.push(`user_${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); + const { declarations } = forNode.init; + for (let i = 0; i < declarations.length; i++) { + if (declarations[i].init && declarations[i].init.type !== 'Literal') { + isSafe = false; + } + } + if (isSafe) { + 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.pushState('in-for-loop-test'); + this.astGeneric(forNode.test, testArr); + this.popState('in-for-loop-test'); + } 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 (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} 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; + } + switch (property) { + case 'r': + retArr.push(`user_${ name }.r`); + return retArr; + case 'g': + retArr.push(`user_${ name }.g`); + return retArr; + case 'b': + retArr.push(`user_${ name }.b`); + return retArr; + case 'a': + retArr.push(`user_${ name }.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_${ 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 '[][]': + 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}_${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)': + // 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 'HTMLImage': + 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; + 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 + if (functionName === 'atan2') { + functionName = 'atan'; + } + + // 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 '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') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast); + this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i); + retArr.push(`user_${argument.name}`); + continue; + } + break; + case 'HTMLImage': + 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); + retArr.push(`user_${argument.name},user_${argument.name}Size,user_${argument.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 arrLen = arrNode.elements.length; + + retArr.push('vec' + arrLen + '('); + for (let i = 0; i < arrLen; ++i) { + if (i > 0) { + retArr.push(', '); + } + const subNode = arrNode.elements[i]; + 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', + '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', + 'HTMLImage': 'sampler2D', + 'HTMLImageArray': 'sampler2DArray', +}; + +const operatorMap = { + '===': '==', + '!==': '!=' +}; diff --git a/src/backend/web-gl/kernel-value-maps.js b/src/backend/web-gl/kernel-value-maps.js index e0480d68..07b2e0fa 100644 --- a/src/backend/web-gl/kernel-value-maps.js +++ b/src/backend/web-gl/kernel-value-maps.js @@ -1,186 +1,181 @@ -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 { WebGLKernelValueSingleArray2 } = require('./kernel-value/single-array2'); -const { WebGLKernelValueSingleArray3 } = require('./kernel-value/single-array3'); -const { WebGLKernelValueSingleArray4 } = require('./kernel-value/single-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)': false, - 'Array(3)': false, - 'Array(4)': false, - '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, - 'HTMLImage': WebGLKernelValueDynamicHTMLImage, - 'HTMLImageArray': false, - 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGLKernelValueBoolean, - 'Float': WebGLKernelValueFloat, - 'Integer': WebGLKernelValueInteger, - 'Array': WebGLKernelValueUnsignedArray, - 'Array(2)': false, - 'Array(3)': false, - 'Array(4)': false, - '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, - 'HTMLImage': WebGLKernelValueHTMLImage, - 'HTMLImageArray': false, - 'HTMLVideo': WebGLKernelValueHTMLVideo, - } - }, - single: { - dynamic: { - 'Boolean': WebGLKernelValueBoolean, - 'Integer': WebGLKernelValueInteger, - 'Float': WebGLKernelValueFloat, - 'Array': WebGLKernelValueDynamicSingleArray, - 'Array(2)': WebGLKernelValueSingleArray2, - 'Array(3)': WebGLKernelValueSingleArray3, - 'Array(4)': WebGLKernelValueSingleArray4, - '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, - 'HTMLImage': WebGLKernelValueDynamicHTMLImage, - 'HTMLImageArray': false, - 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGLKernelValueBoolean, - 'Float': WebGLKernelValueFloat, - 'Integer': WebGLKernelValueInteger, - 'Array': WebGLKernelValueSingleArray, - 'Array(2)': WebGLKernelValueSingleArray2, - 'Array(3)': WebGLKernelValueSingleArray3, - 'Array(4)': WebGLKernelValueSingleArray4, - '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, - 'HTMLImage': 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 +import { WebGLKernelValueBoolean } from './kernel-value/boolean'; +import { WebGLKernelValueFloat } from './kernel-value/float'; +import { WebGLKernelValueInteger } from './kernel-value/integer'; + +import { WebGLKernelValueHTMLImage } from './kernel-value/html-image'; +import { WebGLKernelValueDynamicHTMLImage } from './kernel-value/dynamic-html-image'; + +import { WebGLKernelValueHTMLVideo } from './kernel-value/html-video'; +import { WebGLKernelValueDynamicHTMLVideo } from './kernel-value/dynamic-html-video'; + +import { WebGLKernelValueSingleInput } from './kernel-value/single-input'; +import { WebGLKernelValueDynamicSingleInput } from './kernel-value/dynamic-single-input'; + +import { WebGLKernelValueUnsignedInput } from './kernel-value/unsigned-input'; +import { WebGLKernelValueDynamicUnsignedInput } from './kernel-value/dynamic-unsigned-input'; + +import { WebGLKernelValueMemoryOptimizedNumberTexture } from './kernel-value/memory-optimized-number-texture'; +import { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } from './kernel-value/dynamic-memory-optimized-number-texture'; + +import { WebGLKernelValueNumberTexture } from './kernel-value/number-texture'; +import { WebGLKernelValueDynamicNumberTexture } from './kernel-value/dynamic-number-texture'; + +import { WebGLKernelValueSingleArray } from './kernel-value/single-array'; +import { WebGLKernelValueDynamicSingleArray } from './kernel-value/dynamic-single-array'; + +import { WebGLKernelValueSingleArray1DI } from './kernel-value/single-array1d-i'; +import { WebGLKernelValueDynamicSingleArray1DI } from './kernel-value/dynamic-single-array1d-i'; + +import { WebGLKernelValueSingleArray2DI } from './kernel-value/single-array2d-i'; +import { WebGLKernelValueDynamicSingleArray2DI } from './kernel-value/dynamic-single-array2d-i'; + +import { WebGLKernelValueSingleArray3DI } from './kernel-value/single-array3d-i'; +import { WebGLKernelValueDynamicSingleArray3DI } from './kernel-value/dynamic-single-array3d-i'; + +import { WebGLKernelValueSingleArray2 } from './kernel-value/single-array2'; +import { WebGLKernelValueSingleArray3 } from './kernel-value/single-array3'; +import { WebGLKernelValueSingleArray4 } from './kernel-value/single-array4'; + +import { WebGLKernelValueUnsignedArray } from './kernel-value/unsigned-array'; +import { WebGLKernelValueDynamicUnsignedArray } from './kernel-value/dynamic-unsigned-array'; + +export const kernelValueMaps = { + unsigned: { + dynamic: { + 'Boolean': WebGLKernelValueBoolean, + 'Integer': WebGLKernelValueInteger, + 'Float': WebGLKernelValueFloat, + 'Array': WebGLKernelValueDynamicUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + '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': WebGLKernelValueMemoryOptimizedNumberTexture, + 'HTMLImage': WebGLKernelValueDynamicHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGLKernelValueBoolean, + 'Float': WebGLKernelValueFloat, + 'Integer': WebGLKernelValueInteger, + 'Array': WebGLKernelValueUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + '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': WebGLKernelValueDynamicMemoryOptimizedNumberTexture, + 'HTMLImage': WebGLKernelValueHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueHTMLVideo, + } + }, + single: { + dynamic: { + 'Boolean': WebGLKernelValueBoolean, + 'Integer': WebGLKernelValueInteger, + 'Float': WebGLKernelValueFloat, + 'Array': WebGLKernelValueDynamicSingleArray, + 'Array(2)': WebGLKernelValueSingleArray2, + 'Array(3)': WebGLKernelValueSingleArray3, + 'Array(4)': WebGLKernelValueSingleArray4, + '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, + 'HTMLImage': WebGLKernelValueDynamicHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGLKernelValueBoolean, + 'Float': WebGLKernelValueFloat, + 'Integer': WebGLKernelValueInteger, + 'Array': WebGLKernelValueSingleArray, + 'Array(2)': WebGLKernelValueSingleArray2, + 'Array(3)': WebGLKernelValueSingleArray3, + 'Array(4)': WebGLKernelValueSingleArray4, + '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, + 'HTMLImage': WebGLKernelValueHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueHTMLVideo, + } + }, +}; + +export 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]; +} diff --git a/src/backend/web-gl/kernel-value/boolean.js b/src/backend/web-gl/kernel-value/boolean.js index 895663d0..6015bb0a 100644 --- a/src/backend/web-gl/kernel-value/boolean.js +++ b/src/backend/web-gl/kernel-value/boolean.js @@ -1,28 +1,24 @@ -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 +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export 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); + } +} diff --git a/src/backend/web-gl/kernel-value/dynamic-html-image.js b/src/backend/web-gl/kernel-value/dynamic-html-image.js index 926ead66..4a58e819 100644 --- a/src/backend/web-gl/kernel-value/dynamic-html-image.js +++ b/src/backend/web-gl/kernel-value/dynamic-html-image.js @@ -1,26 +1,22 @@ -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 +import { utils } from '../../../utils'; +import { WebGLKernelValueHTMLImage } from './html-image'; + +export 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); + } +} diff --git a/src/backend/web-gl/kernel-value/dynamic-html-video.js b/src/backend/web-gl/kernel-value/dynamic-html-video.js index a10a00f6..95e1a790 100644 --- a/src/backend/web-gl/kernel-value/dynamic-html-video.js +++ b/src/backend/web-gl/kernel-value/dynamic-html-video.js @@ -1,7 +1,3 @@ -const { WebGLKernelValueDynamicHTMLImage } = require('./dynamic-html-image'); - -class WebGLKernelValueDynamicHTMLVideo extends WebGLKernelValueDynamicHTMLImage {} - -module.exports = { - WebGLKernelValueDynamicHTMLVideo -}; \ No newline at end of file +import { WebGLKernelValueDynamicHTMLImage } from './dynamic-html-image'; + +export class WebGLKernelValueDynamicHTMLVideo extends WebGLKernelValueDynamicHTMLImage {} 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 index 1083f40f..157fd5d5 100644 --- 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 @@ -1,25 +1,21 @@ -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.checkSize(inputTexture.size[0], inputTexture.size[1]); - this.dimensions = inputTexture.dimensions; - 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 +import { utils } from '../../../utils'; +import { WebGLKernelValueMemoryOptimizedNumberTexture } from './memory-optimized-number-texture'; + +export class WebGLKernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture { + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + + updateValue(inputTexture) { + this.checkSize(inputTexture.size[0], inputTexture.size[1]); + this.dimensions = inputTexture.dimensions; + this.textureSize = inputTexture.size; + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(inputTexture); + } +} diff --git a/src/backend/web-gl/kernel-value/dynamic-number-texture.js b/src/backend/web-gl/kernel-value/dynamic-number-texture.js index edf5980d..3526a1ca 100644 --- a/src/backend/web-gl/kernel-value/dynamic-number-texture.js +++ b/src/backend/web-gl/kernel-value/dynamic-number-texture.js @@ -1,25 +1,21 @@ -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 +import { utils } from '../../../utils'; +import { WebGLKernelValueNumberTexture } from './number-texture'; + +export 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); + } +} diff --git a/src/backend/web-gl/kernel-value/dynamic-single-array.js b/src/backend/web-gl/kernel-value/dynamic-single-array.js index ed0135eb..7f26eae7 100644 --- a/src/backend/web-gl/kernel-value/dynamic-single-array.js +++ b/src/backend/web-gl/kernel-value/dynamic-single-array.js @@ -1,27 +1,23 @@ -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.bitRatio, this.textureSize[1] * this.bitRatio); - 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 +import { utils } from '../../../utils'; +import { WebGLKernelValueSingleArray } from './single-array'; + +export 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.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } +} 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 index 0c9489ce..89cd81f5 100644 --- a/src/backend/web-gl/kernel-value/dynamic-single-array1d-i.js +++ b/src/backend/web-gl/kernel-value/dynamic-single-array1d-i.js @@ -1,23 +1,19 @@ -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 +import { utils } from '../../../utils'; +import { WebGLKernelValueSingleArray1DI } from './single-array1d-i'; + +export 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); + } +} 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 index b164f3c1..ba9b474f 100644 --- a/src/backend/web-gl/kernel-value/dynamic-single-array2d-i.js +++ b/src/backend/web-gl/kernel-value/dynamic-single-array2d-i.js @@ -1,23 +1,19 @@ -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 +import { utils } from '../../../utils'; +import { WebGLKernelValueSingleArray2DI } from './single-array2d-i'; + +export 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); + } +} 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 index b1d52a5d..a6d8deeb 100644 --- a/src/backend/web-gl/kernel-value/dynamic-single-array3d-i.js +++ b/src/backend/web-gl/kernel-value/dynamic-single-array3d-i.js @@ -1,23 +1,19 @@ -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 +import { utils } from '../../../utils'; +import { WebGLKernelValueSingleArray3DI } from './single-array3d-i'; + +export 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); + } +} diff --git a/src/backend/web-gl/kernel-value/dynamic-single-input.js b/src/backend/web-gl/kernel-value/dynamic-single-input.js index a2efbdb1..38684525 100644 --- a/src/backend/web-gl/kernel-value/dynamic-single-input.js +++ b/src/backend/web-gl/kernel-value/dynamic-single-input.js @@ -1,28 +1,24 @@ -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.bitRatio, this.textureSize[1] * this.bitRatio); - 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 +import { utils } from '../../../utils'; +import { WebGLKernelValueSingleInput } from './single-input'; + +export 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.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } +} diff --git a/src/backend/web-gl/kernel-value/dynamic-unsigned-array.js b/src/backend/web-gl/kernel-value/dynamic-unsigned-array.js index ca0db3ac..2e1a9b8e 100644 --- a/src/backend/web-gl/kernel-value/dynamic-unsigned-array.js +++ b/src/backend/web-gl/kernel-value/dynamic-unsigned-array.js @@ -1,29 +1,25 @@ -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] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - 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 +import { utils } from '../../../utils'; +import { WebGLKernelValueUnsignedArray } from './unsigned-array'; + +export 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] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + 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); + } +} diff --git a/src/backend/web-gl/kernel-value/dynamic-unsigned-input.js b/src/backend/web-gl/kernel-value/dynamic-unsigned-input.js index bba6c923..51482dc8 100644 --- a/src/backend/web-gl/kernel-value/dynamic-unsigned-input.js +++ b/src/backend/web-gl/kernel-value/dynamic-unsigned-input.js @@ -1,30 +1,26 @@ -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] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - 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 +import { utils } from '../../../utils'; +import { WebGLKernelValueUnsignedInput } from './unsigned-input'; + +export 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] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + 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); + } +} diff --git a/src/backend/web-gl/kernel-value/float.js b/src/backend/web-gl/kernel-value/float.js index 3668bfb6..8685a881 100644 --- a/src/backend/web-gl/kernel-value/float.js +++ b/src/backend/web-gl/kernel-value/float.js @@ -1,30 +1,26 @@ -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 +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export 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); + } +} diff --git a/src/backend/web-gl/kernel-value/html-image.js b/src/backend/web-gl/kernel-value/html-image.js index eaf2404c..7a9cc9c7 100644 --- a/src/backend/web-gl/kernel-value/html-image.js +++ b/src/backend/web-gl/kernel-value/html-image.js @@ -1,47 +1,43 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueHTMLImage extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - const { width, height } = value; - this.checkSize(width, height); - this.dimensions = [width, height, 1]; - this.requestTexture(); - 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(); - return; - } - 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); - 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 +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueHTMLImage extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + const { width, height } = value; + this.checkSize(width, height); + this.dimensions = [width, height, 1]; + this.requestTexture(); + 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(); + return; + } + 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); + 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); + } +} diff --git a/src/backend/web-gl/kernel-value/html-video.js b/src/backend/web-gl/kernel-value/html-video.js index 64a2793e..bc18180b 100644 --- a/src/backend/web-gl/kernel-value/html-video.js +++ b/src/backend/web-gl/kernel-value/html-video.js @@ -1,8 +1,3 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueHTMLImage } = require('./html-image'); - -class WebGLKernelValueHTMLVideo extends WebGLKernelValueHTMLImage {} - -module.exports = { - WebGLKernelValueHTMLVideo -}; \ No newline at end of file +import { WebGLKernelValueHTMLImage } from './html-image'; + +export class WebGLKernelValueHTMLVideo extends WebGLKernelValueHTMLImage {} diff --git a/src/backend/web-gl/kernel-value/index.js b/src/backend/web-gl/kernel-value/index.js index 9b64f165..741118f6 100644 --- a/src/backend/web-gl/kernel-value/index.js +++ b/src/backend/web-gl/kernel-value/index.js @@ -1,157 +1,153 @@ -const { utils } = require('../../../utils'); -const { Input } = require('../../../input'); -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; - } - - /** - * - * @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 width of ${width} larger than maximum size of ${maxTextureSize} for your GPU`); - } else { - throw new Error(`Argument height of ${height} larger than maximum size of ${maxTextureSize} for your GPU`); - } - } - } - - requestTexture() { - this.texture = this.onRequestTexture(); - this.setupTexture(); - } - - setupTexture() { - this.contextHandle = this.onRequestContextHandle(); - this.index = this.onRequestIndex(); - this.dimensionsId = this.id + 'Dim'; - this.sizeId = this.id + 'Size'; - } - - 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; - } - /** - * @desc Adds kernel parameters to the Value Texture, - * binding it to the context, etc. - * - * @param {Array|Float32Array|Uint16Array} value - The actual Value supplied to the kernel - * @param {Number} length - the expected total length of the output array - * @param {Object} [Type] - * @returns {Float32Array|Uint16Array|Uint8Array} flattened array to transfer - */ - formatArrayTransfer(value, length, Type) { - if (utils.isArray(value[0]) || this.optimizeFloatMemory) { - // not already flat - const valuesFlat = new Float32Array(length); - utils.flattenTo(value, valuesFlat); - return valuesFlat; - } else { - switch (value.constructor) { - case Uint8ClampedArray: - case Uint8Array: - case Int8Array: - case Uint16Array: - case Int16Array: - case Float32Array: - case Int32Array: { - const valuesFlat = new(Type || value.constructor)(length); - utils.flattenTo(value, valuesFlat); - return valuesFlat; - } - default: { - const valuesFlat = new Float32Array(length); - utils.flattenTo(value, valuesFlat); - return valuesFlat; - } - } - } - } - - /** - * 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; - } - } - - /** - * 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() { - switch (this.tactic) { - case 'speed': - return 'lowp'; - case 'performance': - return 'highp'; - case 'balanced': - default: - return 'mediump'; - } - } -} - -module.exports = { - WebGLKernelValue -}; \ No newline at end of file +import { Input } from '../../../input'; +import { KernelValue } from '../../kernel-value'; +import { utils } from '../../../utils'; + +export 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; + } + + /** + * + * @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 width of ${width} larger than maximum size of ${maxTextureSize} for your GPU`); + } else { + throw new Error(`Argument height of ${height} larger than maximum size of ${maxTextureSize} for your GPU`); + } + } + } + + requestTexture() { + this.texture = this.onRequestTexture(); + this.setupTexture(); + } + + setupTexture() { + this.contextHandle = this.onRequestContextHandle(); + this.index = this.onRequestIndex(); + this.dimensionsId = this.id + 'Dim'; + this.sizeId = this.id + 'Size'; + } + + 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; + } + /** + * @desc Adds kernel parameters to the Value Texture, + * binding it to the context, etc. + * + * @param {Array|Float32Array|Uint16Array} value - The actual Value supplied to the kernel + * @param {Number} length - the expected total length of the output array + * @param {Object} [Type] + * @returns {Float32Array|Uint16Array|Uint8Array} flattened array to transfer + */ + formatArrayTransfer(value, length, Type) { + if (utils.isArray(value[0]) || this.optimizeFloatMemory) { + // not already flat + const valuesFlat = new Float32Array(length); + utils.flattenTo(value, valuesFlat); + return valuesFlat; + } else { + switch (value.constructor) { + case Uint8ClampedArray: + case Uint8Array: + case Int8Array: + case Uint16Array: + case Int16Array: + case Float32Array: + case Int32Array: { + const valuesFlat = new(Type || value.constructor)(length); + utils.flattenTo(value, valuesFlat); + return valuesFlat; + } + default: { + const valuesFlat = new Float32Array(length); + utils.flattenTo(value, valuesFlat); + return valuesFlat; + } + } + } + } + + /** + * 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; + } + } + + /** + * 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() { + switch (this.tactic) { + case 'speed': + return 'lowp'; + case 'performance': + return 'highp'; + case 'balanced': + default: + return 'mediump'; + } + } +} diff --git a/src/backend/web-gl/kernel-value/integer.js b/src/backend/web-gl/kernel-value/integer.js index c7dad4ac..f79c2925 100644 --- a/src/backend/web-gl/kernel-value/integer.js +++ b/src/backend/web-gl/kernel-value/integer.js @@ -1,27 +1,23 @@ -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 +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export 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); + } +} 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 index 418e2a5f..05f45ff8 100644 --- a/src/backend/web-gl/kernel-value/memory-optimized-number-texture.js +++ b/src/backend/web-gl/kernel-value/memory-optimized-number-texture.js @@ -1,45 +1,41 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueMemoryOptimizedNumberTexture extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - const [width, height] = value.size; - this.checkSize(width, height); - this.setupTexture(); - this.dimensions = value.dimensions; - this.textureSize = value.size; - this.uploadValue = value.texture; - this.forceUploadEachRun = true; - } - - 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(); - return; - } - if (this.checkContext && inputTexture.context !== this.context) { - throw new Error(`Value ${this.name} (${this.type }) must be from same context`); - } - const { context: gl } = this; - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueMemoryOptimizedNumberTexture -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueMemoryOptimizedNumberTexture extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + const [width, height] = value.size; + this.checkSize(width, height); + this.setupTexture(); + this.dimensions = value.dimensions; + this.textureSize = value.size; + this.uploadValue = value.texture; + this.forceUploadEachRun = true; + } + + 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(); + return; + } + if (this.checkContext && inputTexture.context !== this.context) { + throw new Error(`Value ${this.name} (${this.type }) must be from same context`); + } + const { context: gl } = this; + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); + this.kernel.setUniform1i(this.id, this.index); + } +} diff --git a/src/backend/web-gl/kernel-value/number-texture.js b/src/backend/web-gl/kernel-value/number-texture.js index 2548c9a9..ae80f249 100644 --- a/src/backend/web-gl/kernel-value/number-texture.js +++ b/src/backend/web-gl/kernel-value/number-texture.js @@ -1,47 +1,43 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueNumberTexture extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - const [width, height] = value.size; - this.checkSize(width, height); - this.setupTexture(); - const { size: textureSize, dimensions } = value; - this.bitRatio = this.getBitRatio(value); - this.dimensions = dimensions; - this.textureSize = textureSize; - this.uploadValue = value.texture; - this.forceUploadEachRun = true; - } - - 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(); - return; - } - if (this.checkContext && inputTexture.context !== this.context) { - throw new Error(`Value ${this.name} (${this.type}) must be from same context`); - } - const { context: gl } = this; - 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 +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueNumberTexture extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + const [width, height] = value.size; + this.checkSize(width, height); + this.setupTexture(); + const { size: textureSize, dimensions } = value; + this.bitRatio = this.getBitRatio(value); + this.dimensions = dimensions; + this.textureSize = textureSize; + this.uploadValue = value.texture; + this.forceUploadEachRun = true; + } + + 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(); + return; + } + if (this.checkContext && inputTexture.context !== this.context) { + throw new Error(`Value ${this.name} (${this.type}) must be from same context`); + } + const { context: gl } = this; + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); + this.kernel.setUniform1i(this.id, this.index); + } +} diff --git a/src/backend/web-gl/kernel-value/single-array.js b/src/backend/web-gl/kernel-value/single-array.js index 1cca1b0b..0dc477b1 100644 --- a/src/backend/web-gl/kernel-value/single-array.js +++ b/src/backend/web-gl/kernel-value/single-array.js @@ -1,51 +1,47 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - 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.bitRatio, this.textureSize[1] * this.bitRatio); - 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(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - 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); - 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 +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueSingleArray extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + 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.bitRatio, this.textureSize[1] * this.bitRatio); + 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(); + return; + } + const { context: gl } = this; + utils.flattenTo(value, this.uploadValue); + 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); + 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); + } +} diff --git a/src/backend/web-gl/kernel-value/single-array1d-i.js b/src/backend/web-gl/kernel-value/single-array1d-i.js index 999f7820..9d6a3d46 100644 --- a/src/backend/web-gl/kernel-value/single-array1d-i.js +++ b/src/backend/web-gl/kernel-value/single-array1d-i.js @@ -1,56 +1,52 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray1DI extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - 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.bitRatio, this.textureSize[1] * this.bitRatio); - 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(); - return; - } - const { context: gl } = this; - utils.flatten2dArrayTo(value, this.uploadValue); - 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); - 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 +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueSingleArray1DI extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + 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.bitRatio, this.textureSize[1] * this.bitRatio); + 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(); + return; + } + const { context: gl } = this; + utils.flatten2dArrayTo(value, this.uploadValue); + 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); + 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); + } +} diff --git a/src/backend/web-gl/kernel-value/single-array2.js b/src/backend/web-gl/kernel-value/single-array2.js index 4121a675..fa1edd27 100644 --- a/src/backend/web-gl/kernel-value/single-array2.js +++ b/src/backend/web-gl/kernel-value/single-array2.js @@ -1,30 +1,26 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray2 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 = { - WebGLKernelValueSingleArray2 -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueSingleArray2 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); + } +} diff --git a/src/backend/web-gl/kernel-value/single-array2d-i.js b/src/backend/web-gl/kernel-value/single-array2d-i.js index 22419a3a..b9f378f8 100644 --- a/src/backend/web-gl/kernel-value/single-array2d-i.js +++ b/src/backend/web-gl/kernel-value/single-array2d-i.js @@ -1,56 +1,52 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray2DI extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - 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.bitRatio, this.textureSize[1] * this.bitRatio); - 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(); - return; - } - const { context: gl } = this; - utils.flatten3dArrayTo(value, this.uploadValue); - 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); - 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 +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueSingleArray2DI extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + 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.bitRatio, this.textureSize[1] * this.bitRatio); + 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(); + return; + } + const { context: gl } = this; + utils.flatten3dArrayTo(value, this.uploadValue); + 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); + 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); + } +} diff --git a/src/backend/web-gl/kernel-value/single-array3.js b/src/backend/web-gl/kernel-value/single-array3.js index 56781a8b..ce318c2c 100644 --- a/src/backend/web-gl/kernel-value/single-array3.js +++ b/src/backend/web-gl/kernel-value/single-array3.js @@ -1,30 +1,26 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray3 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 = { - WebGLKernelValueSingleArray3 -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueSingleArray3 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); + } +} diff --git a/src/backend/web-gl/kernel-value/single-array3d-i.js b/src/backend/web-gl/kernel-value/single-array3d-i.js index 236829a8..27aa7319 100644 --- a/src/backend/web-gl/kernel-value/single-array3d-i.js +++ b/src/backend/web-gl/kernel-value/single-array3d-i.js @@ -1,56 +1,52 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray3DI extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - 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.bitRatio, this.textureSize[1] * this.bitRatio); - 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(); - return; - } - const { context: gl } = this; - utils.flatten4dArrayTo(value, this.uploadValue); - 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); - 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 +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueSingleArray3DI extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + 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.bitRatio, this.textureSize[1] * this.bitRatio); + 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(); + return; + } + const { context: gl } = this; + utils.flatten4dArrayTo(value, this.uploadValue); + 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); + 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); + } +} diff --git a/src/backend/web-gl/kernel-value/single-array4.js b/src/backend/web-gl/kernel-value/single-array4.js index c5d93f48..4fd5512c 100644 --- a/src/backend/web-gl/kernel-value/single-array4.js +++ b/src/backend/web-gl/kernel-value/single-array4.js @@ -1,30 +1,26 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray4 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 = { - WebGLKernelValueSingleArray4 -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueSingleArray4 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); + } +} diff --git a/src/backend/web-gl/kernel-value/single-input.js b/src/backend/web-gl/kernel-value/single-input.js index 2124d43d..651074d7 100644 --- a/src/backend/web-gl/kernel-value/single-input.js +++ b/src/backend/web-gl/kernel-value/single-input.js @@ -1,52 +1,48 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleInput extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - 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.bitRatio, this.textureSize[1] * this.bitRatio); - 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(); - return; - } - const { context: gl } = this; - utils.flattenTo(input.value, this.uploadValue); - 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); - 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 +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueSingleInput extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + 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.bitRatio, this.textureSize[1] * this.bitRatio); + 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(); + return; + } + const { context: gl } = this; + utils.flattenTo(input.value, this.uploadValue); + 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); + 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); + } +} diff --git a/src/backend/web-gl/kernel-value/unsigned-array.js b/src/backend/web-gl/kernel-value/unsigned-array.js index 753932e0..f3bfed0c 100644 --- a/src/backend/web-gl/kernel-value/unsigned-array.js +++ b/src/backend/web-gl/kernel-value/unsigned-array.js @@ -1,54 +1,50 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueUnsignedArray extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - 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] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - 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(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.preUploadValue); - 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); - 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 +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueUnsignedArray extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + 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] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + 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(); + return; + } + const { context: gl } = this; + utils.flattenTo(value, this.preUploadValue); + 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); + 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); + } +} diff --git a/src/backend/web-gl/kernel-value/unsigned-input.js b/src/backend/web-gl/kernel-value/unsigned-input.js index 9cb720bc..a9397e62 100644 --- a/src/backend/web-gl/kernel-value/unsigned-input.js +++ b/src/backend/web-gl/kernel-value/unsigned-input.js @@ -1,55 +1,51 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueUnsignedInput extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - 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] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - 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(); - return; - } - const { context: gl } = this; - utils.flattenTo(input.value, this.preUploadValue); - 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); - 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 +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueUnsignedInput extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + 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] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + 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(); + return; + } + const { context: gl } = this; + utils.flattenTo(input.value, this.preUploadValue); + 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); + 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); + } +} diff --git a/src/backend/web-gl/kernel.js b/src/backend/web-gl/kernel.js index e7340391..ad15f268 100644 --- a/src/backend/web-gl/kernel.js +++ b/src/backend/web-gl/kernel.js @@ -1,1567 +1,1557 @@ -const { GLKernel } = require('../gl/kernel'); -const { FunctionBuilder } = require('../function-builder'); -const { WebGLFunctionNode } = require('./function-node'); -const { utils } = require('../../utils'); -const triangleNoise = require('../../plugins/triangle-noise'); -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 = [triangleNoise]; -const canvases = []; -const maxTexSizes = {}; - - -/** - * @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.

- * - * @prop {Object} textureCache - webGl Texture cache - * @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} pipeline - Set output type to FAST mode (GPU to GPU via Textures), instead of float - * @prop {String} endianness - Endian information like Little-endian, Big-endian. - * @prop {Array} argumentTypes - Types of parameters sent to the Kernel - * @prop {String} compiledFragmentShader - Compiled fragment shader string - * @prop {String} 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 getFeatures() { - const isDrawBuffers = this.getIsDrawBuffers(); - return Object.freeze({ - isFloatRead: this.getIsFloatRead(), - isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), - isTextureFloat: this.getIsTextureFloat(), - isDrawBuffers, - kernelMap: isDrawBuffers, - channelCount: this.getChannelCount(), - maxTextureSize: this.getMaxTextureSize(), - }); - } - - 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; - } - - /** - * - * @param {String} source - * @param {IKernelSettings} settings - */ - constructor(source, settings) { - super(source, settings); - this.program = null; - this.pipeline = settings.pipeline; - this.endianness = utils.systemEndianness(); - this.extensions = {}; - this.subKernelOutputTextures = null; - this.kernelArguments = null; - this.argumentTextureCount = 0; - this.constantTextureCount = 0; - this.compiledFragmentShader = null; - this.compiledVertexShader = null; - this.fragShader = null; - this.vertShader = null; - this.drawBuffersMap = null; - this.outputTexture = null; - - /** - * - * @type {Int32Array|null} - */ - this.maxTexSize = null; - this.switchingKernels = false; - this.onRequestSwitchKernel = 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); - } - } - - initContext() { - const settings = { - alpha: false, - depth: false, - antialias: false - }; - return this.canvas.getContext('webgl', settings) || this.canvas.getContext('experimental-webgl', settings); - } - - 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); - 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'); - } - - 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]; - } - } - - // TODO: move channel checks to new place - _oldtranslateSource() { - const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { - fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy - }); - - // need this line to automatically get returnType - const translatedSource = functionBuilder.getPrototypeString('kernel'); - - if (!this.returnType) { - this.returnType = functionBuilder.getKernelResultType(); - } - - let requiredChannels = 0; - const returnTypes = functionBuilder.getReturnTypes(); - for (let i = 0; i < returnTypes.length; i++) { - switch (returnTypes[i]) { - case 'Float': - case 'Number': - case 'Integer': - requiredChannels++; - break; - case 'Array(2)': - requiredChannels += 2; - break; - case 'Array(3)': - requiredChannels += 3; - break; - case 'Array(4)': - requiredChannels += 4; - break; - } - } - - if (features && requiredChannels > features.channelCount) { - throw new Error('Too many channels!'); - } - - return this.translatedSource = translatedSource; - } - - 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; - 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: () => { - return this.context.createTexture(); - }, - onRequestIndex: () => { - return textureIndexes++; - }, - onUpdateValueMismatch: () => { - this.switchingKernels = true; - }, - onRequestContextHandle: () => { - return gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount++; - } - }); - this.kernelArguments.push(kernelArgument); - this.argumentSizes.push(kernelArgument.textureSize); - this.argumentBitRatios[index] = kernelArgument.bitRatio; - } - } - - 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.context.createTexture(); - }, - onRequestIndex: () => { - return textureIndexes++; - }, - onRequestContextHandle: () => { - return gl.TEXTURE0 + this.constantTextureCount++; - } - }); - this.constantBitRatios[name] = kernelValue.bitRatio; - this.kernelConstants.push(kernelValue); - if (kernelValue.forceUploadEachRun) { - this.forceUploadKernelConstants.push(kernelValue); - } - } - } - - build() { - 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]; - - 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]); - } - - if (!this.immutable) { - this._setupOutputTexture(); - if ( - this.subKernels !== null && - this.subKernels.length > 0 - ) { - this._setupSubOutputTextures(); - } - } - } - - translateSource() { - const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { - fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy - }); - this.translatedSource = functionBuilder.getPrototypeString('kernel'); - 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, forceUploadKernelConstants } = this; - const texSize = this.texSize; - const gl = this.context; - - 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]); - - this.switchingKernels = false; - 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.outputTexture || this.immutable) { - this._setupOutputTexture(); - } - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - return new this.TextureConstructor({ - texture: this.outputTexture, - size: texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }); - } - 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._setupOutputTexture(); - } - - if (this.subKernels !== null) { - if (this.immutable) { - this._setupSubOutputTextures(); - } - this.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(this.drawBuffersMap); - } - - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - } - - /** - * @desc This return defined outputTexture, which is setup in .build(), or if immutable, is defined in .run() - * @returns {Object} Output Texture Cache - */ - getOutputTexture() { - return this.outputTexture; - } - - /** - * @desc Setup and replace output texture - */ - _setupOutputTexture() { - const gl = this.context; - const texSize = this.texSize; - const texture = this.outputTexture = this.context.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); - // 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); - // } - if (this.precision === 'single') { - if (this.pipeline) { - // TODO: investigate if webgl1 can handle gl.RED usage in gl.texImage2D, otherwise, simplify the below - switch (this.returnType) { - case 'Number': - case 'Float': - case 'Integer': - if (this.optimizeFloatMemory) { - 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.FLOAT, null); - } - break; - case 'Array(2)': - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - break; - case 'Array(3)': - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - break; - case 'Array(4)': - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - break; - default: - if (!this.graphical) { - throw new Error('Unhandled return type'); - } - } - } else { - 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, gl.TEXTURE_2D, texture, 0); - } - - /** - * @desc Setup and replace sub-output textures - */ - _setupSubOutputTextures() { - const gl = this.context; - const texSize = this.texSize; - this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; - this.subKernelOutputTextures = []; - for (let i = 0; i < this.subKernels.length; i++) { - const texture = this.context.createTexture(); - this.subKernelOutputTextures.push(texture); - 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); - } - } - - /** - * @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.textureCache.hasOwnProperty(name)) { - return this.textureCache[name]; - } - return this.textureCache[name] = this.context.createTexture(); - } - - /** - * @desc removes a texture from the kernel's cache - * @param {String} name - Name of texture - */ - detachTextureCache(name) { - delete this.textureCache[name]; - } - - 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); - } - - 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); - } - - 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); - } - - 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); - } - - /** - * @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 div_with_int_check(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; -}` : - ''; - } - - /** - * @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) { - result.push(this.kernelConstants[i++].getSource(this.constants[name])); - } - } - return result.join(''); - } - - /** - * @desc Get Kernel program string (in *glsl*) for a kernel. - * @returns {String} result - */ - getKernelString() { - let kernelResultDeclaration; - switch (this.returnType) { - case 'Array(2)': - kernelResultDeclaration = 'vec2 kernelResult'; - break; - case 'Array(3)': - kernelResultDeclaration = 'vec3 kernelResult'; - break; - case 'Array(4)': - kernelResultDeclaration = 'vec4 kernelResult'; - break; - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - kernelResultDeclaration = 'float kernelResult'; - break; - default: - if (this.graphical) { - kernelResultDeclaration = 'float kernelResult'; - } else { - throw new Error(`unrecognized output type "${ this.returnType }"`); - } - } - - const result = []; - const subKernels = this.subKernels; - if (subKernels !== null) { - result.push( - kernelResultDeclaration - ); - 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; - } - } else { - result.push( - kernelResultDeclaration - ); - } - - 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}`, - ); - } - } - 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.outputTexture) { - this.context.deleteTexture(this.outputTexture); - } - if (this.buffer) { - this.context.deleteBuffer(this.buffer); - } - if (this.framebuffer) { - this.context.deleteFramebuffer(this.framebuffer); - } - if (this.vertShader) { - this.context.deleteShader(this.vertShader); - } - if (this.fragShader) { - this.context.deleteShader(this.fragShader); - } - if (this.program) { - this.context.deleteProgram(this.program); - } - - const keys = Object.keys(this.textureCache); - - for (let i = 0; i < keys.length; i++) { - const name = keys[i]; - this.context.deleteTexture(this.textureCache[name]); - } - - if (this.subKernelOutputTextures) { - for (let i = 0; i < this.subKernelOutputTextures.length; i++) { - this.context.deleteTexture(this.subKernelOutputTextures[i]); - } - } - 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; - } - - 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(); - return json; - } -} - -module.exports = { - WebGLKernel -}; \ No newline at end of file +import { GLKernel } from '../gl/kernel'; +import { FunctionBuilder } from '../function-builder'; +import { WebGLFunctionNode } from './function-node'; +import { utils } from '../../utils'; +import triangleNoise from '../../plugins/triangle-noise'; +import { fragmentShader } from './fragment-shader'; +import { vertexShader } from './vertex-shader'; +import { glKernelString } from '../gl/kernel-string'; +import { lookupKernelValueType } from './kernel-value-maps'; + +let isSupported = null; +let testCanvas = null; +let testContext = null; +let testExtensions = null; +let features = null; + +const plugins = [triangleNoise]; +const canvases = []; +const maxTexSizes = {}; + +/** + * @desc Kernel Implementation for WebGL. + * + * This builds the shaders and runs them on the GPU, then outputs the result + * back as float (enabled by default) and Texture. + * + * @prop {Object} textureCache - webGl Texture cache + * @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} pipeline - Set output type to FAST mode (GPU to GPU via Textures), instead of float + * @prop {String} endianness - Endian information like Little-endian, Big-endian. + * @prop {Array} argumentTypes - Types of parameters sent to the Kernel + * @prop {String} compiledFragmentShader - Compiled fragment shader string + * @prop {String} compiledVertexShader - Compiled Vertical shader string + * @extends GLKernel + */ +export 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 getFeatures() { + const isDrawBuffers = this.getIsDrawBuffers(); + return Object.freeze({ + isFloatRead: this.getIsFloatRead(), + isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), + isTextureFloat: this.getIsTextureFloat(), + isDrawBuffers, + kernelMap: isDrawBuffers, + channelCount: this.getChannelCount(), + }); + } + + 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 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} source + * @param {IKernelSettings} settings + */ + constructor(source, settings) { + super(source, settings); + this.program = null; + this.pipeline = settings.pipeline; + this.endianness = utils.systemEndianness(); + this.extensions = {}; + this.subKernelOutputTextures = null; + this.kernelArguments = null; + this.argumentTextureCount = 0; + this.constantTextureCount = 0; + this.compiledFragmentShader = null; + this.compiledVertexShader = null; + this.fragShader = null; + this.vertShader = null; + this.drawBuffersMap = null; + this.outputTexture = null; + + /** + * + * @type {Int32Array|null} + */ + this.maxTexSize = null; + this.switchingKernels = false; + this.onRequestSwitchKernel = 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); + } + } + + initContext() { + const settings = { + alpha: false, + depth: false, + antialias: false + }; + return this.canvas.getContext('webgl', settings) || this.canvas.getContext('experimental-webgl', settings); + } + + 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); + 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'); + } + + 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]; + } + } + + // TODO: move channel checks to new place + _oldtranslateSource() { + const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { + fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy + }); + + // need this line to automatically get returnType + const translatedSource = functionBuilder.getPrototypeString('kernel'); + + if (!this.returnType) { + this.returnType = functionBuilder.getKernelResultType(); + } + + let requiredChannels = 0; + const returnTypes = functionBuilder.getReturnTypes(); + for (let i = 0; i < returnTypes.length; i++) { + switch (returnTypes[i]) { + case 'Float': + case 'Number': + case 'Integer': + requiredChannels++; + break; + case 'Array(2)': + requiredChannels += 2; + break; + case 'Array(3)': + requiredChannels += 3; + break; + case 'Array(4)': + requiredChannels += 4; + break; + } + } + + if (features && requiredChannels > features.channelCount) { + throw new Error('Too many channels!'); + } + + return this.translatedSource = translatedSource; + } + + 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; + 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: () => { + return this.context.createTexture(); + }, + onRequestIndex: () => { + return textureIndexes++; + }, + onUpdateValueMismatch: () => { + this.switchingKernels = true; + }, + onRequestContextHandle: () => { + return gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount++; + } + }); + this.kernelArguments.push(kernelArgument); + this.argumentSizes.push(kernelArgument.textureSize); + this.argumentBitRatios[index] = kernelArgument.bitRatio; + } + } + + 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.context.createTexture(); + }, + onRequestIndex: () => { + return textureIndexes++; + }, + onRequestContextHandle: () => { + return gl.TEXTURE0 + this.constantTextureCount++; + } + }); + this.constantBitRatios[name] = kernelValue.bitRatio; + this.kernelConstants.push(kernelValue); + if (kernelValue.forceUploadEachRun) { + this.forceUploadKernelConstants.push(kernelValue); + } + } + } + + build() { + 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]; + + 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]); + } + + if (!this.immutable) { + this._setupOutputTexture(); + if ( + this.subKernels !== null && + this.subKernels.length > 0 + ) { + this._setupSubOutputTextures(); + } + } + } + + translateSource() { + const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { + fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy + }); + this.translatedSource = functionBuilder.getPrototypeString('kernel'); + 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, forceUploadKernelConstants } = this; + const texSize = this.texSize; + const gl = this.context; + + 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]); + + this.switchingKernels = false; + 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.outputTexture || this.immutable) { + this._setupOutputTexture(); + } + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + return new this.TextureConstructor({ + texture: this.outputTexture, + size: texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }); + } + 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._setupOutputTexture(); + } + + if (this.subKernels !== null) { + if (this.immutable) { + this._setupSubOutputTextures(); + } + this.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(this.drawBuffersMap); + } + + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + } + + /** + * @desc This return defined outputTexture, which is setup in .build(), or if immutable, is defined in .run() + * @returns {Object} Output Texture Cache + */ + getOutputTexture() { + return this.outputTexture; + } + + /** + * @desc Setup and replace output texture + */ + _setupOutputTexture() { + const gl = this.context; + const texSize = this.texSize; + const texture = this.outputTexture = this.context.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); + // 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); + // } + if (this.precision === 'single') { + if (this.pipeline) { + // TODO: investigate if webgl1 can handle gl.RED usage in gl.texImage2D, otherwise, simplify the below + switch (this.returnType) { + case 'Number': + case 'Float': + case 'Integer': + if (this.optimizeFloatMemory) { + 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.FLOAT, null); + } + break; + case 'Array(2)': + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + break; + case 'Array(3)': + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + break; + case 'Array(4)': + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + break; + default: + if (!this.graphical) { + throw new Error('Unhandled return type'); + } + } + } else { + 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, gl.TEXTURE_2D, texture, 0); + } + + /** + * @desc Setup and replace sub-output textures + */ + _setupSubOutputTextures() { + const gl = this.context; + const texSize = this.texSize; + this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; + this.subKernelOutputTextures = []; + for (let i = 0; i < this.subKernels.length; i++) { + const texture = this.context.createTexture(); + this.subKernelOutputTextures.push(texture); + 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); + } + } + + /** + * @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.textureCache.hasOwnProperty(name)) { + return this.textureCache[name]; + } + return this.textureCache[name] = this.context.createTexture(); + } + + /** + * @desc removes a texture from the kernel's cache + * @param {String} name - Name of texture + */ + detachTextureCache(name) { + delete this.textureCache[name]; + } + + 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); + } + + 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); + } + + 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); + } + + 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); + } + + /** + * @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 div_with_int_check(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; +}` : + ''; + } + + /** + * @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) { + result.push(this.kernelConstants[i++].getSource(this.constants[name])); + } + } + return result.join(''); + } + + /** + * @desc Get Kernel program string (in *glsl*) for a kernel. + * @returns {String} result + */ + getKernelString() { + let kernelResultDeclaration; + switch (this.returnType) { + case 'Array(2)': + kernelResultDeclaration = 'vec2 kernelResult'; + break; + case 'Array(3)': + kernelResultDeclaration = 'vec3 kernelResult'; + break; + case 'Array(4)': + kernelResultDeclaration = 'vec4 kernelResult'; + break; + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + kernelResultDeclaration = 'float kernelResult'; + break; + default: + if (this.graphical) { + kernelResultDeclaration = 'float kernelResult'; + } else { + throw new Error(`unrecognized output type "${ this.returnType }"`); + } + } + + const result = []; + const subKernels = this.subKernels; + if (subKernels !== null) { + result.push( + kernelResultDeclaration + ); + 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; + } + } else { + result.push( + kernelResultDeclaration + ); + } + + 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}`, + ); + } + } + 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.outputTexture) { + this.context.deleteTexture(this.outputTexture); + } + if (this.buffer) { + this.context.deleteBuffer(this.buffer); + } + if (this.framebuffer) { + this.context.deleteFramebuffer(this.framebuffer); + } + if (this.vertShader) { + this.context.deleteShader(this.vertShader); + } + if (this.fragShader) { + this.context.deleteShader(this.fragShader); + } + if (this.program) { + this.context.deleteProgram(this.program); + } + + const keys = Object.keys(this.textureCache); + + for (let i = 0; i < keys.length; i++) { + const name = keys[i]; + this.context.deleteTexture(this.textureCache[name]); + } + + if (this.subKernelOutputTextures) { + for (let i = 0; i < this.subKernelOutputTextures.length; i++) { + this.context.deleteTexture(this.subKernelOutputTextures[i]); + } + } + 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; + } + + 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(); + return json; + } +} diff --git a/src/backend/web-gl/vertex-shader.js b/src/backend/web-gl/vertex-shader.js index 88647d73..f4e7cf49 100644 --- a/src/backend/web-gl/vertex-shader.js +++ b/src/backend/web-gl/vertex-shader.js @@ -1,19 +1,15 @@ -// 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 +// language=GLSL +export 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; +}`; diff --git a/src/backend/web-gl2/fragment-shader.js b/src/backend/web-gl2/fragment-shader.js index 8a31c1be..d50dcae3 100644 --- a/src/backend/web-gl2/fragment-shader.js +++ b/src/backend/web-gl2/fragment-shader.js @@ -1,395 +1,391 @@ -// 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; - -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); -} - -__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 +// language=GLSL +export 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; + +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); +} + +__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__; +}`; diff --git a/src/backend/web-gl2/function-node.js b/src/backend/web-gl2/function-node.js index ccf35af4..7db91258 100644 --- a/src/backend/web-gl2/function-node.js +++ b/src/backend/web-gl2/function-node.js @@ -1,45 +1,41 @@ -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); - - if (idtNode.name === 'Infinity') { - retArr.push('intBitsToFloat(2139095039)'); - } else if (type === 'Boolean') { - if (this.argumentNames.indexOf(idtNode.name) > -1) { - retArr.push(`bool(user_${idtNode.name})`); - } else { - retArr.push(`user_${idtNode.name}`); - } - } else { - retArr.push(`user_${idtNode.name}`); - } - - return retArr; - } -} - -module.exports = { - WebGL2FunctionNode -}; \ No newline at end of file +import { WebGLFunctionNode } from '../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 + */ +export 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); + + if (idtNode.name === 'Infinity') { + retArr.push('intBitsToFloat(2139095039)'); + } else if (type === 'Boolean') { + if (this.argumentNames.indexOf(idtNode.name) > -1) { + retArr.push(`bool(user_${idtNode.name})`); + } else { + retArr.push(`user_${idtNode.name}`); + } + } else { + retArr.push(`user_${idtNode.name}`); + } + + return retArr; + } +} diff --git a/src/backend/web-gl2/kernel-value-maps.js b/src/backend/web-gl2/kernel-value-maps.js index 357fa824..67e8a856 100644 --- a/src/backend/web-gl2/kernel-value-maps.js +++ b/src/backend/web-gl2/kernel-value-maps.js @@ -1,189 +1,184 @@ -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 { WebGL2KernelValueSingleArray2 } = require('./kernel-value/single-array2'); -const { WebGL2KernelValueSingleArray3 } = require('./kernel-value/single-array3'); -const { WebGL2KernelValueSingleArray4 } = require('./kernel-value/single-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)': false, - 'Array(3)': false, - 'Array(4)': false, - '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, - 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, - 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, - 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGL2KernelValueBoolean, - 'Float': WebGL2KernelValueFloat, - 'Integer': WebGL2KernelValueInteger, - 'Array': WebGL2KernelValueUnsignedArray, - 'Array(2)': false, - 'Array(3)': false, - 'Array(4)': false, - '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, - 'HTMLImage': WebGL2KernelValueHTMLImage, - 'HTMLImageArray': WebGL2KernelValueHTMLImageArray, - 'HTMLVideo': WebGL2KernelValueHTMLVideo, - } - }, - single: { - dynamic: { - 'Boolean': WebGL2KernelValueBoolean, - 'Integer': WebGL2KernelValueInteger, - 'Float': WebGL2KernelValueFloat, - 'Array': WebGL2KernelValueDynamicSingleArray, - 'Array(2)': WebGL2KernelValueSingleArray2, - 'Array(3)': WebGL2KernelValueSingleArray3, - 'Array(4)': WebGL2KernelValueSingleArray4, - '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, - 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, - 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, - 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGL2KernelValueBoolean, - 'Float': WebGL2KernelValueFloat, - 'Integer': WebGL2KernelValueInteger, - 'Array': WebGL2KernelValueSingleArray, - 'Array(2)': WebGL2KernelValueSingleArray2, - 'Array(3)': WebGL2KernelValueSingleArray3, - 'Array(4)': WebGL2KernelValueSingleArray4, - '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, - 'HTMLImage': 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 +import { WebGL2KernelValueBoolean } from './kernel-value/boolean'; +import { WebGL2KernelValueFloat } from './kernel-value/float'; +import { WebGL2KernelValueInteger } from './kernel-value/integer'; + +import { WebGL2KernelValueHTMLImage } from './kernel-value/html-image'; +import { WebGL2KernelValueDynamicHTMLImage } from './kernel-value/dynamic-html-image'; + +import { WebGL2KernelValueHTMLImageArray } from './kernel-value/html-image-array'; +import { WebGL2KernelValueDynamicHTMLImageArray } from './kernel-value/dynamic-html-image-array'; + +import { WebGL2KernelValueHTMLVideo } from './kernel-value/html-video'; +import { WebGL2KernelValueDynamicHTMLVideo } from './kernel-value/dynamic-html-video'; + +import { WebGL2KernelValueSingleInput } from './kernel-value/single-input'; +import { WebGL2KernelValueDynamicSingleInput } from './kernel-value/dynamic-single-input'; + +import { WebGL2KernelValueUnsignedInput } from './kernel-value/unsigned-input'; +import { WebGL2KernelValueDynamicUnsignedInput } from './kernel-value/dynamic-unsigned-input'; + +import { WebGL2KernelValueMemoryOptimizedNumberTexture } from './kernel-value/memory-optimized-number-texture'; +import { WebGL2KernelValueDynamicMemoryOptimizedNumberTexture } from './kernel-value/dynamic-memory-optimized-number-texture'; + +import { WebGL2KernelValueNumberTexture } from './kernel-value/number-texture'; +import { WebGL2KernelValueDynamicNumberTexture } from './kernel-value/dynamic-number-texture'; + +import { WebGL2KernelValueSingleArray } from './kernel-value/single-array'; +import { WebGL2KernelValueDynamicSingleArray } from './kernel-value/dynamic-single-array'; + +import { WebGL2KernelValueSingleArray1DI } from './kernel-value/single-array1d-i'; +import { WebGL2KernelValueDynamicSingleArray1DI } from './kernel-value/dynamic-single-array1d-i'; + +import { WebGL2KernelValueSingleArray2DI } from './kernel-value/single-array2d-i'; +import { WebGL2KernelValueDynamicSingleArray2DI } from './kernel-value/dynamic-single-array2d-i'; + +import { WebGL2KernelValueSingleArray3DI } from './kernel-value/single-array3d-i'; +import { WebGL2KernelValueDynamicSingleArray3DI } from './kernel-value/dynamic-single-array3d-i'; + +import { WebGL2KernelValueSingleArray2 } from './kernel-value/single-array2'; +import { WebGL2KernelValueSingleArray3 } from './kernel-value/single-array3'; +import { WebGL2KernelValueSingleArray4 } from './kernel-value/single-array4'; + +import { WebGL2KernelValueUnsignedArray } from './kernel-value/unsigned-array'; +import { WebGL2KernelValueDynamicUnsignedArray } from './kernel-value/dynamic-unsigned-array'; + +export const kernelValueMaps = { + unsigned: { + dynamic: { + 'Boolean': WebGL2KernelValueBoolean, + 'Integer': WebGL2KernelValueInteger, + 'Float': WebGL2KernelValueFloat, + 'Array': WebGL2KernelValueDynamicUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + '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, + 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, + 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGL2KernelValueBoolean, + 'Float': WebGL2KernelValueFloat, + 'Integer': WebGL2KernelValueInteger, + 'Array': WebGL2KernelValueUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + '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, + 'HTMLImage': WebGL2KernelValueHTMLImage, + 'HTMLImageArray': WebGL2KernelValueHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueHTMLVideo, + } + }, + single: { + dynamic: { + 'Boolean': WebGL2KernelValueBoolean, + 'Integer': WebGL2KernelValueInteger, + 'Float': WebGL2KernelValueFloat, + 'Array': WebGL2KernelValueDynamicSingleArray, + 'Array(2)': WebGL2KernelValueSingleArray2, + 'Array(3)': WebGL2KernelValueSingleArray3, + 'Array(4)': WebGL2KernelValueSingleArray4, + '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, + 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, + 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGL2KernelValueBoolean, + 'Float': WebGL2KernelValueFloat, + 'Integer': WebGL2KernelValueInteger, + 'Array': WebGL2KernelValueSingleArray, + 'Array(2)': WebGL2KernelValueSingleArray2, + 'Array(3)': WebGL2KernelValueSingleArray3, + 'Array(4)': WebGL2KernelValueSingleArray4, + '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, + 'HTMLImage': WebGL2KernelValueHTMLImage, + 'HTMLImageArray': WebGL2KernelValueHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueHTMLVideo, + } + }, +}; + +export 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]; +} diff --git a/src/backend/web-gl2/kernel-value/boolean.js b/src/backend/web-gl2/kernel-value/boolean.js index c91a61a9..3f765060 100644 --- a/src/backend/web-gl2/kernel-value/boolean.js +++ b/src/backend/web-gl2/kernel-value/boolean.js @@ -1,7 +1,3 @@ -const { WebGLKernelValueBoolean } = require('../../web-gl/kernel-value/boolean'); - -class WebGL2KernelValueBoolean extends WebGLKernelValueBoolean {} - -module.exports = { - WebGL2KernelValueBoolean -}; \ No newline at end of file +import { WebGLKernelValueBoolean } from '../../web-gl/kernel-value/boolean'; + +export class WebGL2KernelValueBoolean extends WebGLKernelValueBoolean {} 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 index dab14341..c96ef1ce 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-html-image-array.js +++ b/src/backend/web-gl2/kernel-value/dynamic-html-image-array.js @@ -1,26 +1,22 @@ -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 +import { WebGL2KernelValueHTMLImageArray } from './html-image-array'; + +export 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); + } +} diff --git a/src/backend/web-gl2/kernel-value/dynamic-html-image.js b/src/backend/web-gl2/kernel-value/dynamic-html-image.js index f1ba34eb..352bfe56 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-html-image.js +++ b/src/backend/web-gl2/kernel-value/dynamic-html-image.js @@ -1,17 +1,13 @@ -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 +import { utils } from '../../../utils'; +import { WebGLKernelValueDynamicHTMLImage } from '../../web-gl/kernel-value/dynamic-html-image'; + +export 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}`, + ]); + } +} diff --git a/src/backend/web-gl2/kernel-value/dynamic-html-video.js b/src/backend/web-gl2/kernel-value/dynamic-html-video.js index 00f723d1..81b617f6 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-html-video.js +++ b/src/backend/web-gl2/kernel-value/dynamic-html-video.js @@ -1,8 +1,3 @@ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueDynamicHTMLImage } = require('./dynamic-html-image'); - -class WebGL2KernelValueDynamicHTMLVideo extends WebGL2KernelValueDynamicHTMLImage {} - -module.exports = { - WebGL2KernelValueDynamicHTMLVideo -}; \ No newline at end of file +import { WebGL2KernelValueDynamicHTMLImage } from './dynamic-html-image'; + +export class WebGL2KernelValueDynamicHTMLVideo extends WebGL2KernelValueDynamicHTMLImage {} 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 index 5e3cff4b..e0f5d50e 100644 --- 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 @@ -1,16 +1,12 @@ -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 +import { utils } from '../../../utils'; +import { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } from '../../web-gl/kernel-value/dynamic-memory-optimized-number-texture'; + +export class WebGL2KernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueDynamicMemoryOptimizedNumberTexture { + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } +} diff --git a/src/backend/web-gl2/kernel-value/dynamic-number-texture.js b/src/backend/web-gl2/kernel-value/dynamic-number-texture.js index e3820a56..443b7425 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-number-texture.js +++ b/src/backend/web-gl2/kernel-value/dynamic-number-texture.js @@ -1,17 +1,13 @@ -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 +import { utils } from '../../../utils'; +import { WebGLKernelValueDynamicNumberTexture } from '../../web-gl/kernel-value/dynamic-number-texture'; + +export 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}`, + ]); + } +} diff --git a/src/backend/web-gl2/kernel-value/dynamic-single-array.js b/src/backend/web-gl2/kernel-value/dynamic-single-array.js index 3356cdbf..9374fc2a 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-single-array.js +++ b/src/backend/web-gl2/kernel-value/dynamic-single-array.js @@ -1,28 +1,24 @@ -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.bitRatio, this.textureSize[1] * this.bitRatio); - 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 +import { utils } from '../../../utils'; +import { WebGL2KernelValueSingleArray } from '../../web-gl2/kernel-value/single-array'; + +export 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.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } +} 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 index 45203f92..344b79d1 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-single-array1d-i.js +++ b/src/backend/web-gl2/kernel-value/dynamic-single-array1d-i.js @@ -1,24 +1,20 @@ -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 +import { utils } from '../../../utils'; +import { WebGL2KernelValueSingleArray1DI } from '../../web-gl2/kernel-value/single-array1d-i'; + +export 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); + } +} 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 index d80f712d..127bb64f 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-single-array2d-i.js +++ b/src/backend/web-gl2/kernel-value/dynamic-single-array2d-i.js @@ -1,24 +1,20 @@ -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 +import { utils } from '../../../utils'; +import { WebGL2KernelValueSingleArray2DI } from '../../web-gl2/kernel-value/single-array2d-i'; + +export 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); + } +} 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 index 15f79ba4..1dd343f5 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-single-array3d-i.js +++ b/src/backend/web-gl2/kernel-value/dynamic-single-array3d-i.js @@ -1,24 +1,20 @@ -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 +import { utils } from '../../../utils'; +import { WebGL2KernelValueSingleArray3DI } from '../../web-gl2/kernel-value/single-array3d-i'; + +export 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); + } +} diff --git a/src/backend/web-gl2/kernel-value/dynamic-single-input.js b/src/backend/web-gl2/kernel-value/dynamic-single-input.js index 02058a11..95ee750a 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-single-input.js +++ b/src/backend/web-gl2/kernel-value/dynamic-single-input.js @@ -1,29 +1,25 @@ -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.bitRatio, this.textureSize[1] * this.bitRatio); - 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 +import { utils } from '../../../utils'; +import { WebGL2KernelValueSingleInput } from '../../web-gl2/kernel-value/single-input'; + +export 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.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } +} diff --git a/src/backend/web-gl2/kernel-value/dynamic-unsigned-array.js b/src/backend/web-gl2/kernel-value/dynamic-unsigned-array.js index 514682c5..1190d00d 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-unsigned-array.js +++ b/src/backend/web-gl2/kernel-value/dynamic-unsigned-array.js @@ -1,17 +1,13 @@ -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 +import { utils } from '../../../utils'; +import { WebGLKernelValueDynamicUnsignedArray } from '../../web-gl/kernel-value/dynamic-unsigned-array'; + +export 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}`, + ]); + } +} diff --git a/src/backend/web-gl2/kernel-value/dynamic-unsigned-input.js b/src/backend/web-gl2/kernel-value/dynamic-unsigned-input.js index 9c79330a..c9311fa8 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-unsigned-input.js +++ b/src/backend/web-gl2/kernel-value/dynamic-unsigned-input.js @@ -1,17 +1,13 @@ -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 +import { utils } from '../../../utils'; +import { WebGLKernelValueDynamicUnsignedInput } from '../../web-gl/kernel-value/dynamic-unsigned-input'; + +export 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}`, + ]); + } +} diff --git a/src/backend/web-gl2/kernel-value/float.js b/src/backend/web-gl2/kernel-value/float.js index b3fc5a78..0ebc9a6c 100644 --- a/src/backend/web-gl2/kernel-value/float.js +++ b/src/backend/web-gl2/kernel-value/float.js @@ -1,8 +1,3 @@ -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 +import { WebGLKernelValueFloat } from '../../web-gl/kernel-value/float'; + +export class WebGL2KernelValueFloat extends WebGLKernelValueFloat {} diff --git a/src/backend/web-gl2/kernel-value/html-image-array.js b/src/backend/web-gl2/kernel-value/html-image-array.js index 07303b4b..634965e4 100644 --- a/src/backend/web-gl2/kernel-value/html-image-array.js +++ b/src/backend/web-gl2/kernel-value/html-image-array.js @@ -1,68 +1,64 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('../../web-gl/kernel-value/index'); - -class WebGL2KernelValueHTMLImageArray extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.checkSize(value[0].width, value[0].height); - this.requestTexture(); - this.dimensions = [value[0].width, value[0].height, value.length]; - this.textureSize = [value[0].width, value[0].height]; - } - 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.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - 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 +import { utils } from '../../../utils'; +import { WebGLKernelValue } from '../../web-gl/kernel-value/index'; + +export class WebGL2KernelValueHTMLImageArray extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.checkSize(value[0].width, value[0].height); + this.requestTexture(); + this.dimensions = [value[0].width, value[0].height, value.length]; + this.textureSize = [value[0].width, value[0].height]; + } + 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.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + 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); + } +} diff --git a/src/backend/web-gl2/kernel-value/html-image.js b/src/backend/web-gl2/kernel-value/html-image.js index 637182a0..e749aaf7 100644 --- a/src/backend/web-gl2/kernel-value/html-image.js +++ b/src/backend/web-gl2/kernel-value/html-image.js @@ -1,17 +1,13 @@ -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 +import { utils } from '../../../utils'; +import { WebGLKernelValueHTMLImage } from '../../web-gl/kernel-value/html-image'; + +export 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]})`, + ]); + } +} diff --git a/src/backend/web-gl2/kernel-value/html-video.js b/src/backend/web-gl2/kernel-value/html-video.js index 85fb3953..665773ff 100644 --- a/src/backend/web-gl2/kernel-value/html-video.js +++ b/src/backend/web-gl2/kernel-value/html-video.js @@ -1,8 +1,3 @@ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueHTMLImage } = require('./html-image'); - -class WebGL2KernelValueHTMLVideo extends WebGL2KernelValueHTMLImage {} - -module.exports = { - WebGL2KernelValueHTMLVideo -}; \ No newline at end of file +import { WebGL2KernelValueHTMLImage } from './html-image'; + +export class WebGL2KernelValueHTMLVideo extends WebGL2KernelValueHTMLImage {} diff --git a/src/backend/web-gl2/kernel-value/integer.js b/src/backend/web-gl2/kernel-value/integer.js index a41a2533..530df2fb 100644 --- a/src/backend/web-gl2/kernel-value/integer.js +++ b/src/backend/web-gl2/kernel-value/integer.js @@ -1,21 +1,16 @@ -const { utils } = require('../../../utils'); -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 +import { WebGLKernelValueInteger } from '../../web-gl/kernel-value/integer'; + +export 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); + } +} 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 index 7fd85798..d4830b97 100644 --- a/src/backend/web-gl2/kernel-value/memory-optimized-number-texture.js +++ b/src/backend/web-gl2/kernel-value/memory-optimized-number-texture.js @@ -1,18 +1,14 @@ -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 +import { utils } from '../../../utils'; +import { WebGLKernelValueMemoryOptimizedNumberTexture } from '../../web-gl/kernel-value/memory-optimized-number-texture'; + +export 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]})`, + ]); + } +} diff --git a/src/backend/web-gl2/kernel-value/number-texture.js b/src/backend/web-gl2/kernel-value/number-texture.js index 440f1e4e..d638c528 100644 --- a/src/backend/web-gl2/kernel-value/number-texture.js +++ b/src/backend/web-gl2/kernel-value/number-texture.js @@ -1,18 +1,14 @@ -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 +import { utils } from '../../../utils'; +import { WebGLKernelValueNumberTexture } from '../../web-gl/kernel-value/number-texture'; + +export 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]})`, + ]); + } +} diff --git a/src/backend/web-gl2/kernel-value/single-array.js b/src/backend/web-gl2/kernel-value/single-array.js index c6ff3d9b..6bce4a4a 100644 --- a/src/backend/web-gl2/kernel-value/single-array.js +++ b/src/backend/web-gl2/kernel-value/single-array.js @@ -1,34 +1,30 @@ -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(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - 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); - 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 +import { utils } from '../../../utils'; +import { WebGLKernelValueSingleArray } from '../../web-gl/kernel-value/single-array'; + +export 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(); + return; + } + const { context: gl } = this; + utils.flattenTo(value, this.uploadValue); + 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); + 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); + } +} diff --git a/src/backend/web-gl2/kernel-value/single-array1d-i.js b/src/backend/web-gl2/kernel-value/single-array1d-i.js index 6a64101d..a380c9c9 100644 --- a/src/backend/web-gl2/kernel-value/single-array1d-i.js +++ b/src/backend/web-gl2/kernel-value/single-array1d-i.js @@ -1,25 +1,21 @@ -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(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - 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); - 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 +import { utils } from '../../../utils'; +import { WebGLKernelValueSingleArray1DI } from '../../web-gl/kernel-value/single-array1d-i'; + +export class WebGL2KernelValueSingleArray1DI extends WebGLKernelValueSingleArray1DI { + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils.flattenTo(value, this.uploadValue); + 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); + 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); + } +} diff --git a/src/backend/web-gl2/kernel-value/single-array2.js b/src/backend/web-gl2/kernel-value/single-array2.js index 638125fb..ff41ed60 100644 --- a/src/backend/web-gl2/kernel-value/single-array2.js +++ b/src/backend/web-gl2/kernel-value/single-array2.js @@ -1,7 +1,3 @@ -const { WebGLKernelValueSingleArray2 } = require('../../web-gl/kernel-value/single-array2'); - -class WebGL2KernelValueSingleArray2 extends WebGLKernelValueSingleArray2 {} - -module.exports = { - WebGL2KernelValueSingleArray2 -}; \ No newline at end of file +import { WebGLKernelValueSingleArray2 } from '../../web-gl/kernel-value/single-array2'; + +export class WebGL2KernelValueSingleArray2 extends WebGLKernelValueSingleArray2 {} diff --git a/src/backend/web-gl2/kernel-value/single-array2d-i.js b/src/backend/web-gl2/kernel-value/single-array2d-i.js index 8374e67c..4c62c47f 100644 --- a/src/backend/web-gl2/kernel-value/single-array2d-i.js +++ b/src/backend/web-gl2/kernel-value/single-array2d-i.js @@ -1,25 +1,21 @@ -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(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - 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); - 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 +import { utils } from '../../../utils'; +import { WebGLKernelValueSingleArray2DI } from '../../web-gl/kernel-value/single-array2d-i'; + +export class WebGL2KernelValueSingleArray2DI extends WebGLKernelValueSingleArray2DI { + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils.flattenTo(value, this.uploadValue); + 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); + 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); + } +} diff --git a/src/backend/web-gl2/kernel-value/single-array3.js b/src/backend/web-gl2/kernel-value/single-array3.js index 9af01c8f..3dc5df84 100644 --- a/src/backend/web-gl2/kernel-value/single-array3.js +++ b/src/backend/web-gl2/kernel-value/single-array3.js @@ -1,7 +1,3 @@ -const { WebGLKernelValueSingleArray3 } = require('../../web-gl/kernel-value/single-array3'); - -class WebGL2KernelValueSingleArray3 extends WebGLKernelValueSingleArray3 {} - -module.exports = { - WebGL2KernelValueSingleArray3 -}; \ No newline at end of file +import { WebGLKernelValueSingleArray3 } from '../../web-gl/kernel-value/single-array3'; + +export class WebGL2KernelValueSingleArray3 extends WebGLKernelValueSingleArray3 {} diff --git a/src/backend/web-gl2/kernel-value/single-array3d-i.js b/src/backend/web-gl2/kernel-value/single-array3d-i.js index ea850885..382a3600 100644 --- a/src/backend/web-gl2/kernel-value/single-array3d-i.js +++ b/src/backend/web-gl2/kernel-value/single-array3d-i.js @@ -1,25 +1,21 @@ -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(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - 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); - 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 +import { utils } from '../../../utils'; +import { WebGLKernelValueSingleArray3DI } from '../../web-gl/kernel-value/single-array3d-i'; + +export class WebGL2KernelValueSingleArray3DI extends WebGLKernelValueSingleArray3DI { + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils.flattenTo(value, this.uploadValue); + 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); + 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); + } +} diff --git a/src/backend/web-gl2/kernel-value/single-array4.js b/src/backend/web-gl2/kernel-value/single-array4.js index d5ec9d2a..d84ac6bc 100644 --- a/src/backend/web-gl2/kernel-value/single-array4.js +++ b/src/backend/web-gl2/kernel-value/single-array4.js @@ -1,7 +1,3 @@ -const { WebGLKernelValueSingleArray4 } = require('../../web-gl/kernel-value/single-array4'); - -class WebGL2KernelValueSingleArray4 extends WebGLKernelValueSingleArray4 {} - -module.exports = { - WebGL2KernelValueSingleArray4 -}; \ No newline at end of file +import { WebGLKernelValueSingleArray4 } from '../../web-gl/kernel-value/single-array4'; + +export class WebGL2KernelValueSingleArray4 extends WebGLKernelValueSingleArray4 {} diff --git a/src/backend/web-gl2/kernel-value/single-input.js b/src/backend/web-gl2/kernel-value/single-input.js index 2bf23acb..6dac696b 100644 --- a/src/backend/web-gl2/kernel-value/single-input.js +++ b/src/backend/web-gl2/kernel-value/single-input.js @@ -1,30 +1,26 @@ -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.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); - 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 +import { utils } from '../../../utils'; +import { WebGLKernelValueSingleInput } from '../../web-gl/kernel-value/single-input'; + +export 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.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); + 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); + } +} diff --git a/src/backend/web-gl2/kernel-value/unsigned-array.js b/src/backend/web-gl2/kernel-value/unsigned-array.js index bac1e6f1..ca8cff6c 100644 --- a/src/backend/web-gl2/kernel-value/unsigned-array.js +++ b/src/backend/web-gl2/kernel-value/unsigned-array.js @@ -1,17 +1,13 @@ -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 +import { utils } from '../../../utils'; +import { WebGLKernelValueUnsignedArray } from '../../web-gl/kernel-value/unsigned-array'; + +export 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]})`, + ]); + } +} diff --git a/src/backend/web-gl2/kernel-value/unsigned-input.js b/src/backend/web-gl2/kernel-value/unsigned-input.js index ed933347..7dddcb5f 100644 --- a/src/backend/web-gl2/kernel-value/unsigned-input.js +++ b/src/backend/web-gl2/kernel-value/unsigned-input.js @@ -1,17 +1,13 @@ -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 +import { utils } from '../../../utils'; +import { WebGLKernelValueUnsignedInput } from '../../web-gl/kernel-value/unsigned-input'; + +export 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]})`, + ]); + } +} diff --git a/src/backend/web-gl2/kernel.js b/src/backend/web-gl2/kernel.js index d27fdec8..d95a8660 100644 --- a/src/backend/web-gl2/kernel.js +++ b/src/backend/web-gl2/kernel.js @@ -1,685 +1,681 @@ -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; - -/** - * - * @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; - } - - static getFeatures() { - return Object.freeze({ - isFloatRead: this.getIsFloatRead(), - isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), - kernelMap: true, - isTextureFloat: true, - channelCount: this.getChannelCount(), - maxTextureSize: this.getMaxTextureSize(), - }); - } - - static getIsTextureFloat() { - return true; - } - - static getIsIntegerDivisionAccurate() { - return super.getIsIntegerDivisionAccurate(); - } - - 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; - } - - initContext() { - const settings = { - alpha: false, - depth: false, - antialias: false - }; - const context = this.canvas.getContext('webgl2', settings); - return context; - } - - 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.features; - 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'); - 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 } = this; - const gl = this.context; - - 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]); - - this.switchingKernels = false; - 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.outputTexture || this.immutable) { - this._setupOutputTexture(); - } - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - return new this.TextureConstructor({ - texture: this.outputTexture, - size: texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context - }); - } - 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._setupOutputTexture(); - } - - if (this.subKernels !== null) { - if (this.immutable) { - this._setupSubOutputTextures(); - } - gl.drawBuffers(this.drawBuffersMap); - } - - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - } - - drawBuffers() { - this.context.drawBuffers(this.drawBuffersMap); - } - - getOutputTexture() { - return this.outputTexture; - } - - _setupOutputTexture() { - const { texSize } = this; - const gl = this.context; - const texture = this.outputTexture = gl.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); - if (this.precision === 'single') { - if (this.pipeline) { - switch (this.returnType) { - case 'Number': - case 'Float': - case 'Integer': - if (this.optimizeFloatMemory) { - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); - } else { - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.R32F, texSize[0], texSize[1]); - } - break; - case 'Array(2)': - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RG32F, texSize[0], texSize[1]); - break; - case 'Array(3)': // there is _no_ 3 channel format which is guaranteed to be color-renderable - case 'Array(4)': - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); - break; - default: - throw new Error('Unhandled return type'); - } - } else { - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, 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, gl.TEXTURE_2D, texture, 0); - } - - _setupSubOutputTextures() { - const { texSize } = this; - const gl = this.context; - this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; - this.subKernelOutputTextures = []; - for (let i = 0; i < this.subKernels.length; i++) { - const texture = this.context.createTexture(); - this.subKernelOutputTextures.push(texture); - 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 - if (this.precision === 'single') { - 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); - } - } - - /** - * - * @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; - if (subKernels === null || subKernels.length < 1) { - switch (this.tactic) { - case 'speed': - return 'in lowp vec2 vTexCoord;\n'; - case 'performance': - return 'in highp vec2 vTexCoord;\n'; - case 'balanced': - default: - return 'in mediump vec2 vTexCoord;\n'; - } - } else { - switch (this.tactic) { - case 'speed': - return 'out lowp vec2 vTexCoord;\n'; - case 'performance': - return 'out highp vec2 vTexCoord;\n'; - case 'balanced': - default: - return 'out mediump 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() { - let kernelResultDeclaration; - switch (this.returnType) { - case 'Array(2)': - kernelResultDeclaration = 'vec2 kernelResult'; - break; - case 'Array(3)': - kernelResultDeclaration = 'vec3 kernelResult'; - break; - case 'Array(4)': - kernelResultDeclaration = 'vec4 kernelResult'; - break; - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - kernelResultDeclaration = 'float kernelResult'; - break; - default: - if (this.graphical) { - kernelResultDeclaration = 'float kernelResult'; - } else { - throw new Error(`unrecognized output type "${ this.returnType }"`); - } - } - - const result = []; - const subKernels = this.subKernels; - if (subKernels !== null) { - result.push( - kernelResultDeclaration, - 'layout(location = 0) out vec4 data0' - ); - 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 }` - ); - } - } else { - result.push( - 'out vec4 data0', - kernelResultDeclaration - ); - } - - 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); - } - - 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()', - ` 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(); - return json; - } -} - -module.exports = { - WebGL2Kernel -}; \ No newline at end of file +import { WebGLKernel } from '../web-gl/kernel'; +import { WebGL2FunctionNode } from './function-node'; +import { FunctionBuilder } from '../function-builder'; +import { utils } from '../../utils'; +import { fragmentShader } from './fragment-shader'; +import { vertexShader } from './vertex-shader'; +import { lookupKernelValueType } from './kernel-value-maps'; + +let isSupported = null; +let testCanvas = null; +let testContext = null; +let testExtensions = null; + +/** + * + * @type {IKernelFeatures} + */ +let features = null; + +/** + * @extends WebGLKernel + */ +export 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; + } + + static getFeatures() { + return Object.freeze({ + isFloatRead: this.getIsFloatRead(), + isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), + kernelMap: true, + isTextureFloat: true, + channelCount: this.getChannelCount(), + maxTextureSize: this.getMaxTextureSize(), + }); + } + + static getIsTextureFloat() { + return true; + } + + static getIsIntegerDivisionAccurate() { + return super.getIsIntegerDivisionAccurate(); + } + + 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; + } + + initContext() { + const settings = { + alpha: false, + depth: false, + antialias: false + }; + const context = this.canvas.getContext('webgl2', settings); + return context; + } + + 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.features; + 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'); + 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 } = this; + const gl = this.context; + + 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]); + + this.switchingKernels = false; + 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.outputTexture || this.immutable) { + this._setupOutputTexture(); + } + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + return new this.TextureConstructor({ + texture: this.outputTexture, + size: texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context + }); + } + 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._setupOutputTexture(); + } + + if (this.subKernels !== null) { + if (this.immutable) { + this._setupSubOutputTextures(); + } + gl.drawBuffers(this.drawBuffersMap); + } + + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + } + + drawBuffers() { + this.context.drawBuffers(this.drawBuffersMap); + } + + getOutputTexture() { + return this.outputTexture; + } + + _setupOutputTexture() { + const { texSize } = this; + const gl = this.context; + const texture = this.outputTexture = gl.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); + if (this.precision === 'single') { + if (this.pipeline) { + switch (this.returnType) { + case 'Number': + case 'Float': + case 'Integer': + if (this.optimizeFloatMemory) { + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); + } else { + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.R32F, texSize[0], texSize[1]); + } + break; + case 'Array(2)': + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RG32F, texSize[0], texSize[1]); + break; + case 'Array(3)': // there is _no_ 3 channel format which is guaranteed to be color-renderable + case 'Array(4)': + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); + break; + default: + throw new Error('Unhandled return type'); + } + } else { + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, 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, gl.TEXTURE_2D, texture, 0); + } + + _setupSubOutputTextures() { + const { texSize } = this; + const gl = this.context; + this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; + this.subKernelOutputTextures = []; + for (let i = 0; i < this.subKernels.length; i++) { + const texture = this.context.createTexture(); + this.subKernelOutputTextures.push(texture); + 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 + if (this.precision === 'single') { + 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); + } + } + + /** + * + * @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; + if (subKernels === null || subKernels.length < 1) { + switch (this.tactic) { + case 'speed': + return 'in lowp vec2 vTexCoord;\n'; + case 'performance': + return 'in highp vec2 vTexCoord;\n'; + case 'balanced': + default: + return 'in mediump vec2 vTexCoord;\n'; + } + } else { + switch (this.tactic) { + case 'speed': + return 'out lowp vec2 vTexCoord;\n'; + case 'performance': + return 'out highp vec2 vTexCoord;\n'; + case 'balanced': + default: + return 'out mediump 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() { + let kernelResultDeclaration; + switch (this.returnType) { + case 'Array(2)': + kernelResultDeclaration = 'vec2 kernelResult'; + break; + case 'Array(3)': + kernelResultDeclaration = 'vec3 kernelResult'; + break; + case 'Array(4)': + kernelResultDeclaration = 'vec4 kernelResult'; + break; + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + kernelResultDeclaration = 'float kernelResult'; + break; + default: + if (this.graphical) { + kernelResultDeclaration = 'float kernelResult'; + } else { + throw new Error(`unrecognized output type "${ this.returnType }"`); + } + } + + const result = []; + const subKernels = this.subKernels; + if (subKernels !== null) { + result.push( + kernelResultDeclaration, + 'layout(location = 0) out vec4 data0' + ); + 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 }` + ); + } + } else { + result.push( + 'out vec4 data0', + kernelResultDeclaration + ); + } + + 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); + } + + 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()', + ` 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(); + return json; + } +} diff --git a/src/backend/web-gl2/vertex-shader.js b/src/backend/web-gl2/vertex-shader.js index e44dc986..5b65a0bb 100644 --- a/src/backend/web-gl2/vertex-shader.js +++ b/src/backend/web-gl2/vertex-shader.js @@ -1,20 +1,16 @@ -// 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 +// language=GLSL +export 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; +}`; diff --git a/src/base-gpu.js b/src/base-gpu.js new file mode 100644 index 00000000..be3e0921 --- /dev/null +++ b/src/base-gpu.js @@ -0,0 +1,577 @@ +import { gpuMock } from 'gpu-mock.js'; +import { CPUKernel } from './backend/cpu/kernel'; +import { WebGL2Kernel } from './backend/web-gl2/kernel'; +import { WebGLKernel } from './backend/web-gl/kernel'; +import { kernelRunShortcut } from './kernel-run-shortcut'; +import { + functionToIFunction, + getFunctionNameFromString, + isFunction, + warnDeprecated +} from './common'; +import { getVariableType } from './utils'; + +/** + * @type {Kernel[]} + */ +const kernelOrder = [ WebGL2Kernel, WebGLKernel ]; + +/** + * @type {string[]} + */ +const kernelTypes = [ 'gpu', 'cpu' ]; + +const internalKernels = { + 'webgl2': WebGL2Kernel, + 'webgl': WebGLKernel, +}; + +let validate = true; + +/** + * The GPU.js library class which manages the GPU context for the creating kernels + */ +export 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 false; + } + + /** + * + * @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(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) { + this.addNativeFunction(p, settings.nativeFunctions[p]); + } + } + } + + getValidate() { + return validate; + } + + /** + * Choose kernel type and save on .Kernel property of GPU + */ + 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; + } + + /** + * @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 {Object} [settings] - The parameter configuration object + * @return {Kernel} callable function to run + */ + createKernel(source, settings) { + if (typeof source === 'undefined') { + throw new Error('Missing source parameter'); + } + if (typeof source !== 'object' && !isFunction(source) && typeof source !== 'string') { + throw new Error('source parameter not a function'); + } + + if (this.mode === 'dev') { + const devKernel = gpuMock(source, upgradeDeprecatedCreateKernelSettings(settings)); + this.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) { + 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, + warnVarUsage: kernelRun.warnVarUsage, + }); + fallbackKernel.build.apply(fallbackKernel, args); + const result = fallbackKernel.run.apply(fallbackKernel, args); + kernelRun.replaceKernel(fallbackKernel); + return result; + } + + function onRequestSwitchKernel(args, kernel) { + 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] = getVariableType(arg); + break; + default: + argumentTypes[i] = type; + } + } + } + const signature = argumentTypes.join(','); + const existingKernel = switchableKernels[signature]; + if (existingKernel) { + existingKernel.run.apply(existingKernel, args); + if (existingKernel.renderKernels) { + return existingKernel.renderKernels(); + } else { + return existingKernel.renderOutput(); + } + } + + const newKernel = switchableKernels[signature] = new kernel.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: 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, + warnVarUsage: kernel.warnVarUsage, + returnType: kernel.returnType, + onRequestFallback, + onRequestSwitchKernel, + }); + newKernel.build.apply(newKernel, args); + newKernel.run.apply(newKernel, args); + kernelRun.replaceKernel(newKernel); + if (newKernel.renderKernels) { + return newKernel.renderKernels(); + } else { + return newKernel.renderOutput(); + } + } + 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 kernelRun = kernelRunShortcut(new this.Kernel(source, mergedSettings)); + + //if canvas didn't come from this, propagate from kernel + if (!this.canvas) { + this.canvas = kernelRun.canvas; + } + + //if context didn't come from this, propagate from kernel + if (!this.context) { + this.context = kernelRun.context; + } + + this.kernels.push(kernelRun); + + 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; + if (typeof arguments[arguments.length - 2] === 'function') { + 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 = 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 = getFunctionNameFromString(source); + settingsCopy.subKernels.push({ + name: name || p, + source, + property: p, + }); + } + } + const kernel = this.createKernel(fn, settingsCopy); + + 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. + * + * @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; + }; + } + + /** + * @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(functionToIFunction(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.'); + } + settings = settings || {}; + const { argumentTypes, argumentNames } = this.Kernel.nativeFunctionArguments(source) || {}; + this.nativeFunctions.push({ + name, + source, + settings, + argumentTypes, + argumentNames, + returnType: settings.returnType || this.Kernel.nativeFunctionReturnType(source), + }); + 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 + */ + destroy() { + if (!this.kernels) return; + // 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(() => { + 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); + } + } + }, 0); + } +} + +function upgradeDeprecatedCreateKernelSettings(settings) { + if (!settings) { + return {}; + } + const upgradedSettings = Object.assign({}, settings); + + if (settings.hasOwnProperty('floatOutput')) { + warnDeprecated('setting', 'floatOutput', 'precision'); + upgradedSettings.precision = settings.floatOutput ? 'single' : 'unsigned'; + } + if (settings.hasOwnProperty('outputToTexture')) { + warnDeprecated('setting', 'outputToTexture', 'pipeline'); + upgradedSettings.pipeline = Boolean(settings.outputToTexture); + } + if (settings.hasOwnProperty('outputImmutable')) { + warnDeprecated('setting', 'outputImmutable', 'immutable'); + upgradedSettings.immutable = Boolean(settings.outputImmutable); + } + if (settings.hasOwnProperty('floatTextures')) { + warnDeprecated('setting', 'floatTextures', 'optimizeFloatMemory'); + upgradedSettings.optimizeFloatMemory = Boolean(settings.floatTextures); + } + return upgradedSettings; +} diff --git a/src/browser-header.txt b/src/browser-header.txt deleted file mode 100644 index ef9d7f8a..00000000 --- a/src/browser-header.txt +++ /dev/null @@ -1,14 +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 - */ \ No newline at end of file diff --git a/src/browser.js b/src/browser.js index ffea4a6f..9178f497 100644 --- a/src/browser.js +++ b/src/browser.js @@ -1,8 +1,70 @@ -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]; -} -module.exports = GPU; \ No newline at end of file +import { GPU } from './base-gpu'; +import { alias } from './alias'; +import { utils } from './utils'; +import * as common from './common'; +import { Input, input } from './input'; +import { Texture } from './texture'; +import { FunctionBuilder } from './backend/function-builder'; +import { FunctionNode } from './backend/function-node'; +import { CPUFunctionNode } from './backend/cpu/function-node'; +import { CPUKernel } from './backend/cpu/kernel'; +import { WebGLFunctionNode } from './backend/web-gl/function-node'; +import { WebGLKernel } from './backend/web-gl/kernel'; +import { WebGL2FunctionNode } from './backend/web-gl2/function-node'; +import { WebGL2Kernel } from './backend/web-gl2/kernel'; +import { GLKernel } from './backend/gl/kernel'; +import { Kernel } from './backend/kernel'; + +/** + * Stub for HeadlessGL. + */ +class HeadlessGLKernel extends WebGLKernel { + static get isSupported() { return false } + static isContextMatch() { return false } + static getIsTextureFloat() { return false } + static getIsDrawBuffers() { return false } + static getChannelCount() { return 1 } + static get testCanvas() { return null } + static get testContext() { return null } + static get features() { return null } + static setupFeatureChecks() {} + static destroyContext() {} + initCanvas() { return {} } + initContext() { return null } + toString() { return '' } + initExtensions() {} + build() {} + destroyExtensions() {} + setOutput() {} + + static getFeatures() { + return Object.freeze({ + isFloatRead: false, + isIntegerDivisionAccurate: false, + isTextureFloat: false, + isDrawBuffers: false, + kernelMap: false, + channelCount: 1, + }); + } +}; + +const lib = GPU; +lib.alias = alias; +lib.CPUFunctionNode = CPUFunctionNode; +lib.CPUKernel = CPUKernel; +lib.FunctionBuilder = FunctionBuilder; +lib.FunctionNode = FunctionNode; +lib.HeadlessGLKernel = HeadlessGLKernel; +lib.Input = Input; +lib.input = input; +lib.Texture = Texture; +lib.utils = { ...common, ...utils }; +lib.WebGL2FunctionNode = WebGL2FunctionNode; +lib.WebGL2Kernel = WebGL2Kernel; +lib.WebGLFunctionNode = WebGLFunctionNode; +lib.WebGLKernel = WebGLKernel; +lib.GLKernel = GLKernel; +lib.Kernel = Kernel; + +export default lib; diff --git a/src/common.js b/src/common.js new file mode 100644 index 00000000..a780f77b --- /dev/null +++ b/src/common.js @@ -0,0 +1,139 @@ +/** + * @fileoverview Branch of utils to prevent circular dependencies. + */ + +const ARGUMENT_NAMES = /([^\s,]+)/g; +const FUNCTION_NAME = /function ([^(]*)/; +const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; + +/** + * @descReturn 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 + */ +export function isFunction(funcObj) { + return typeof(funcObj) === 'function'; +}; + +/** + * @desc 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) + */ +export function getFunctionNameFromString(funcStr) { + return FUNCTION_NAME.exec(funcStr)[1].trim(); +}; + +/** + * + * @param {String|Function} source + * @param {IFunctionSettings} [settings] + * @returns {IFunction} + */ +export function functionToIFunction(source, settings) { + settings = 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 = getArgumentNamesFromString(sourceString) + .map(name => settings.argumentTypes[name]) || []; + } else { + argumentTypes = settings.argumentTypes || []; + } + + return { + source: sourceString, + argumentTypes, + returnType: settings.returnType || null, + }; +}; + +export function warnDeprecated(type, oldName, newName) { + const msg = newName + ? `It has been replaced with "${ newName }"` + : 'It has been removed'; + console.warn(`You are using a deprecated ${ type } "${ oldName }". ${msg}. Fixing, but please upgrade as it will soon be removed.`) +}; + +/** + * @desc Return TRUE, on a valid JS function string + * Note: This does just a VERY simply sanity check. And may give false positives. + * + * @param {String} fn - String of JS function to validate + * @returns {Boolean} TRUE if the string passes basic validation + */ +export function isFunctionString(fn) { + if (typeof fn === 'string') { + return (fn + .slice(0, 'function'.length) + .toLowerCase() === 'function'); + } + return false; +}; + +/** + * @desc Return list of argument names extracted from a javascript function + * @param {String} fn - String of JS function to validate + * @returns {String[]} Array representing all the parameter names + */ +export function 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; +}; + +/** + * @desc Checks if is an array or Array-like object + * @param {Object} array - The argument object to check if is array + * @returns {Boolean} true if is array or Array-like object + */ +export function isArray(array) { + return !isNaN(array.length); +}; + +export function 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; +}; + +export function 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; +}; + +export function 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'); +}; diff --git a/src/gpu.js b/src/gpu.js index 12e3b768..24ab8e9a 100644 --- a/src/gpu.js +++ b/src/gpu.js @@ -1,579 +1,81 @@ -const { gpuMock } = require('gpu-mock.js'); -const { utils } = require('./utils'); -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 {Kernel[]} - */ -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 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(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) { - this.addNativeFunction(p, settings.nativeFunctions[p]); - } - } - } - - /** - * Choose kernel type and save on .Kernel property of GPU - */ - 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; - } - - /** - * @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 {Object} [settings] - The parameter configuration object - * @return {Kernel} 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'); - } - - if (this.mode === 'dev') { - const devKernel = gpuMock(source, upgradeDeprecatedCreateKernelSettings(settings)); - this.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) { - 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, - warnVarUsage: kernelRun.warnVarUsage, - }); - fallbackKernel.build.apply(fallbackKernel, args); - const result = fallbackKernel.run.apply(fallbackKernel, args); - kernelRun.replaceKernel(fallbackKernel); - return result; - } - - function onRequestSwitchKernel(args, kernel) { - 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; - } - } - } - const signature = argumentTypes.join(','); - const existingKernel = switchableKernels[signature]; - if (existingKernel) { - existingKernel.run.apply(existingKernel, args); - if (existingKernel.renderKernels) { - return existingKernel.renderKernels(); - } else { - return existingKernel.renderOutput(); - } - } - - const newKernel = switchableKernels[signature] = new kernel.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: 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, - warnVarUsage: kernel.warnVarUsage, - returnType: kernel.returnType, - onRequestFallback, - onRequestSwitchKernel, - }); - newKernel.build.apply(newKernel, args); - newKernel.run.apply(newKernel, args); - kernelRun.replaceKernel(newKernel); - if (newKernel.renderKernels) { - return newKernel.renderKernels(); - } else { - return newKernel.renderOutput(); - } - } - 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 kernelRun = kernelRunShortcut(new this.Kernel(source, mergedSettings)); - - //if canvas didn't come from this, propagate from kernel - if (!this.canvas) { - this.canvas = kernelRun.canvas; - } - - //if context didn't come from this, propagate from kernel - if (!this.context) { - this.context = kernelRun.context; - } - - this.kernels.push(kernelRun); - - 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; - if (typeof arguments[arguments.length - 2] === 'function') { - 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, - }); - } - } - const kernel = this.createKernel(fn, settingsCopy); - - 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. - * - * @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; - }; - } - - /** - * @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(utils.functionToIFunction(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.'); - } - settings = settings || {}; - const { argumentTypes, argumentNames } = this.Kernel.nativeFunctionArguments(source) || {}; - this.nativeFunctions.push({ - name, - source, - settings, - argumentTypes, - argumentNames, - returnType: settings.returnType || this.Kernel.nativeFunctionReturnType(source), - }); - 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 - */ - destroy() { - if (!this.kernels) return; - // 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(() => { - 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); - } - } - }, 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 +import { GPU as BaseGPU } from './base-gpu'; +import { HeadlessGLKernel } from './backend/headless-gl/kernel'; +import { CPUKernel } from './backend/cpu/kernel'; + +/** + * Extends the BaseGPU class to cover HeadlessGL instead of WebGL. + */ +export class GPU extends BaseGPU { + static get isGPUSupported() { + return HeadlessGLKernel.isSupported; + } + + static get isKernelMapSupported() { + return HeadlessGLKernel.isSupported && HeadlessGLKernel.features.kernelMap; + } + + static get isSinglePrecisionSupported() { + return HeadlessGLKernel.isSupported + && HeadlessGLKernel.features.isFloatRead + && HeadlessGLKernel.features.isTextureFloat; + } + + static get isWebGLSupported() { + return false; + } + + static get isWebGL2Supported() { + return false; + } + + static get isHeadlessGLSupported() { + return HeadlessGLKernel.isSupported; + } + + static get isGPUHTMLImageArraySupported() { + return false; + } + + chooseKernel() { + if (this.Kernel) return; + + let Kernel = null; + + if (this.context) { + if (HeadlessGLKernel.isContextMatch(this.context)) { + if (!HeadlessGLKernel.isSupported) { + throw new Error(`Kernel type ${HeadlessGLKernel.name} not supported`); + } + Kernel = HeadlessGLKernel; + } + if (Kernel === null) { + throw new Error('unknown Context'); + } + } else if (this.mode) { + if (this.mode === 'headlessgl') { + if (!this.getValidate() || HeadlessGLKernel.isSupported) { + Kernel = HeadlessGLKernel; + } + } else if (this.mode === 'gpu') { + if (HeadlessGLKernel.isSupported) { + Kernel = HeadlessGLKernel; + } + } else if (this.mode === 'cpu') { + Kernel = CPUKernel; + } + + if (!Kernel) { + throw new Error(`A requested mode of "${this.mode}" and is not supported`); + } + } else { + Kernel = HeadlessGLKernel.isSupported ? HeadlessGLKernel : CPUKernel; + } + + if (!this.mode) { + this.mode = Kernel.mode; + } + this.Kernel = Kernel; + } + + +}; diff --git a/src/index.js b/src/index.js index 95302ea9..9a8bd3c3 100644 --- a/src/index.js +++ b/src/index.js @@ -1,51 +1,45 @@ -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'); - -module.exports = { - alias, - CPUFunctionNode, - CPUKernel, - GPU, - FunctionBuilder, - FunctionNode, - HeadlessGLKernel, - Input, - input, - Texture, - utils, - - WebGL2FunctionNode, - WebGL2Kernel, - webGL2KernelValueMaps, - - WebGLFunctionNode, - WebGLKernel, - webGLKernelValueMaps, - - GLKernel, - Kernel, - FunctionTracer, -}; \ No newline at end of file +import { GPU } from './gpu'; +import { alias } from './alias'; +import * as common from './common'; +import { utils as util } from './utils'; +import { Input, input } from './input'; +import { Texture } from './texture'; +import { FunctionBuilder } from './backend/function-builder'; +import { FunctionNode } from './backend/function-node'; +import { CPUFunctionNode } from './backend/cpu/function-node'; +import { CPUKernel } from './backend/cpu/kernel'; +import { HeadlessGLKernel } from './backend/headless-gl/kernel'; +import { WebGLFunctionNode } from './backend/web-gl/function-node'; +import { WebGLKernel } from './backend/web-gl/kernel'; +import { WebGL2FunctionNode } from './backend/web-gl2/function-node'; +import { WebGL2Kernel } from './backend/web-gl2/kernel'; +import { GLKernel } from './backend/gl/kernel'; +import { Kernel } from './backend/kernel'; +import { kernelValueMaps as webGLKernelValueMaps } from './backend/web-gl/kernel-value-maps'; +import { kernelValueMaps as webGL2KernelValueMaps } from './backend/web-gl2/kernel-value-maps'; +import { FunctionTracer } from './backend/function-tracer'; + +const utils = { ...common, ...util }; + +export { + alias, + CPUFunctionNode, + CPUKernel, + GPU, + FunctionBuilder, + FunctionNode, + HeadlessGLKernel, + Input, + input, + Texture, + utils, + WebGL2FunctionNode, + WebGL2Kernel, + webGL2KernelValueMaps, + WebGLFunctionNode, + WebGLKernel, + webGLKernelValueMaps, + GLKernel, + Kernel, + FunctionTracer, +}; diff --git a/src/input.js b/src/input.js index 12f0c252..1b959487 100644 --- a/src/input.js +++ b/src/input.js @@ -1,54 +1,50 @@ -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 -}; \ No newline at end of file +import { erectMemoryOptimized2DFloat, erectMemoryOptimized3DFloat } from './common'; + +export 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 [ w, h, d ] = this.size; + if (d) { + return erectMemoryOptimized3DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h, d); + } else if (h) { + return erectMemoryOptimized2DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h); + } else { + return this.value; + } + } +}; + +export function input(value, size) { + return new Input(value, size); +}; diff --git a/src/kernel-run-shortcut.js b/src/kernel-run-shortcut.js index 3739d0c7..88b41077 100644 --- a/src/kernel-run-shortcut.js +++ b/src/kernel-run-shortcut.js @@ -1,95 +1,92 @@ -const { utils } = require('./utils'); - -/** - * Makes kernels easier for mortals (including me) - * @param kernel - * @returns {function()} - */ -function kernelRunShortcut(kernel) { - let run = function() { - kernel.build.apply(kernel, arguments); - if (kernel.renderKernels) { - run = function() { - kernel.run.apply(kernel, arguments); - if (kernel.switchingKernels) { - kernel.switchingKernels = false; - return kernel.onRequestSwitchKernel(arguments, kernel); - } - return kernel.renderKernels(); - }; - } else if (kernel.renderOutput) { - run = function() { - kernel.run.apply(kernel, arguments); - if (kernel.switchingKernels) { - kernel.switchingKernels = false; - return kernel.onRequestSwitchKernel(arguments, kernel); - } - return kernel.renderOutput(); - }; - } else { - run = function() { - return kernel.run.apply(kernel, arguments); - }; - } - return run.apply(kernel, arguments); - }; - const shortcut = function() { - return run.apply(kernel, arguments); - }; - /** - * Run kernel in async mode - * @returns {Promise} - */ - 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); - shortcut.kernel = kernel; - }; - - bindKernelToShortcut(kernel, shortcut); - shortcut.kernel = kernel; - return shortcut; -} - -function bindKernelToShortcut(kernel, shortcut) { - 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() { - kernel[property].apply(kernel, arguments); - return shortcut; - }; - } else { - if (property === 'toString') { - shortcut.toString = function() { - return kernel.toString.apply(kernel, arguments); - }; - } else { - shortcut[property] = kernel[property].bind(kernel); - } - } - } else { - shortcut.__defineGetter__(property, () => { - return kernel[property]; - }); - shortcut.__defineSetter__(property, (value) => { - kernel[property] = value; - }); - } - } -} -module.exports = { - kernelRunShortcut -}; \ No newline at end of file +import { utils } from './utils'; + +/** + * Makes kernels easier for mortals (including me) + * @param kernel + * @returns {function()} + */ +export function kernelRunShortcut(kernel) { + let run = function() { + kernel.build.apply(kernel, arguments); + if (kernel.renderKernels) { + run = function() { + kernel.run.apply(kernel, arguments); + if (kernel.switchingKernels) { + kernel.switchingKernels = false; + return kernel.onRequestSwitchKernel(arguments, kernel); + } + return kernel.renderKernels(); + }; + } else if (kernel.renderOutput) { + run = function() { + kernel.run.apply(kernel, arguments); + if (kernel.switchingKernels) { + kernel.switchingKernels = false; + return kernel.onRequestSwitchKernel(arguments, kernel); + } + return kernel.renderOutput(); + }; + } else { + run = function() { + return kernel.run.apply(kernel, arguments); + }; + } + return run.apply(kernel, arguments); + }; + const shortcut = function() { + return run.apply(kernel, arguments); + }; + /** + * Run kernel in async mode + * @returns {Promise} + */ + 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); + shortcut.kernel = kernel; + }; + + bindKernelToShortcut(kernel, shortcut); + shortcut.kernel = kernel; + return shortcut; +} + +function bindKernelToShortcut(kernel, shortcut) { + 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() { + kernel[property].apply(kernel, arguments); + return shortcut; + }; + } else { + if (property === 'toString') { + shortcut.toString = function() { + return kernel.toString.apply(kernel, arguments); + }; + } else { + shortcut[property] = kernel[property].bind(kernel); + } + } + } else { + shortcut.__defineGetter__(property, () => { + return kernel[property]; + }); + shortcut.__defineSetter__(property, (value) => { + kernel[property] = value; + }); + } + } +} diff --git a/src/plugins/triangle-noise.js b/src/plugins/triangle-noise.js index cc2972e2..6d23f5f8 100644 --- a/src/plugins/triangle-noise.js +++ b/src/plugins/triangle-noise.js @@ -1,53 +1,52 @@ -const source = ` - -uniform highp float triangle_noise_seed; -highp float triangle_noise_shift = 0.000001; - -//https://www.shadertoy.com/view/4t2SDh -//note: uniformly distributed, normalized rand, [0;1[ -float nrand( vec2 n ) -{ - return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453); -} -//note: remaps v to [0;1] in interval [a;b] -float remap( float a, float b, float v ) -{ - return clamp( (v-a) / (b-a), 0.0, 1.0 ); -} - -float n4rand( vec2 n ) -{ - float t = fract( triangle_noise_seed + triangle_noise_shift ); - float nrnd0 = nrand( n + 0.07*t ); - float nrnd1 = nrand( n + 0.11*t ); - float nrnd2 = nrand( n + 0.13*t ); - float nrnd3 = nrand( n + 0.17*t ); - float result = (nrnd0+nrnd1+nrnd2+nrnd3) / 4.0; - triangle_noise_shift = result + 0.000001; - return result; -}`; - -const name = 'triangle-noise-noise'; - -const functionMatch = 'Math.random()'; - -const functionReplace = 'n4rand(vTexCoord)'; - -const functionReturnType = 'Number'; - -const onBeforeRun = (kernel) => { - kernel.setUniform1f('triangle_noise_seed', Math.random()); -}; - -/** - * - * @type IPlugin - */ -module.exports = { - name, - onBeforeRun, - functionMatch, - functionReplace, - functionReturnType, - source -}; \ No newline at end of file +const source = ` + +uniform highp float triangle_noise_seed; +highp float triangle_noise_shift = 0.000001; + +//https://www.shadertoy.com/view/4t2SDh +//note: uniformly distributed, normalized rand, [0;1[ +float nrand( vec2 n ) +{ + return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453); +} +//note: remaps v to [0;1] in interval [a;b] +float remap( float a, float b, float v ) +{ + return clamp( (v-a) / (b-a), 0.0, 1.0 ); +} + +float n4rand( vec2 n ) +{ + float t = fract( triangle_noise_seed + triangle_noise_shift ); + float nrnd0 = nrand( n + 0.07*t ); + float nrnd1 = nrand( n + 0.11*t ); + float nrnd2 = nrand( n + 0.13*t ); + float nrnd3 = nrand( n + 0.17*t ); + float result = (nrnd0+nrnd1+nrnd2+nrnd3) / 4.0; + triangle_noise_shift = result + 0.000001; + return result; +}`; + +const name = 'triangle-noise-noise'; + +const functionMatch = 'Math.random()'; + +const functionReplace = 'n4rand(vTexCoord)'; + +const functionReturnType = 'Number'; + +const onBeforeRun = (kernel) => { + kernel.setUniform1f('triangle_noise_seed', Math.random()); +}; + +/** + * @type IPlugin + */ +export default { + name, + onBeforeRun, + functionMatch, + functionReplace, + functionReturnType, + source +}; diff --git a/src/texture.js b/src/texture.js index f7a192c9..1d4c99fe 100644 --- a/src/texture.js +++ b/src/texture.js @@ -1,44 +1,40 @@ -/** - * @desc WebGl Texture implementation in JS - * @param {ITextureSettings} settings - */ -class Texture { - constructor(settings) { - const { - texture, - size, - dimensions, - output, - context, - type = 'NumberTexture', - } = settings; - if (!output) throw new Error('settings property "output" required.'); - if (!context) throw new Error('settings property "context" required.'); - this.texture = texture; - this.size = size; - this.dimensions = dimensions; - this.output = output; - this.context = context; - this.kernel = null; - this.type = type; - } - - /** - * @desc Converts the Texture into a JavaScript Array - * @returns {Number[]|Number[][]|Number[][][]} - */ - toArray() { - throw new Error(`Not implemented on ${this.constructor.name}`); - } - - /** - * @desc Deletes the Texture - */ - delete() { - return this.context.deleteTexture(this.texture); - } -} - -module.exports = { - Texture -}; \ No newline at end of file +/** + * @desc WebGl Texture implementation in JS + * @param {ITextureSettings} settings + */ +export class Texture { + constructor(settings) { + const { + texture, + size, + dimensions, + output, + context, + type = 'NumberTexture', + } = settings; + if (!output) throw new Error('settings property "output" required.'); + if (!context) throw new Error('settings property "context" required.'); + this.texture = texture; + this.size = size; + this.dimensions = dimensions; + this.output = output; + this.context = context; + this.kernel = null; + this.type = type; + } + + /** + * @desc Converts the Texture into a JavaScript Array + * @returns {Number[]|Number[][]|Number[][][]} + */ + toArray() { + throw new Error(`Not implemented on ${this.constructor.name}`); + } + + /** + * @desc Deletes the Texture + */ + delete() { + return this.context.deleteTexture(this.texture); + } +}; diff --git a/src/utils.js b/src/utils.js index d840c333..b2beaec9 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,899 +1,691 @@ -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; - -/** - * - * @desc 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) - */ -const utils = { - /** - * - * @desc Gets the system endianness, and cache it - * @returns {String} 'LE' or 'BE' depending on system architecture - * Credit: https://gist.github.com/TooTallNate/4750953 - */ - 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'); - }, - - /** - * @descReturn 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 - */ - isFunction(funcObj) { - return typeof(funcObj) === 'function'; - }, - - /** - * @desc Return TRUE, on a valid JS function string - * Note: This does just a VERY simply sanity check. And may give false positives. - * - * @param {String} fn - String of JS function to validate - * @returns {Boolean} TRUE if the string passes basic validation - */ - isFunctionString(fn) { - if (typeof fn === 'string') { - return (fn - .slice(0, 'function'.length) - .toLowerCase() === 'function'); - } - return false; - }, - - /** - * @desc 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) - */ - getFunctionNameFromString(funcStr) { - return FUNCTION_NAME.exec(funcStr)[1].trim(); - }, - - getFunctionBodyFromString(funcStr) { - return funcStr.substring(funcStr.indexOf('{') + 1, funcStr.lastIndexOf('}')); - }, - - /** - * @desc Return list of argument names extracted from a javascript function - * @param {String} fn - String of JS function to validate - * @returns {String[]} Array representing all the parameter names - */ - 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; - }, - - /** - * @desc Returns a clone - * @param {Object} obj - Object to clone - * @returns {Object|Array} Cloned object - */ - 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; - }, - - /** - * @desc Checks if is an array or Array-like object - * @param {Object} array - The argument object to check if is array - * @returns {Boolean} true if is array or Array-like object - */ - isArray(array) { - return !isNaN(array.length); - }, - - /** - * @desc Evaluate the argument type, to apply respective logic for it - * @param {Object} value - The argument object to evaluate type - * @returns {String} Argument type Array/Number/Float/Texture/Unknown - */ - 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'; - } - switch (value.nodeName) { - case 'IMG': - return 'HTMLImage'; - case 'VIDEO': - return 'HTMLVideo'; - } - if (value.hasOwnProperty('type')) { - return value.type; - } - 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 given dimensions == a 2d image - if (h > 1 && w * h === texelCount) { - return new Int32Array([w, h]); - } - return utils.closestSquareDimensions(texelCount); - }, - - /** - * - * @param {Number} length - * @returns {TextureDimensions} - */ - 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)]); - }, - - /** - * A texture takes up four - * @param {OutputDimensions} dimensions - * @param {Number} bitRatio - * @returns {TextureDimensions} - */ - 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); - }, - - /** - * - * @param dimensions - * @param bitRatio - * @returns {*|TextureDimensions} - */ - 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; - }, - /** - * @desc Return the dimension of an array. - * @param {Array|String|Texture|Input} x - The array - * @param {Boolean} [pad] - To include padding in the dimension calculation - * @returns {OutputDimensions} - */ - 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); - }, - - /** - * Puts a nested 2d array into a one-dimensional target array - * @param {Array|*} array - * @param {Float32Array|Float64Array} target - */ - flatten2dArrayTo(array, target) { - let offset = 0; - for (let y = 0; y < array.length; y++) { - target.set(array[y], offset); - offset += array[y].length; - } - }, - - /** - * Puts a nested 3d array into a one-dimensional target array - * @param {Array|*} array - * @param {Float32Array|Float64Array} target - */ - 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; - } - } - }, - - /** - * Puts a nested 4d array into a one-dimensional target array - * @param {Array|*} array - * @param {Float32Array|Float64Array} target - */ - 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; - } - } - } - }, - - /** - * Puts a nested 1d, 2d, or 3d array into a one-dimensional target array - * @param {Float32Array|Uint16Array|Uint8Array} array - * @param {Float32Array} target - */ - 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); - } - }, - - /** - * - * @desc Splits an array into smaller arrays. - * Number of elements in one small chunk is given by `part` - * - * @param {Number[]} array - The array to split into chunks - * @param {Number} part - elements in one chunk - * - * @returns {Number[]} An array of smaller chunks - */ - 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; - }, - - /** - * @param {Array} lines - An Array of strings - * @returns {String} Single combined String, separated by *\n* - */ - 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.`); - } - }, - /** - * - * @param {String|Function} source - * @param {IFunctionSettings} [settings] - * @returns {IFunction} - */ - functionToIFunction(source, settings) { - settings = 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 { - source: sourceString, - argumentTypes, - returnType: settings.returnType || null, - }; - }, - flipPixels: (pixels, width, height) => { - // https://stackoverflow.com/a/41973289/1324039 - const halfHeight = height / 2 | 0; // the | 0 keeps the result an int - const bytesPerRow = width * 4; - // make a temp buffer to hold one row - 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; - - // make copy of a row on the top half - temp.set(result.subarray(topOffset, topOffset + bytesPerRow)); - - // copy a row from the bottom half to the top - result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow); - - // copy the copy of the top half row to the bottom half - 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; - }, - - /** - * - * @param {String} source - * @param {Object} settings - * @return {String} - */ - flattenFunctionToString: (source, settings) => { - const { findDependency, thisLookup, doNotDefine } = settings; - let flattened = settings.flattened; - if (!flattened) { - flattened = settings.flattened = {}; - } - const ast = acorn.parse(source); - const functionDependencies = []; - - 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); - case 'FunctionDeclaration': - return `function ${ast.id.name}(${ast.params.map(flatten).join(', ')}) ${ flatten(ast.body) }`; - case 'BlockStatement': { - const result = []; - for (let i = 0; i < ast.body.length; i++) { - result.push(flatten(ast.body[i]), ';\n'); - } - return `{\n${result.join('')}}`; - } - case 'VariableDeclaration': - switch (ast.declarations[0].id.type) { - case 'ObjectPattern': { - const source = flatten(ast.declarations[0].init); - const properties = ast.declarations.map(declaration => declaration.id.properties.map(flatten))[0]; - if (/this/.test(source)) { - const result = []; - const lookups = properties.map(thisLookup); - for (let i = 0; i < lookups.length; i++) { - const lookup = lookups[i]; - if (lookup === null) continue; - const property = properties[i]; - result.push(`${ast.kind} ${ property } = ${ lookup };\n`); - } - - return result.join(''); - } - return `${ast.kind} { ${properties} } = ${source}`; - } - case 'ArrayPattern': - return `${ast.kind} [ ${ ast.declarations.map(declaration => flatten(declaration.id)).join(', ') } ] = ${flatten(ast.declarations[0].init)}`; - } - if (doNotDefine && doNotDefine.indexOf(ast.declarations[0].id.name) !== -1) { - return ''; - } - return `${ast.kind} ${ast.declarations[0].id.name} = ${flatten(ast.declarations[0].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) { - // we're not flattening it - return `${ast.callee.object.name}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; - } else { - functionDependencies.push(foundSource); - // we're flattening it - 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 '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; - } - flattenedFunctionDependencies.push(utils.flattenFunctionToString(functionDependency, settings) + ';\n'); - } - return flattenedFunctionDependencies.join('') + result; - } - return result; - }, - - splitHTMLImageToRGB: (image, mode) => { - const gpu = new GPU({ mode }); - - 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: ['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: ['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: ['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: ['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; - }, - - /** - * A visual debug utility - * @param rgba - * @param width - * @param height - * @param mode - * @return {Object[]} - */ - splitRGBAToCanvases: (rgba, width, height, mode) => { - const { GPU } = require('./gpu.js'); - - const visualGPUR = new GPU({ mode }); - const visualKernelR = visualGPUR.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 visualGPUG = new GPU({ mode }); - const visualKernelG = visualGPUG.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 visualGPUB = new GPU({ mode }); - const visualKernelB = visualGPUB.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 visualGPUA = new GPU({ mode }); - const visualKernelA = visualGPUA.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); - - visualGPUR.destroy(); - visualGPUG.destroy(); - visualGPUB.destroy(); - visualGPUA.destroy(); - - return [ - visualKernelR.canvas, - visualKernelG.canvas, - visualKernelB.canvas, - visualKernelA.canvas, - ]; - } -}; - -const _systemEndianness = utils.getSystemEndianness(); - -module.exports = { - utils -}; \ No newline at end of file +import { parse } from 'acorn'; +import { Texture } from './texture'; +import { Input } from './input'; +import { + getAstString, + erectMemoryOptimized2DFloat, + erectMemoryOptimized3DFloat, + functionToIFunction, + getArgumentNamesFromString, + getFunctionNameFromString, + isArray, + isFunction, + isFunctionString, + warnDeprecated +} from './common'; + +export function 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'); +}; + +const _systemEndianness = getSystemEndianness(); + +/** + * + * @desc Gets the system endianness, and cache it + * @returns {String} 'LE' or 'BE' depending on system architecture + * Credit: https://gist.github.com/TooTallNate/4750953 + */ +export function systemEndianness() { + return _systemEndianness; +}; + +/** + * @desc Evaluate the argument type, to apply respective logic for it + * @param {Object} value - The argument object to evaluate type + * @returns {String} Argument type Array/Number/Float/Texture/Unknown + */ +export function getVariableType(value, strictIntegers) { + if (isArray(value)) { + if (value[0].nodeName === 'IMG') { + return 'HTMLImageArray'; + } + return 'Array'; + } + + switch (value.constructor) { + case Boolean: + return 'Boolean'; + case Number: + return strictIntegers && Number.isInteger(value) ? 'Integer' : 'Float'; + case Texture: + return value.type; + case Input: + return 'Input'; + } + + switch (value.nodeName) { + case 'IMG': + return 'HTMLImage'; + case 'VIDEO': + return 'HTMLVideo'; + } + + return value.hasOwnProperty('type') ? value.type : 'Unknown'; +}; + +/** + * @desc 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) + */ +const utils = { + systemEndianness, + getSystemEndianness, + isFunction, + isFunctionString, + getFunctionNameFromString, + + getFunctionBodyFromString(funcStr) { + return funcStr.substring(funcStr.indexOf('{') + 1, funcStr.lastIndexOf('}')); + }, + + getArgumentNamesFromString, + + /** + * @desc Returns a clone + * @param {Object} obj - Object to clone + * @returns {Object|Array} Cloned object + */ + 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; + }, + + isArray, + getVariableType, + + 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 given dimensions == a 2d image + if (h > 1 && w * h === texelCount) { + return new Int32Array([w, h]); + } + return utils.closestSquareDimensions(texelCount); + }, + + /** + * + * @param {Number} length + * @returns {TextureDimensions} + */ + 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)]); + }, + + /** + * A texture takes up four + * @param {OutputDimensions} dimensions + * @param {Number} bitRatio + * @returns {TextureDimensions} + */ + 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); + }, + + /** + * + * @param dimensions + * @param bitRatio + * @returns {*|TextureDimensions} + */ + 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; + }, + /** + * @desc Return the dimension of an array. + * @param {Array|String|Texture|Input} x - The array + * @param {Boolean} [pad] - To include padding in the dimension calculation + * @returns {OutputDimensions} + */ + getDimensions(x, pad) { + let ret; + if (isArray(x)) { + const dim = []; + let temp = x; + while (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); + }, + + /** + * Puts a nested 2d array into a one-dimensional target array + * @param {Array|*} array + * @param {Float32Array|Float64Array} target + */ + flatten2dArrayTo(array, target) { + let offset = 0; + for (let y = 0; y < array.length; y++) { + target.set(array[y], offset); + offset += array[y].length; + } + }, + + /** + * Puts a nested 3d array into a one-dimensional target array + * @param {Array|*} array + * @param {Float32Array|Float64Array} target + */ + 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; + } + } + }, + + /** + * Puts a nested 4d array into a one-dimensional target array + * @param {Array|*} array + * @param {Float32Array|Float64Array} target + */ + 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; + } + } + } + }, + + /** + * Puts a nested 1d, 2d, or 3d array into a one-dimensional target array + * @param {Float32Array|Uint16Array|Uint8Array} array + * @param {Float32Array} target + */ + flattenTo(array, target) { + if (isArray(array[0])) { + if (isArray(array[0][0])) { + if (isArray(array[0][0][0])) { + utils.flatten4dArrayTo(array, target); + } else { + utils.flatten3dArrayTo(array, target); + } + } else { + utils.flatten2dArrayTo(array, target); + } + } else { + target.set(array); + } + }, + + /** + * + * @desc Splits an array into smaller arrays. + * Number of elements in one small chunk is given by `part` + * + * @param {Number[]} array - The array to split into chunks + * @param {Number} part - elements in one chunk + * + * @returns {Number[]} An array of smaller chunks + */ + 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, + + allPropertiesOf(obj) { + const props = []; + + do { + props.push.apply(props, Object.getOwnPropertyNames(obj)); + } while (obj = Object.getPrototypeOf(obj)); + + return props; + }, + + /** + * @param {Array} lines - An Array of strings + * @returns {String} Single combined String, separated by *\n* + */ + linesToString(lines) { + if (lines.length > 0) { + return lines.join(';\n') + ';\n'; + } else { + return '\n'; + } + }, + + warnDeprecated, + functionToIFunction, + + flipPixels(pixels, width, height) { + // https://stackoverflow.com/a/41973289/1324039 + const halfHeight = height / 2 | 0; // the | 0 keeps the result an int + const bytesPerRow = width * 4; + // make a temp buffer to hold one row + 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; + + // make copy of a row on the top half + temp.set(result.subarray(topOffset, topOffset + bytesPerRow)); + + // copy a row from the bottom half to the top + result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow); + + // copy the copy of the top half row to the bottom half + 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, + erectMemoryOptimized3DFloat, + 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; + }, + + /** + * @param {String} source + * @param {Object} settings + * @return {String} + */ + flattenFunctionToString: (source, settings) => { + const { findDependency, thisLookup, doNotDefine } = settings; + let flattened = settings.flattened; + if (!flattened) { + flattened = settings.flattened = {}; + } + + const ast = parse(source); + const functionDependencies = []; + + 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); + case 'FunctionDeclaration': + return `function ${ast.id.name}(${ast.params.map(flatten).join(', ')}) ${ flatten(ast.body) }`; + case 'BlockStatement': { + const result = []; + for (let i = 0; i < ast.body.length; i++) { + result.push(flatten(ast.body[i]), ';\n'); + } + return `{\n${result.join('')}}`; + } + case 'VariableDeclaration': + switch (ast.declarations[0].id.type) { + case 'ObjectPattern': { + const source = flatten(ast.declarations[0].init); + const properties = ast.declarations.map(declaration => declaration.id.properties.map(flatten))[0]; + if (/this/.test(source)) { + const result = []; + const lookups = properties.map(thisLookup); + for (let i = 0; i < lookups.length; i++) { + const lookup = lookups[i]; + if (lookup === null) continue; + const property = properties[i]; + result.push(`${ast.kind} ${ property } = ${ lookup };\n`); + } + + return result.join(''); + } + return `${ast.kind} { ${properties} } = ${source}`; + } + case 'ArrayPattern': + return `${ast.kind} [ ${ ast.declarations.map(declaration => flatten(declaration.id)).join(', ') } ] = ${flatten(ast.declarations[0].init)}`; + } + if (doNotDefine && doNotDefine.indexOf(ast.declarations[0].id.name) !== -1) { + return ''; + } + return `${ast.kind} ${ast.declarations[0].id.name} = ${flatten(ast.declarations[0].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) { + // we're not flattening it + return `${ast.callee.object.name}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } else { + functionDependencies.push(foundSource); + // we're flattening it + 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 '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; + } + flattenedFunctionDependencies.push(utils.flattenFunctionToString(functionDependency, settings) + ';\n'); + } + return flattenedFunctionDependencies.join('') + result; + } + return result; + }, +}; + +export { utils }; diff --git a/test/.DS_Store b/test/.DS_Store deleted file mode 100644 index 0183cffe..00000000 Binary files a/test/.DS_Store and /dev/null differ diff --git a/test/all-template.html b/test/all-template.html index 3bf6bca0..6759e87a 100644 --- a/test/all-template.html +++ b/test/all-template.html @@ -1,39 +1,34 @@ - - - - - GPU.JS : Test All - - - - - - - -
-
- - - -{{test-files}} - - + + + + + GPU.JS : Test All + + + + + + + +
+
+ + + +{{test-files}} + + diff --git a/test/all.html b/test/all.html index 1ecf5da3..c93b16e2 100644 --- a/test/all.html +++ b/test/all.html @@ -1,39 +1,34 @@ - - - - - GPU.JS : Test All - - - - - - - -
-
- - - + + + + + GPU.JS : Test All + + + + + + + +
+
+ + + @@ -293,6 +288,6 @@ - - - + + + diff --git a/test/benchmark-faster.js b/test/benchmark-faster.js index a41e505c..d05001fb 100644 --- a/test/benchmark-faster.js +++ b/test/benchmark-faster.js @@ -1,4 +1,4 @@ -const { GPU } = require('../src/index.js'); +const { GPU } = require('../dist/gpu.js'); const Benchmark = require('benchmark'); const suite = new Benchmark.Suite; diff --git a/test/benchmark.js b/test/benchmark.js index 86e72d14..31827969 100644 --- a/test/benchmark.js +++ b/test/benchmark.js @@ -1,4 +1,4 @@ -const { GPU } = require('../src/index.js'); +const { GPU } = require('../dist/gpu.js'); const Benchmark = require('benchmark'); const suite = new Benchmark.Suite(); diff --git a/test/features/add-custom-function.js b/test/features/add-custom-function.js index 2cc16840..946dba26 100644 --- a/test/features/add-custom-function.js +++ b/test/features/add-custom-function.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: add custom function'); diff --git a/test/features/add-custom-native-function.js b/test/features/add-custom-native-function.js index 13e0ae23..79d65d00 100644 --- a/test/features/add-custom-native-function.js +++ b/test/features/add-custom-native-function.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: add native'); diff --git a/test/features/add-typed-functions.js b/test/features/add-typed-functions.js index 72ec14ec..139b33d8 100644 --- a/test/features/add-typed-functions.js +++ b/test/features/add-typed-functions.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: add typed functions vec2Test'); function vec2Test(mode) { diff --git a/test/features/argument-array-types.js b/test/features/argument-array-types.js index 93a1102d..7f48158a 100644 --- a/test/features/argument-array-types.js +++ b/test/features/argument-array-types.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('argument array types'); diff --git a/test/features/argument-array1d-types.js b/test/features/argument-array1d-types.js index ce409417..2b15a809 100644 --- a/test/features/argument-array1d-types.js +++ b/test/features/argument-array1d-types.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('argument array 1 types'); diff --git a/test/features/argument-array2d-types.js b/test/features/argument-array2d-types.js index 44e7e79b..8181c786 100644 --- a/test/features/argument-array2d-types.js +++ b/test/features/argument-array2d-types.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('argument array 2 types'); diff --git a/test/features/argument-array3d-types.js b/test/features/argument-array3d-types.js index 68e1fe3a..6ba3c4b3 100644 --- a/test/features/argument-array3d-types.js +++ b/test/features/argument-array3d-types.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('argument array 3 types'); diff --git a/test/features/arithmetic-operators.js b/test/features/arithmetic-operators.js index 83e2d726..5ed59d4c 100644 --- a/test/features/arithmetic-operators.js +++ b/test/features/arithmetic-operators.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: arithmetic operators'); diff --git a/test/features/assignment-operators.js b/test/features/assignment-operators.js index e18bada0..bbce6b95 100644 --- a/test/features/assignment-operators.js +++ b/test/features/assignment-operators.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: assignment operators'); diff --git a/test/features/basic-math.js b/test/features/basic-math.js index 828aec5d..e5444fc1 100644 --- a/test/features/basic-math.js +++ b/test/features/basic-math.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: basic math'); diff --git a/test/features/bitwise-operators.js b/test/features/bitwise-operators.js index 3d0ac614..170424b8 100644 --- a/test/features/bitwise-operators.js +++ b/test/features/bitwise-operators.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('feature: bitwise operators'); diff --git a/test/features/combine-kernels.js b/test/features/combine-kernels.js index 3db77f89..2f8116d1 100644 --- a/test/features/combine-kernels.js +++ b/test/features/combine-kernels.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: combine kernels'); function combineKernels(mode) { diff --git a/test/features/constants-array.js b/test/features/constants-array.js index 910d8086..10090903 100644 --- a/test/features/constants-array.js +++ b/test/features/constants-array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: constants array'); diff --git a/test/features/constants-bool.js b/test/features/constants-bool.js index 4d9c0bed..dba9f1a0 100644 --- a/test/features/constants-bool.js +++ b/test/features/constants-bool.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: constants bool'); diff --git a/test/features/constants-float.js b/test/features/constants-float.js index 16bf7c1c..1d53f681 100644 --- a/test/features/constants-float.js +++ b/test/features/constants-float.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: constants float'); function floatConstantTest(mode) { diff --git a/test/features/constants-image-array.js b/test/features/constants-image-array.js index f286916b..4bab3040 100644 --- a/test/features/constants-image-array.js +++ b/test/features/constants-image-array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU, WebGLKernel } = require('../../src'); +const { GPU, WebGLKernel } = require('../../dist/gpu.js'); describe('features: constants image array'); function feature(mode, done) { diff --git a/test/features/constants-image.js b/test/features/constants-image.js index ae70389c..f191eef0 100644 --- a/test/features/constants-image.js +++ b/test/features/constants-image.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: constants image'); function imageConstantTest(mode, done) { diff --git a/test/features/constants-integer.js b/test/features/constants-integer.js index b3f20005..e3a2b7ab 100644 --- a/test/features/constants-integer.js +++ b/test/features/constants-integer.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: constants integer'); diff --git a/test/features/constants-texture.js b/test/features/constants-texture.js index 83881603..e351dfc8 100644 --- a/test/features/constants-texture.js +++ b/test/features/constants-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: constants texture 1d'); function test1D(mode) { diff --git a/test/features/cpu-with-textures.js b/test/features/cpu-with-textures.js index b5d80233..70b832c2 100644 --- a/test/features/cpu-with-textures.js +++ b/test/features/cpu-with-textures.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: CPU with Textures'); diff --git a/test/features/create-kernel-map.js b/test/features/create-kernel-map.js index 47c3d5af..26a97050 100644 --- a/test/features/create-kernel-map.js +++ b/test/features/create-kernel-map.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, alias } = require('../../src'); +const { GPU, alias } = require('../../dist/gpu.js'); describe('features: create kernel map'); function createPropertyKernels(gpu, output) { diff --git a/test/features/demo.js b/test/features/demo.js index c31af05c..75b6d0b2 100644 --- a/test/features/demo.js +++ b/test/features/demo.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: demo'); diff --git a/test/features/destroy.js b/test/features/destroy.js index b88b7507..e6f24d30 100644 --- a/test/features/destroy.js +++ b/test/features/destroy.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); const sinon = require('sinon'); describe('features: destroy'); diff --git a/test/features/dev-mode.js b/test/features/dev-mode.js index 4e2a9ae0..3976c510 100644 --- a/test/features/dev-mode.js +++ b/test/features/dev-mode.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, input } = require('../../src'); +const { GPU, input } = require('../../dist/gpu.js'); describe('features: dev mode'); diff --git a/test/features/dynamic-arguments.js b/test/features/dynamic-arguments.js index efbe031c..5194c58e 100644 --- a/test/features/dynamic-arguments.js +++ b/test/features/dynamic-arguments.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, input } = require('../../src'); +const { GPU, input } = require('../../dist/gpu.js'); describe('features: dynamic arguments'); diff --git a/test/features/dynamic-output.js b/test/features/dynamic-output.js index 955c46c6..c74d4525 100644 --- a/test/features/dynamic-output.js +++ b/test/features/dynamic-output.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: dynamic output'); diff --git a/test/features/function-return.js b/test/features/function-return.js index c82bb415..8a654254 100644 --- a/test/features/function-return.js +++ b/test/features/function-return.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: function return'); diff --git a/test/features/get-canvas.js b/test/features/get-canvas.js index ef247ad1..98f07729 100644 --- a/test/features/get-canvas.js +++ b/test/features/get-canvas.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('get canvas'); diff --git a/test/features/get-pixels.js b/test/features/get-pixels.js index 4e15491a..f463635b 100644 --- a/test/features/get-pixels.js +++ b/test/features/get-pixels.js @@ -1,5 +1,5 @@ const { assert, test, module: describe, only, skip } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: getPixels'); diff --git a/test/features/if-else.js b/test/features/if-else.js index 53426729..7dd0f9d9 100644 --- a/test/features/if-else.js +++ b/test/features/if-else.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('if else boolean'); function ifElseBooleanTest(mode) { diff --git a/test/features/image-array.js b/test/features/image-array.js index 023d0ac6..7d90649d 100644 --- a/test/features/image-array.js +++ b/test/features/image-array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, CPUKernel } = require('../../src'); +const { GPU, CPUKernel } = require('../../dist/gpu.js'); describe('features: image array'); function getImages(callback) { diff --git a/test/features/image.js b/test/features/image.js index 1e7101d9..315c4136 100644 --- a/test/features/image.js +++ b/test/features/image.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('image'); function imageArgumentTest(mode, done) { diff --git a/test/features/infinity.js b/test/features/infinity.js index 6f9ba3e4..4a31ba09 100644 --- a/test/features/infinity.js +++ b/test/features/infinity.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('infinity'); function inputWithoutFloat(checks, mode) { diff --git a/test/features/inject-native.js b/test/features/inject-native.js index ed16d9df..3632f3cf 100644 --- a/test/features/inject-native.js +++ b/test/features/inject-native.js @@ -1,82 +1,82 @@ -const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); - -describe('features: inject native'); - -function gpuAddAB(mode) { - const gpu = new GPU({mode}); - gpu - .injectNative(` -int customAdder(int a, int b) { - return a + b; -} -`) - .addNativeFunction('customAdderLink', `int customAdderLink(int a, int b) { - return customAdder(a, b); -}`); - const kernel = gpu.createKernel(function (a, b) { - return customAdderLink(a[this.thread.x], b[this.thread.x]); - }, { - output: [6], - returnType: 'Integer' - }); - - const a = [1, 2, 3, 5, 6, 7]; - const b = [4, 5, 6, 1, 2, 3]; - - const result = kernel(a, b); - - const expected = [5, 7, 9, 6, 8, 10]; - - assert.deepEqual(Array.from(result), expected); - gpu.destroy(); -} - -test('addAB auto', () => { - gpuAddAB(null); -}); - -test('addAB gpu', () => { - gpuAddAB('gpu'); -}); - -(GPU.isWebGLSupported ? test : skip)('addAB webgl', () => { - gpuAddAB('webgl'); -}); - -(GPU.isWebGL2Supported ? test : skip)('addAB webgl2', () => { - gpuAddAB('webgl2'); -}); - -(GPU.isHeadlessGLSupported ? test : skip)('addAB headlessgl', () => { - gpuAddAB('headlessgl'); -}); - -function cpuAddAB(mode) { - function customAdder(a, b) { - return a + b; - } - const gpu = new GPU({mode}); - gpu - .injectNative(customAdder.toString()); - const kernel = gpu.createKernel(function (a, b) { - return customAdder(a[this.thread.x], b[this.thread.x]); - }, { - output: [6], - returnType: 'Integer' - }); - - const a = [1, 2, 3, 5, 6, 7]; - const b = [4, 5, 6, 1, 2, 3]; - - const result = kernel(a, b); - - const expected = [5, 7, 9, 6, 8, 10]; - - assert.deepEqual(Array.from(result), expected); - gpu.destroy(); -} - -test('addAB cpu', () => { - cpuAddAB('cpu'); -}); +const { assert, skip, test, module: describe, only } = require('qunit'); +const { GPU } = require('../../dist/gpu.js'); + +describe('features: inject native'); + +function gpuAddAB(mode) { + const gpu = new GPU({mode}); + gpu + .injectNative(` +int customAdder(int a, int b) { + return a + b; +} +`) + .addNativeFunction('customAdderLink', `int customAdderLink(int a, int b) { + return customAdder(a, b); +}`); + const kernel = gpu.createKernel(function (a, b) { + return customAdderLink(a[this.thread.x], b[this.thread.x]); + }, { + output: [6], + returnType: 'Integer' + }); + + const a = [1, 2, 3, 5, 6, 7]; + const b = [4, 5, 6, 1, 2, 3]; + + const result = kernel(a, b); + + const expected = [5, 7, 9, 6, 8, 10]; + + assert.deepEqual(Array.from(result), expected); + gpu.destroy(); +} + +test('addAB auto', () => { + gpuAddAB(null); +}); + +test('addAB gpu', () => { + gpuAddAB('gpu'); +}); + +(GPU.isWebGLSupported ? test : skip)('addAB webgl', () => { + gpuAddAB('webgl'); +}); + +(GPU.isWebGL2Supported ? test : skip)('addAB webgl2', () => { + gpuAddAB('webgl2'); +}); + +(GPU.isHeadlessGLSupported ? test : skip)('addAB headlessgl', () => { + gpuAddAB('headlessgl'); +}); + +function cpuAddAB(mode) { + function customAdder(a, b) { + return a + b; + } + const gpu = new GPU({mode}); + gpu + .injectNative(customAdder.toString()); + const kernel = gpu.createKernel(function (a, b) { + return customAdder(a[this.thread.x], b[this.thread.x]); + }, { + output: [6], + returnType: 'Integer' + }); + + const a = [1, 2, 3, 5, 6, 7]; + const b = [4, 5, 6, 1, 2, 3]; + + const result = kernel(a, b); + + const expected = [5, 7, 9, 6, 8, 10]; + + assert.deepEqual(Array.from(result), expected); + gpu.destroy(); +} + +test('addAB cpu', () => { + cpuAddAB('cpu'); +}); diff --git a/test/features/input.js b/test/features/input.js index 150557b6..54df97ac 100644 --- a/test/features/input.js +++ b/test/features/input.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, input } = require('../../src'); +const { GPU, input } = require('../../dist/gpu.js'); describe('input'); diff --git a/test/features/json.js b/test/features/json.js index 48bb5d7f..678bd203 100644 --- a/test/features/json.js +++ b/test/features/json.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('json serialize'); diff --git a/test/features/legacy-encoder.js b/test/features/legacy-encoder.js index 8c361264..ebf683e1 100644 --- a/test/features/legacy-encoder.js +++ b/test/features/legacy-encoder.js @@ -1,268 +1,268 @@ -const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, HeadlessGLKernel, WebGLKernel, WebGL2Kernel } = require('../../src'); - -describe('features: legacy encoder'); - -function testLegacyEncoderOff(mode) { - const gpu = new GPU({ mode }); - const kernel = gpu.createKernel(function() { - return 1; - }, { output: [1], precision: 'unsigned' }); - assert.equal(kernel()[0], 1); - gpu.destroy(); -} - -test('off auto', () => { - testLegacyEncoderOff(); -}); - -(GPU.isWebGLSupported ? test : skip)('off webgl', () => { - testLegacyEncoderOff('webgl'); -}); - -(GPU.isWebGL2Supported ? test : skip)('off webgl2', () => { - testLegacyEncoderOff('webgl2'); -}); - -(GPU.isHeadlessGLSupported ? test : skip)('off headlessgl', () => { - testLegacyEncoderOff('headlessgl'); -}); - -test('off cpu', () => { - testLegacyEncoderOff('cpu'); -}); - -function testLegacyEncoderOn(mode) { - const gpu = new GPU({ mode }); - const kernel = gpu.createKernel(function() { - return 1; - }, { - output: [1], - precision: 'unsigned', - useLegacyEncoder: true, - }); - assert.equal(kernel()[0], 1); - gpu.destroy(); -} - -test('on auto', () => { - testLegacyEncoderOn(); -}); - -(GPU.isWebGLSupported ? test : skip)('on webgl', () => { - testLegacyEncoderOn('webgl'); -}); - -(GPU.isWebGL2Supported ? test : skip)('on webgl2', () => { - testLegacyEncoderOn('webgl2'); -}); - -(GPU.isHeadlessGLSupported ? test : skip)('on headlessgl', () => { - testLegacyEncoderOn('headlessgl'); -}); - -test('on cpu', () => { - testLegacyEncoderOn('cpu'); -}); - -function testSubKernelsLegacyEncoderOff(mode) { - const gpu = new GPU({ mode }); - function addOne(value) { - return value + 1; - } - const kernel = gpu.createKernelMap([ - addOne, - ], function() { - const result = addOne(1); - return result + 1; - }, { output: [1], precision: 'unsigned' }); - assert.equal(kernel()[0][0], 2); - assert.equal(kernel().result[0], 3); - gpu.destroy(); -} - -(GPU.isKernelMapSupported ? test : skip)('subKernels off auto', () => { - testSubKernelsLegacyEncoderOff(); -}); - -(GPU.isWebGLSupported && GPU.isKernelMapSupported ? test : skip)('subKernels off webgl', () => { - testSubKernelsLegacyEncoderOff('webgl'); -}); - -(GPU.isWebGL2Supported && GPU.isKernelMapSupported ? test : skip)('subKernels off webgl2', () => { - testSubKernelsLegacyEncoderOff('webgl2'); -}); - -(GPU.isHeadlessGLSupported && GPU.isKernelMapSupported ? test : skip)('subKernels off headlessgl', () => { - testSubKernelsLegacyEncoderOff('headlessgl'); -}); - -test('subKernels off cpu', () => { - testSubKernelsLegacyEncoderOff('cpu'); -}); - -function testSubKernelsLegacyEncoderOn(mode) { - const gpu = new GPU({ mode }); - function addOne(value) { - return value + 1; - } - const kernel = gpu.createKernelMap([ - addOne, - ], function() { - const value = addOne(1); - return value + 1; - }, { - output: [1], - precision: 'unsigned', - useLegacyEncoder: true, - }); - assert.equal(kernel()[0][0], 2); - assert.equal(kernel().result[0], 3); - gpu.destroy(); -} - -(GPU.isKernelMapSupported ? test : skip)('subKernels on auto', () => { - testSubKernelsLegacyEncoderOn(); -}); - -(GPU.isWebGLSupported && GPU.isKernelMapSupported ? test : skip)('subKernels on webgl', () => { - testSubKernelsLegacyEncoderOn('webgl'); -}); - -(GPU.isWebGL2Supported && GPU.isKernelMapSupported ? test : skip)('subKernels on webgl2', () => { - testSubKernelsLegacyEncoderOn('webgl2'); -}); - -(GPU.isHeadlessGLSupported && GPU.isKernelMapSupported ? test : skip)('subKernels on headlessgl', () => { - testSubKernelsLegacyEncoderOn('headlessgl'); -}); - -test('subKernels on cpu', () => { - testSubKernelsLegacyEncoderOn('cpu'); -}); - -test('HeadlessGLKernel.getMainResultKernelPackedPixels useLegacyEncoder = false', () => { - const result = HeadlessGLKernel.prototype.getMainResultKernelPackedPixels.apply({ - useLegacyEncoder: false - }); - assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); - kernel(); - gl_FragData[0] = encode32(kernelResult); -`); -}); - -test('WebGLKernel.getMainResultKernelPackedPixels useLegacyEncoder = false', () => { - const result = WebGLKernel.prototype.getMainResultKernelPackedPixels.apply({ - useLegacyEncoder: false - }); - assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); - kernel(); - gl_FragData[0] = encode32(kernelResult); -`); -}); - -test('WebGL2Kernel.getMainResultKernelPackedPixels useLegacyEncoder = false', () => { - const result = WebGL2Kernel.prototype.getMainResultKernelPackedPixels.apply({ - useLegacyEncoder: false - }); - assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); - kernel(); - data0 = encode32(kernelResult); -`); -}); - -test('HeadlessGLKernel.getMainResultKernelPackedPixels useLegacyEncoder = true', () => { - const result = HeadlessGLKernel.prototype.getMainResultKernelPackedPixels.apply({ - useLegacyEncoder: true - }); - assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); - kernel(); - gl_FragData[0] = legacyEncode32(kernelResult); -`); -}); - -test('WebGLKernel.getMainResultKernelPackedPixels useLegacyEncoder = true', () => { - const result = WebGLKernel.prototype.getMainResultKernelPackedPixels.apply({ - useLegacyEncoder: true - }); - assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); - kernel(); - gl_FragData[0] = legacyEncode32(kernelResult); -`); -}); - -test('WebGL2Kernel.getMainResultKernelPackedPixels useLegacyEncoder = true', () => { - const result = WebGL2Kernel.prototype.getMainResultKernelPackedPixels.apply({ - useLegacyEncoder: true - }); - assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); - kernel(); - data0 = legacyEncode32(kernelResult); -`); -}); - -test('HeadlessGLKernel.getMainResultSubKernelPackedPixels useLegacyEncoder = false', () => { - const result = HeadlessGLKernel.prototype.getMainResultSubKernelPackedPixels.apply({ - useLegacyEncoder: false, - subKernels: [{ - name: 'subKernel1' - }] - }); - assert.equal(result, ` gl_FragData[1] = encode32(subKernelResult_subKernel1); -`); -}); - -test('WebGLKernel.getMainResultSubKernelPackedPixels useLegacyEncoder = false', () => { - const result = WebGLKernel.prototype.getMainResultSubKernelPackedPixels.apply({ - useLegacyEncoder: false, - subKernels: [{ - name: 'subKernel1' - }] - }); - assert.equal(result, ` gl_FragData[1] = encode32(subKernelResult_subKernel1); -`); -}); - -test('WebGL2Kernel.getMainResultSubKernelPackedPixels useLegacyEncoder = false', () => { - const result = WebGL2Kernel.prototype.getMainResultSubKernelPackedPixels.apply({ - useLegacyEncoder: false, - subKernels: [{ - name: 'subKernel1' - }] - }); - assert.equal(result, ` data1 = encode32(subKernelResult_subKernel1); -`); -}); - -test('HeadlessGLKernel.getMainResultSubKernelPackedPixels useLegacyEncoder = true', () => { - const result = HeadlessGLKernel.prototype.getMainResultSubKernelPackedPixels.apply({ - useLegacyEncoder: true, - subKernels: [{ - name: 'subKernel1' - }] - }); - assert.equal(result, ` gl_FragData[1] = legacyEncode32(subKernelResult_subKernel1); -`); -}); - -test('WebGLKernel.getMainResultSubKernelPackedPixels useLegacyEncoder = true', () => { - const result = WebGLKernel.prototype.getMainResultSubKernelPackedPixels.apply({ - useLegacyEncoder: true, - subKernels: [{ - name: 'subKernel1' - }] - }); - assert.equal(result, ` gl_FragData[1] = legacyEncode32(subKernelResult_subKernel1); -`); -}); - -test('WebGL2Kernel.getMainResultSubKernelPackedPixels useLegacyEncoder = true', () => { - const result = WebGL2Kernel.prototype.getMainResultSubKernelPackedPixels.apply({ - useLegacyEncoder: true, - subKernels: [{ - name: 'subKernel1' - }] - }); - assert.equal(result, ` data1 = legacyEncode32(subKernelResult_subKernel1); -`); -}); +const { assert, skip, test, module: describe, only } = require('qunit'); +const { GPU, HeadlessGLKernel, WebGLKernel, WebGL2Kernel } = require('../../dist/gpu.js'); + +describe('features: legacy encoder'); + +function testLegacyEncoderOff(mode) { + const gpu = new GPU({ mode }); + const kernel = gpu.createKernel(function() { + return 1; + }, { output: [1], precision: 'unsigned' }); + assert.equal(kernel()[0], 1); + gpu.destroy(); +} + +test('off auto', () => { + testLegacyEncoderOff(); +}); + +(GPU.isWebGLSupported ? test : skip)('off webgl', () => { + testLegacyEncoderOff('webgl'); +}); + +(GPU.isWebGL2Supported ? test : skip)('off webgl2', () => { + testLegacyEncoderOff('webgl2'); +}); + +(GPU.isHeadlessGLSupported ? test : skip)('off headlessgl', () => { + testLegacyEncoderOff('headlessgl'); +}); + +test('off cpu', () => { + testLegacyEncoderOff('cpu'); +}); + +function testLegacyEncoderOn(mode) { + const gpu = new GPU({ mode }); + const kernel = gpu.createKernel(function() { + return 1; + }, { + output: [1], + precision: 'unsigned', + useLegacyEncoder: true, + }); + assert.equal(kernel()[0], 1); + gpu.destroy(); +} + +test('on auto', () => { + testLegacyEncoderOn(); +}); + +(GPU.isWebGLSupported ? test : skip)('on webgl', () => { + testLegacyEncoderOn('webgl'); +}); + +(GPU.isWebGL2Supported ? test : skip)('on webgl2', () => { + testLegacyEncoderOn('webgl2'); +}); + +(GPU.isHeadlessGLSupported ? test : skip)('on headlessgl', () => { + testLegacyEncoderOn('headlessgl'); +}); + +test('on cpu', () => { + testLegacyEncoderOn('cpu'); +}); + +function testSubKernelsLegacyEncoderOff(mode) { + const gpu = new GPU({ mode }); + function addOne(value) { + return value + 1; + } + const kernel = gpu.createKernelMap([ + addOne, + ], function() { + const result = addOne(1); + return result + 1; + }, { output: [1], precision: 'unsigned' }); + assert.equal(kernel()[0][0], 2); + assert.equal(kernel().result[0], 3); + gpu.destroy(); +} + +(GPU.isKernelMapSupported ? test : skip)('subKernels off auto', () => { + testSubKernelsLegacyEncoderOff(); +}); + +(GPU.isWebGLSupported && GPU.isKernelMapSupported ? test : skip)('subKernels off webgl', () => { + testSubKernelsLegacyEncoderOff('webgl'); +}); + +(GPU.isWebGL2Supported && GPU.isKernelMapSupported ? test : skip)('subKernels off webgl2', () => { + testSubKernelsLegacyEncoderOff('webgl2'); +}); + +(GPU.isHeadlessGLSupported && GPU.isKernelMapSupported ? test : skip)('subKernels off headlessgl', () => { + testSubKernelsLegacyEncoderOff('headlessgl'); +}); + +test('subKernels off cpu', () => { + testSubKernelsLegacyEncoderOff('cpu'); +}); + +function testSubKernelsLegacyEncoderOn(mode) { + const gpu = new GPU({ mode }); + function addOne(value) { + return value + 1; + } + const kernel = gpu.createKernelMap([ + addOne, + ], function() { + const value = addOne(1); + return value + 1; + }, { + output: [1], + precision: 'unsigned', + useLegacyEncoder: true, + }); + assert.equal(kernel()[0][0], 2); + assert.equal(kernel().result[0], 3); + gpu.destroy(); +} + +(GPU.isKernelMapSupported ? test : skip)('subKernels on auto', () => { + testSubKernelsLegacyEncoderOn(); +}); + +(GPU.isWebGLSupported && GPU.isKernelMapSupported ? test : skip)('subKernels on webgl', () => { + testSubKernelsLegacyEncoderOn('webgl'); +}); + +(GPU.isWebGL2Supported && GPU.isKernelMapSupported ? test : skip)('subKernels on webgl2', () => { + testSubKernelsLegacyEncoderOn('webgl2'); +}); + +(GPU.isHeadlessGLSupported && GPU.isKernelMapSupported ? test : skip)('subKernels on headlessgl', () => { + testSubKernelsLegacyEncoderOn('headlessgl'); +}); + +test('subKernels on cpu', () => { + testSubKernelsLegacyEncoderOn('cpu'); +}); + +(GPU.isHeadlessGLSupported ? test : skip)('HeadlessGLKernel.getMainResultKernelPackedPixels useLegacyEncoder = false', () => { + const result = HeadlessGLKernel.prototype.getMainResultKernelPackedPixels.apply({ + useLegacyEncoder: false + }); + assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); + kernel(); + gl_FragData[0] = encode32(kernelResult); +`); +}); + +(GPU.isWebGLSupported ? test : skip)('WebGLKernel.getMainResultKernelPackedPixels useLegacyEncoder = false', () => { + const result = WebGLKernel.prototype.getMainResultKernelPackedPixels.apply({ + useLegacyEncoder: false + }); + assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); + kernel(); + gl_FragData[0] = encode32(kernelResult); +`); +}); + +(GPU.isWebGL2Supported ? test : skip)('WebGL2Kernel.getMainResultKernelPackedPixels useLegacyEncoder = false', () => { + const result = WebGL2Kernel.prototype.getMainResultKernelPackedPixels.apply({ + useLegacyEncoder: false + }); + assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); + kernel(); + data0 = encode32(kernelResult); +`); +}); + +(GPU.isHeadlessGLSupported ? test : skip)('HeadlessGLKernel.getMainResultKernelPackedPixels useLegacyEncoder = true', () => { + const result = HeadlessGLKernel.prototype.getMainResultKernelPackedPixels.apply({ + useLegacyEncoder: true + }); + assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); + kernel(); + gl_FragData[0] = legacyEncode32(kernelResult); +`); +}); + +(GPU.isWebGLSupported ? test : skip)('WebGLKernel.getMainResultKernelPackedPixels useLegacyEncoder = true', () => { + const result = WebGLKernel.prototype.getMainResultKernelPackedPixels.apply({ + useLegacyEncoder: true + }); + assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); + kernel(); + gl_FragData[0] = legacyEncode32(kernelResult); +`); +}); + +(GPU.isWebGL2Supported ? test : skip)('WebGL2Kernel.getMainResultKernelPackedPixels useLegacyEncoder = true', () => { + const result = WebGL2Kernel.prototype.getMainResultKernelPackedPixels.apply({ + useLegacyEncoder: true + }); + assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); + kernel(); + data0 = legacyEncode32(kernelResult); +`); +}); + +(GPU.isHeadlessGLSupported ? test : skip)('HeadlessGLKernel.getMainResultSubKernelPackedPixels useLegacyEncoder = false', () => { + const result = HeadlessGLKernel.prototype.getMainResultSubKernelPackedPixels.apply({ + useLegacyEncoder: false, + subKernels: [{ + name: 'subKernel1' + }] + }); + assert.equal(result, ` gl_FragData[1] = encode32(subKernelResult_subKernel1); +`); +}); + +(GPU.isWebGLSupported ? test : skip)('WebGLKernel.getMainResultSubKernelPackedPixels useLegacyEncoder = false', () => { + const result = WebGLKernel.prototype.getMainResultSubKernelPackedPixels.apply({ + useLegacyEncoder: false, + subKernels: [{ + name: 'subKernel1' + }] + }); + assert.equal(result, ` gl_FragData[1] = encode32(subKernelResult_subKernel1); +`); +}); + +(GPU.isWebGL2Supported ? test : skip)('WebGL2Kernel.getMainResultSubKernelPackedPixels useLegacyEncoder = false', () => { + const result = WebGL2Kernel.prototype.getMainResultSubKernelPackedPixels.apply({ + useLegacyEncoder: false, + subKernels: [{ + name: 'subKernel1' + }] + }); + assert.equal(result, ` data1 = encode32(subKernelResult_subKernel1); +`); +}); + +(GPU.isHeadlessGLSupported ? test : skip)('HeadlessGLKernel.getMainResultSubKernelPackedPixels useLegacyEncoder = true', () => { + const result = HeadlessGLKernel.prototype.getMainResultSubKernelPackedPixels.apply({ + useLegacyEncoder: true, + subKernels: [{ + name: 'subKernel1' + }] + }); + assert.equal(result, ` gl_FragData[1] = legacyEncode32(subKernelResult_subKernel1); +`); +}); + +(GPU.isWebGLSupported ? test : skip)('WebGLKernel.getMainResultSubKernelPackedPixels useLegacyEncoder = true', () => { + const result = WebGLKernel.prototype.getMainResultSubKernelPackedPixels.apply({ + useLegacyEncoder: true, + subKernels: [{ + name: 'subKernel1' + }] + }); + assert.equal(result, ` gl_FragData[1] = legacyEncode32(subKernelResult_subKernel1); +`); +}); + +(GPU.isWebGL2Supported ? test : skip)('WebGL2Kernel.getMainResultSubKernelPackedPixels useLegacyEncoder = true', () => { + const result = WebGL2Kernel.prototype.getMainResultSubKernelPackedPixels.apply({ + useLegacyEncoder: true, + subKernels: [{ + name: 'subKernel1' + }] + }); + assert.equal(result, ` data1 = legacyEncode32(subKernelResult_subKernel1); +`); +}); diff --git a/test/features/loops.js b/test/features/loops.js index 597471a2..866ec145 100644 --- a/test/features/loops.js +++ b/test/features/loops.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('loops - for'); function forLoopTest(mode) { diff --git a/test/features/math-object.js b/test/features/math-object.js index bd80ae46..fe2c37cf 100644 --- a/test/features/math-object.js +++ b/test/features/math-object.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('math object'); diff --git a/test/features/nested-function.js b/test/features/nested-function.js index 52b830c5..b469c617 100644 --- a/test/features/nested-function.js +++ b/test/features/nested-function.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('nested function'); diff --git a/test/features/optimize-float-memory.js b/test/features/optimize-float-memory.js index 7f79a1a9..5b291a1b 100644 --- a/test/features/optimize-float-memory.js +++ b/test/features/optimize-float-memory.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, utils } = require('../../src'); +const { GPU, utils } = require('../../dist/gpu.js'); describe('feature: optimizeFloatMemory'); diff --git a/test/features/output.js b/test/features/output.js index 17d348e0..e58e8e78 100644 --- a/test/features/output.js +++ b/test/features/output.js @@ -1,5 +1,5 @@ const { assert, test, module: describe, only, skip } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: output'); diff --git a/test/features/promise-api.js b/test/features/promise-api.js index f77c6e87..9e62f99b 100644 --- a/test/features/promise-api.js +++ b/test/features/promise-api.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: promise api'); diff --git a/test/features/raw-output.js b/test/features/raw-output.js index 0f73e5f9..27d33e95 100644 --- a/test/features/raw-output.js +++ b/test/features/raw-output.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: raw output'); diff --git a/test/features/read-color-texture.js b/test/features/read-color-texture.js index 40453319..607a26a7 100644 --- a/test/features/read-color-texture.js +++ b/test/features/read-color-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: read color texture'); diff --git a/test/features/read-from-texture.js b/test/features/read-from-texture.js index e5e007ae..168d3463 100644 --- a/test/features/read-from-texture.js +++ b/test/features/read-from-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU, HeadlessGLKernel } = require('../../src'); +const { GPU, HeadlessGLKernel } = require('../../dist/gpu.js'); describe('features: read from texture'); diff --git a/test/features/return-arrays.js b/test/features/return-arrays.js index a6faa7bc..83e236c1 100644 --- a/test/features/return-arrays.js +++ b/test/features/return-arrays.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: return arrays'); diff --git a/test/features/single-precision-textures.js b/test/features/single-precision-textures.js index 557679d1..564e378a 100644 --- a/test/features/single-precision-textures.js +++ b/test/features/single-precision-textures.js @@ -1,5 +1,5 @@ const { assert, skip, test, only, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: single precision textures'); diff --git a/test/features/single-precision.js b/test/features/single-precision.js index 74c11c1b..4d0b409e 100644 --- a/test/features/single-precision.js +++ b/test/features/single-precision.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: single precision'); function singlePrecisionKernel(mode) { diff --git a/test/features/switches.js b/test/features/switches.js index ec1918f1..62386118 100644 --- a/test/features/switches.js +++ b/test/features/switches.js @@ -1,5 +1,5 @@ const { assert, skip, test, only, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: switches'); diff --git a/test/features/tactic.js b/test/features/tactic.js index 01abb8ce..f1f6378f 100644 --- a/test/features/tactic.js +++ b/test/features/tactic.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: tactic'); diff --git a/test/features/ternary.js b/test/features/ternary.js index b0caeaba..87c3b843 100644 --- a/test/features/ternary.js +++ b/test/features/ternary.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('feature: Ternary'); diff --git a/test/features/to-string/precision/single/arguments/array.js b/test/features/to-string/precision/single/arguments/array.js index d115cfe5..133ce0c5 100644 --- a/test/features/to-string/precision/single/arguments/array.js +++ b/test/features/to-string/precision/single/arguments/array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Array'); diff --git a/test/features/to-string/precision/single/arguments/array2.js b/test/features/to-string/precision/single/arguments/array2.js index b68236a8..c3c16680 100644 --- a/test/features/to-string/precision/single/arguments/array2.js +++ b/test/features/to-string/precision/single/arguments/array2.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Array(2)'); diff --git a/test/features/to-string/precision/single/arguments/array2d.js b/test/features/to-string/precision/single/arguments/array2d.js index 7a503e33..362f8fce 100644 --- a/test/features/to-string/precision/single/arguments/array2d.js +++ b/test/features/to-string/precision/single/arguments/array2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Array2D'); diff --git a/test/features/to-string/precision/single/arguments/array2d2.js b/test/features/to-string/precision/single/arguments/array2d2.js index ae1dcc72..0d18ee60 100644 --- a/test/features/to-string/precision/single/arguments/array2d2.js +++ b/test/features/to-string/precision/single/arguments/array2d2.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Array2D(2)'); diff --git a/test/features/to-string/precision/single/arguments/array2d3.js b/test/features/to-string/precision/single/arguments/array2d3.js index 3d2fb874..249e0ef1 100644 --- a/test/features/to-string/precision/single/arguments/array2d3.js +++ b/test/features/to-string/precision/single/arguments/array2d3.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Array2D(3)'); diff --git a/test/features/to-string/precision/single/arguments/array3.js b/test/features/to-string/precision/single/arguments/array3.js index cc982e1d..149a3bd3 100644 --- a/test/features/to-string/precision/single/arguments/array3.js +++ b/test/features/to-string/precision/single/arguments/array3.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Array(3)'); diff --git a/test/features/to-string/precision/single/arguments/array3d.js b/test/features/to-string/precision/single/arguments/array3d.js index 66d2a27b..f63e4a80 100644 --- a/test/features/to-string/precision/single/arguments/array3d.js +++ b/test/features/to-string/precision/single/arguments/array3d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Array3D'); diff --git a/test/features/to-string/precision/single/arguments/array4.js b/test/features/to-string/precision/single/arguments/array4.js index 8a3a70df..59561c8f 100644 --- a/test/features/to-string/precision/single/arguments/array4.js +++ b/test/features/to-string/precision/single/arguments/array4.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Array(4)'); diff --git a/test/features/to-string/precision/single/arguments/boolean.js b/test/features/to-string/precision/single/arguments/boolean.js index 3ae322a0..b882da16 100644 --- a/test/features/to-string/precision/single/arguments/boolean.js +++ b/test/features/to-string/precision/single/arguments/boolean.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Boolean'); diff --git a/test/features/to-string/precision/single/arguments/float.js b/test/features/to-string/precision/single/arguments/float.js index 3fd99e9f..2ba02ec2 100644 --- a/test/features/to-string/precision/single/arguments/float.js +++ b/test/features/to-string/precision/single/arguments/float.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Float'); diff --git a/test/features/to-string/precision/single/arguments/html-image-array.js b/test/features/to-string/precision/single/arguments/html-image-array.js index 2d2a2fe3..881f986a 100644 --- a/test/features/to-string/precision/single/arguments/html-image-array.js +++ b/test/features/to-string/precision/single/arguments/html-image-array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, CPUKernel } = require('../../../../../../src'); +const { GPU, CPUKernel } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments HTMLImageArray'); diff --git a/test/features/to-string/precision/single/arguments/html-image.js b/test/features/to-string/precision/single/arguments/html-image.js index d28f811b..45f9bb04 100644 --- a/test/features/to-string/precision/single/arguments/html-image.js +++ b/test/features/to-string/precision/single/arguments/html-image.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments HTMLImage'); diff --git a/test/features/to-string/precision/single/arguments/input.js b/test/features/to-string/precision/single/arguments/input.js index 0b87a66a..75b66d55 100644 --- a/test/features/to-string/precision/single/arguments/input.js +++ b/test/features/to-string/precision/single/arguments/input.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, input } = require('../../../../../../src'); +const { GPU, input } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Input'); diff --git a/test/features/to-string/precision/single/arguments/integer.js b/test/features/to-string/precision/single/arguments/integer.js index f787e503..5f775bb4 100644 --- a/test/features/to-string/precision/single/arguments/integer.js +++ b/test/features/to-string/precision/single/arguments/integer.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Integer'); diff --git a/test/features/to-string/precision/single/arguments/memory-optimized-number-texture.js b/test/features/to-string/precision/single/arguments/memory-optimized-number-texture.js index b8e59340..9041271e 100644 --- a/test/features/to-string/precision/single/arguments/memory-optimized-number-texture.js +++ b/test/features/to-string/precision/single/arguments/memory-optimized-number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments MemoryOptimizedNumberTexture'); diff --git a/test/features/to-string/precision/single/arguments/number-texture.js b/test/features/to-string/precision/single/arguments/number-texture.js index 36b80b5c..959bf26b 100644 --- a/test/features/to-string/precision/single/arguments/number-texture.js +++ b/test/features/to-string/precision/single/arguments/number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments NumberTexture'); diff --git a/test/features/to-string/precision/single/constants/array.js b/test/features/to-string/precision/single/constants/array.js index 876d39ad..cb575568 100644 --- a/test/features/to-string/precision/single/constants/array.js +++ b/test/features/to-string/precision/single/constants/array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants Array'); diff --git a/test/features/to-string/precision/single/constants/array2.js b/test/features/to-string/precision/single/constants/array2.js index 3e548306..1a7aadd1 100644 --- a/test/features/to-string/precision/single/constants/array2.js +++ b/test/features/to-string/precision/single/constants/array2.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants Array(2)'); diff --git a/test/features/to-string/precision/single/constants/array2d.js b/test/features/to-string/precision/single/constants/array2d.js index c48af645..ce81856e 100644 --- a/test/features/to-string/precision/single/constants/array2d.js +++ b/test/features/to-string/precision/single/constants/array2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants 2d Array'); diff --git a/test/features/to-string/precision/single/constants/array3.js b/test/features/to-string/precision/single/constants/array3.js index e1aee848..cfe3a411 100644 --- a/test/features/to-string/precision/single/constants/array3.js +++ b/test/features/to-string/precision/single/constants/array3.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants Array(3)'); diff --git a/test/features/to-string/precision/single/constants/array3d.js b/test/features/to-string/precision/single/constants/array3d.js index 784ad56d..fe9cfd37 100644 --- a/test/features/to-string/precision/single/constants/array3d.js +++ b/test/features/to-string/precision/single/constants/array3d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants 3d Array'); diff --git a/test/features/to-string/precision/single/constants/array4.js b/test/features/to-string/precision/single/constants/array4.js index 3290d304..2f4c993b 100644 --- a/test/features/to-string/precision/single/constants/array4.js +++ b/test/features/to-string/precision/single/constants/array4.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants Array(4)'); diff --git a/test/features/to-string/precision/single/constants/boolean.js b/test/features/to-string/precision/single/constants/boolean.js index a1bb6f5a..ef2aadf3 100644 --- a/test/features/to-string/precision/single/constants/boolean.js +++ b/test/features/to-string/precision/single/constants/boolean.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants Boolean'); diff --git a/test/features/to-string/precision/single/constants/float.js b/test/features/to-string/precision/single/constants/float.js index 551a24b4..8ac61d3a 100644 --- a/test/features/to-string/precision/single/constants/float.js +++ b/test/features/to-string/precision/single/constants/float.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants Float'); diff --git a/test/features/to-string/precision/single/constants/html-image-array.js b/test/features/to-string/precision/single/constants/html-image-array.js index a7b0a3a4..8419ade2 100644 --- a/test/features/to-string/precision/single/constants/html-image-array.js +++ b/test/features/to-string/precision/single/constants/html-image-array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, CPUKernel } = require('../../../../../../src'); +const { GPU, CPUKernel } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants HTMLImageArray'); diff --git a/test/features/to-string/precision/single/constants/html-image.js b/test/features/to-string/precision/single/constants/html-image.js index 904d52a7..c9b047db 100644 --- a/test/features/to-string/precision/single/constants/html-image.js +++ b/test/features/to-string/precision/single/constants/html-image.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants HTMLImage'); diff --git a/test/features/to-string/precision/single/constants/input.js b/test/features/to-string/precision/single/constants/input.js index 7f600bad..3e9666f5 100644 --- a/test/features/to-string/precision/single/constants/input.js +++ b/test/features/to-string/precision/single/constants/input.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, input } = require('../../../../../../src'); +const { GPU, input } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants Input'); diff --git a/test/features/to-string/precision/single/constants/integer.js b/test/features/to-string/precision/single/constants/integer.js index aaae2d20..0cd4c1de 100644 --- a/test/features/to-string/precision/single/constants/integer.js +++ b/test/features/to-string/precision/single/constants/integer.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants Integer'); diff --git a/test/features/to-string/precision/single/constants/memory-optimized-number-texture.js b/test/features/to-string/precision/single/constants/memory-optimized-number-texture.js index 9f996df6..14804828 100644 --- a/test/features/to-string/precision/single/constants/memory-optimized-number-texture.js +++ b/test/features/to-string/precision/single/constants/memory-optimized-number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants MemoryOptimizedNumberTexture'); diff --git a/test/features/to-string/precision/single/constants/number-texture.js b/test/features/to-string/precision/single/constants/number-texture.js index d8829edc..d34ab0f2 100644 --- a/test/features/to-string/precision/single/constants/number-texture.js +++ b/test/features/to-string/precision/single/constants/number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants NumberTexture'); diff --git a/test/features/to-string/precision/single/graphical.js b/test/features/to-string/precision/single/graphical.js index 3d86eb7f..d9384bb7 100644 --- a/test/features/to-string/precision/single/graphical.js +++ b/test/features/to-string/precision/single/graphical.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../src'); +const { GPU } = require('../../../../../dist/gpu.js'); describe('feature: to-string single precision graphical'); diff --git a/test/features/to-string/precision/single/kernel-map/array/array.js b/test/features/to-string/precision/single/kernel-map/array/array.js index ef7c52f7..0135b946 100644 --- a/test/features/to-string/precision/single/kernel-map/array/array.js +++ b/test/features/to-string/precision/single/kernel-map/array/array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string single precision array style kernel map returns Array'); diff --git a/test/features/to-string/precision/single/kernel-map/array/array2d.js b/test/features/to-string/precision/single/kernel-map/array/array2d.js index 25bf743c..3fa51f4f 100644 --- a/test/features/to-string/precision/single/kernel-map/array/array2d.js +++ b/test/features/to-string/precision/single/kernel-map/array/array2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string single precision array style kernel map returns 2D Array'); diff --git a/test/features/to-string/precision/single/kernel-map/array/array3d.js b/test/features/to-string/precision/single/kernel-map/array/array3d.js index 03c5f117..707dda58 100644 --- a/test/features/to-string/precision/single/kernel-map/array/array3d.js +++ b/test/features/to-string/precision/single/kernel-map/array/array3d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string single precision array style kernel map returns Array3d'); diff --git a/test/features/to-string/precision/single/kernel-map/array/memory-optimized-number-texture.js b/test/features/to-string/precision/single/kernel-map/array/memory-optimized-number-texture.js index e0b61bac..25c7eee3 100644 --- a/test/features/to-string/precision/single/kernel-map/array/memory-optimized-number-texture.js +++ b/test/features/to-string/precision/single/kernel-map/array/memory-optimized-number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string single precision array style kernel map returns MemoryOptimizedNumberTexture'); diff --git a/test/features/to-string/precision/single/kernel-map/array/number-texture.js b/test/features/to-string/precision/single/kernel-map/array/number-texture.js index 86e8a3e2..2216ea98 100644 --- a/test/features/to-string/precision/single/kernel-map/array/number-texture.js +++ b/test/features/to-string/precision/single/kernel-map/array/number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string single precision array style kernel map returns NumberTexture'); diff --git a/test/features/to-string/precision/single/kernel-map/object/array.js b/test/features/to-string/precision/single/kernel-map/object/array.js index 6fb90600..afe2d1aa 100644 --- a/test/features/to-string/precision/single/kernel-map/object/array.js +++ b/test/features/to-string/precision/single/kernel-map/object/array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string single precision object style returns Array'); diff --git a/test/features/to-string/precision/single/kernel-map/object/array2d.js b/test/features/to-string/precision/single/kernel-map/object/array2d.js index 60b22f91..e82acf30 100644 --- a/test/features/to-string/precision/single/kernel-map/object/array2d.js +++ b/test/features/to-string/precision/single/kernel-map/object/array2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string single precision object style returns Array2D'); diff --git a/test/features/to-string/precision/single/kernel-map/object/array3d.js b/test/features/to-string/precision/single/kernel-map/object/array3d.js index 0c1ac27d..cf84fd5f 100644 --- a/test/features/to-string/precision/single/kernel-map/object/array3d.js +++ b/test/features/to-string/precision/single/kernel-map/object/array3d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string single precision object style returns Array3d'); diff --git a/test/features/to-string/precision/single/kernel-map/object/memory-optimized-number-texture.js b/test/features/to-string/precision/single/kernel-map/object/memory-optimized-number-texture.js index 06c27cd3..d0778e80 100644 --- a/test/features/to-string/precision/single/kernel-map/object/memory-optimized-number-texture.js +++ b/test/features/to-string/precision/single/kernel-map/object/memory-optimized-number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string single precision object style kernel map returns MemoryOptimizedNumberTexture'); diff --git a/test/features/to-string/precision/single/kernel-map/object/number-texture.js b/test/features/to-string/precision/single/kernel-map/object/number-texture.js index ee294f1e..764d42ea 100644 --- a/test/features/to-string/precision/single/kernel-map/object/number-texture.js +++ b/test/features/to-string/precision/single/kernel-map/object/number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string single precision object style kernel map returns NumberTexture'); diff --git a/test/features/to-string/precision/single/returns/array.js b/test/features/to-string/precision/single/returns/array.js index fde332ec..4511b4c6 100644 --- a/test/features/to-string/precision/single/returns/array.js +++ b/test/features/to-string/precision/single/returns/array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision returns Array'); diff --git a/test/features/to-string/precision/single/returns/array2d.js b/test/features/to-string/precision/single/returns/array2d.js index bea7ee04..acec9b2a 100644 --- a/test/features/to-string/precision/single/returns/array2d.js +++ b/test/features/to-string/precision/single/returns/array2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision returns Array2D'); diff --git a/test/features/to-string/precision/single/returns/array3d.js b/test/features/to-string/precision/single/returns/array3d.js index 04828661..141fd522 100644 --- a/test/features/to-string/precision/single/returns/array3d.js +++ b/test/features/to-string/precision/single/returns/array3d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision returns Array3d'); diff --git a/test/features/to-string/precision/unsigned/arguments/array.js b/test/features/to-string/precision/unsigned/arguments/array.js index 18f6ef72..1c5129f5 100644 --- a/test/features/to-string/precision/unsigned/arguments/array.js +++ b/test/features/to-string/precision/unsigned/arguments/array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments Array'); diff --git a/test/features/to-string/precision/unsigned/arguments/array2.js b/test/features/to-string/precision/unsigned/arguments/array2.js index e4ce7279..07cc7c07 100644 --- a/test/features/to-string/precision/unsigned/arguments/array2.js +++ b/test/features/to-string/precision/unsigned/arguments/array2.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments Array(2)'); diff --git a/test/features/to-string/precision/unsigned/arguments/array2d.js b/test/features/to-string/precision/unsigned/arguments/array2d.js index 670a0bf7..cad5f503 100644 --- a/test/features/to-string/precision/unsigned/arguments/array2d.js +++ b/test/features/to-string/precision/unsigned/arguments/array2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments Array2D'); diff --git a/test/features/to-string/precision/unsigned/arguments/array3.js b/test/features/to-string/precision/unsigned/arguments/array3.js index e1bc7428..54dd5432 100644 --- a/test/features/to-string/precision/unsigned/arguments/array3.js +++ b/test/features/to-string/precision/unsigned/arguments/array3.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments Array(3)'); diff --git a/test/features/to-string/precision/unsigned/arguments/array3d.js b/test/features/to-string/precision/unsigned/arguments/array3d.js index 46e465f0..b7035786 100644 --- a/test/features/to-string/precision/unsigned/arguments/array3d.js +++ b/test/features/to-string/precision/unsigned/arguments/array3d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments Array3D'); diff --git a/test/features/to-string/precision/unsigned/arguments/array4.js b/test/features/to-string/precision/unsigned/arguments/array4.js index ca319303..d43dbfbc 100644 --- a/test/features/to-string/precision/unsigned/arguments/array4.js +++ b/test/features/to-string/precision/unsigned/arguments/array4.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments Array(4)'); diff --git a/test/features/to-string/precision/unsigned/arguments/boolean.js b/test/features/to-string/precision/unsigned/arguments/boolean.js index 157b3ac3..6b59f5d8 100644 --- a/test/features/to-string/precision/unsigned/arguments/boolean.js +++ b/test/features/to-string/precision/unsigned/arguments/boolean.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments Boolean'); diff --git a/test/features/to-string/precision/unsigned/arguments/float.js b/test/features/to-string/precision/unsigned/arguments/float.js index aabe1cf2..d3bab22c 100644 --- a/test/features/to-string/precision/unsigned/arguments/float.js +++ b/test/features/to-string/precision/unsigned/arguments/float.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments Float'); diff --git a/test/features/to-string/precision/unsigned/arguments/html-image-array.js b/test/features/to-string/precision/unsigned/arguments/html-image-array.js index a259b44a..8dcaac22 100644 --- a/test/features/to-string/precision/unsigned/arguments/html-image-array.js +++ b/test/features/to-string/precision/unsigned/arguments/html-image-array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, CPUKernel } = require('../../../../../../src'); +const { GPU, CPUKernel } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments HTMLImageArray'); diff --git a/test/features/to-string/precision/unsigned/arguments/html-image.js b/test/features/to-string/precision/unsigned/arguments/html-image.js index 86134f88..c0152af2 100644 --- a/test/features/to-string/precision/unsigned/arguments/html-image.js +++ b/test/features/to-string/precision/unsigned/arguments/html-image.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments HTMLImage'); diff --git a/test/features/to-string/precision/unsigned/arguments/html-video.js b/test/features/to-string/precision/unsigned/arguments/html-video.js index 5c4f477e..69c46ed3 100644 --- a/test/features/to-string/precision/unsigned/arguments/html-video.js +++ b/test/features/to-string/precision/unsigned/arguments/html-video.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments HTMLVideo'); diff --git a/test/features/to-string/precision/unsigned/arguments/input.js b/test/features/to-string/precision/unsigned/arguments/input.js index 0d96103d..b6908f87 100644 --- a/test/features/to-string/precision/unsigned/arguments/input.js +++ b/test/features/to-string/precision/unsigned/arguments/input.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, input } = require('../../../../../../src'); +const { GPU, input } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments Input'); diff --git a/test/features/to-string/precision/unsigned/arguments/integer.js b/test/features/to-string/precision/unsigned/arguments/integer.js index 22d1e750..65e1e02b 100644 --- a/test/features/to-string/precision/unsigned/arguments/integer.js +++ b/test/features/to-string/precision/unsigned/arguments/integer.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments Integer'); diff --git a/test/features/to-string/precision/unsigned/arguments/memory-optimized-number-texture.js b/test/features/to-string/precision/unsigned/arguments/memory-optimized-number-texture.js index 6695695e..f264a4b5 100644 --- a/test/features/to-string/precision/unsigned/arguments/memory-optimized-number-texture.js +++ b/test/features/to-string/precision/unsigned/arguments/memory-optimized-number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments MemoryOptimizedNumberTexture'); diff --git a/test/features/to-string/precision/unsigned/arguments/number-texture.js b/test/features/to-string/precision/unsigned/arguments/number-texture.js index a0012393..dd0e89cf 100644 --- a/test/features/to-string/precision/unsigned/arguments/number-texture.js +++ b/test/features/to-string/precision/unsigned/arguments/number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments NumberTexture'); diff --git a/test/features/to-string/precision/unsigned/constants/array.js b/test/features/to-string/precision/unsigned/constants/array.js index 5e7073c3..b98da77f 100644 --- a/test/features/to-string/precision/unsigned/constants/array.js +++ b/test/features/to-string/precision/unsigned/constants/array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants Array'); diff --git a/test/features/to-string/precision/unsigned/constants/array2.js b/test/features/to-string/precision/unsigned/constants/array2.js index bce3d0eb..f2559568 100644 --- a/test/features/to-string/precision/unsigned/constants/array2.js +++ b/test/features/to-string/precision/unsigned/constants/array2.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants Array(2)'); diff --git a/test/features/to-string/precision/unsigned/constants/array2d.js b/test/features/to-string/precision/unsigned/constants/array2d.js index 5728c074..3d97006e 100644 --- a/test/features/to-string/precision/unsigned/constants/array2d.js +++ b/test/features/to-string/precision/unsigned/constants/array2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants Array2D'); diff --git a/test/features/to-string/precision/unsigned/constants/array3.js b/test/features/to-string/precision/unsigned/constants/array3.js index fae63691..050234c7 100644 --- a/test/features/to-string/precision/unsigned/constants/array3.js +++ b/test/features/to-string/precision/unsigned/constants/array3.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants Array(3)'); diff --git a/test/features/to-string/precision/unsigned/constants/array3d.js b/test/features/to-string/precision/unsigned/constants/array3d.js index 680ae6e2..43e1fe70 100644 --- a/test/features/to-string/precision/unsigned/constants/array3d.js +++ b/test/features/to-string/precision/unsigned/constants/array3d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants Array3D'); diff --git a/test/features/to-string/precision/unsigned/constants/array4.js b/test/features/to-string/precision/unsigned/constants/array4.js index a0a93754..2696f826 100644 --- a/test/features/to-string/precision/unsigned/constants/array4.js +++ b/test/features/to-string/precision/unsigned/constants/array4.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants Array(4)'); diff --git a/test/features/to-string/precision/unsigned/constants/boolean.js b/test/features/to-string/precision/unsigned/constants/boolean.js index 6e65b715..57b6251a 100644 --- a/test/features/to-string/precision/unsigned/constants/boolean.js +++ b/test/features/to-string/precision/unsigned/constants/boolean.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants Boolean'); diff --git a/test/features/to-string/precision/unsigned/constants/float.js b/test/features/to-string/precision/unsigned/constants/float.js index abdebe81..d4dcaf1b 100644 --- a/test/features/to-string/precision/unsigned/constants/float.js +++ b/test/features/to-string/precision/unsigned/constants/float.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants Float'); diff --git a/test/features/to-string/precision/unsigned/constants/html-image-array.js b/test/features/to-string/precision/unsigned/constants/html-image-array.js index db3f5267..b21ba210 100644 --- a/test/features/to-string/precision/unsigned/constants/html-image-array.js +++ b/test/features/to-string/precision/unsigned/constants/html-image-array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, CPUKernel } = require('../../../../../../src'); +const { GPU, CPUKernel } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants HTMLImageArray'); diff --git a/test/features/to-string/precision/unsigned/constants/html-image.js b/test/features/to-string/precision/unsigned/constants/html-image.js index f69bb291..7eaec51b 100644 --- a/test/features/to-string/precision/unsigned/constants/html-image.js +++ b/test/features/to-string/precision/unsigned/constants/html-image.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, utils } = require('../../../../../../src'); +const { GPU, utils } = require('../../../../../../dist/gpu.js'); const { loadImage, imageToArray, check2DImage } = require('../../../../../browser-test-utils'); describe('feature: to-string unsigned precision constants HTMLImage'); diff --git a/test/features/to-string/precision/unsigned/constants/input.js b/test/features/to-string/precision/unsigned/constants/input.js index 8b435a2a..427373e5 100644 --- a/test/features/to-string/precision/unsigned/constants/input.js +++ b/test/features/to-string/precision/unsigned/constants/input.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, input } = require('../../../../../../src'); +const { GPU, input } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants Input'); diff --git a/test/features/to-string/precision/unsigned/constants/integer.js b/test/features/to-string/precision/unsigned/constants/integer.js index 8244c9d8..b128e968 100644 --- a/test/features/to-string/precision/unsigned/constants/integer.js +++ b/test/features/to-string/precision/unsigned/constants/integer.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants Integer'); diff --git a/test/features/to-string/precision/unsigned/constants/memory-optimized-number-texture.js b/test/features/to-string/precision/unsigned/constants/memory-optimized-number-texture.js index bb65fcc9..b5eb8ce7 100644 --- a/test/features/to-string/precision/unsigned/constants/memory-optimized-number-texture.js +++ b/test/features/to-string/precision/unsigned/constants/memory-optimized-number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants MemoryOptimizedNumberTexture'); diff --git a/test/features/to-string/precision/unsigned/constants/number-texture.js b/test/features/to-string/precision/unsigned/constants/number-texture.js index b41fd742..b7171e28 100644 --- a/test/features/to-string/precision/unsigned/constants/number-texture.js +++ b/test/features/to-string/precision/unsigned/constants/number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants NumberTexture'); diff --git a/test/features/to-string/precision/unsigned/graphical.js b/test/features/to-string/precision/unsigned/graphical.js index b6198589..6444ad13 100644 --- a/test/features/to-string/precision/unsigned/graphical.js +++ b/test/features/to-string/precision/unsigned/graphical.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../src'); +const { GPU } = require('../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision graphical'); diff --git a/test/features/to-string/precision/unsigned/kernel-map/array/array.js b/test/features/to-string/precision/unsigned/kernel-map/array/array.js index 093004f3..f8991b4e 100644 --- a/test/features/to-string/precision/unsigned/kernel-map/array/array.js +++ b/test/features/to-string/precision/unsigned/kernel-map/array/array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision array style kernel map returns Array'); diff --git a/test/features/to-string/precision/unsigned/kernel-map/array/array2d.js b/test/features/to-string/precision/unsigned/kernel-map/array/array2d.js index e4d8c555..3898e7f7 100644 --- a/test/features/to-string/precision/unsigned/kernel-map/array/array2d.js +++ b/test/features/to-string/precision/unsigned/kernel-map/array/array2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision array style kernel map returns Array2D'); diff --git a/test/features/to-string/precision/unsigned/kernel-map/array/array3d.js b/test/features/to-string/precision/unsigned/kernel-map/array/array3d.js index 631d0c7f..283d9825 100644 --- a/test/features/to-string/precision/unsigned/kernel-map/array/array3d.js +++ b/test/features/to-string/precision/unsigned/kernel-map/array/array3d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision array style kernel map returns Array3d'); diff --git a/test/features/to-string/precision/unsigned/kernel-map/array/memory-optimized-number-texture.js b/test/features/to-string/precision/unsigned/kernel-map/array/memory-optimized-number-texture.js index 783dbf72..8299cf35 100644 --- a/test/features/to-string/precision/unsigned/kernel-map/array/memory-optimized-number-texture.js +++ b/test/features/to-string/precision/unsigned/kernel-map/array/memory-optimized-number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision array style kernel map returns MemoryOptimizedNumberTexture'); diff --git a/test/features/to-string/precision/unsigned/kernel-map/array/number-texture.js b/test/features/to-string/precision/unsigned/kernel-map/array/number-texture.js index 3ace604a..7a8240b7 100644 --- a/test/features/to-string/precision/unsigned/kernel-map/array/number-texture.js +++ b/test/features/to-string/precision/unsigned/kernel-map/array/number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision array style kernel map returns NumberTexture'); diff --git a/test/features/to-string/precision/unsigned/kernel-map/object/array.js b/test/features/to-string/precision/unsigned/kernel-map/object/array.js index 87c40562..02b069c9 100644 --- a/test/features/to-string/precision/unsigned/kernel-map/object/array.js +++ b/test/features/to-string/precision/unsigned/kernel-map/object/array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision object style returns Array'); diff --git a/test/features/to-string/precision/unsigned/kernel-map/object/array2d.js b/test/features/to-string/precision/unsigned/kernel-map/object/array2d.js index 05b4231e..b5ed4755 100644 --- a/test/features/to-string/precision/unsigned/kernel-map/object/array2d.js +++ b/test/features/to-string/precision/unsigned/kernel-map/object/array2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision object style returns Array2D'); diff --git a/test/features/to-string/precision/unsigned/kernel-map/object/array3d.js b/test/features/to-string/precision/unsigned/kernel-map/object/array3d.js index 16f1fede..24ffa8d6 100644 --- a/test/features/to-string/precision/unsigned/kernel-map/object/array3d.js +++ b/test/features/to-string/precision/unsigned/kernel-map/object/array3d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision object style returns Array3d'); diff --git a/test/features/to-string/precision/unsigned/kernel-map/object/memory-optimized-number-texture.js b/test/features/to-string/precision/unsigned/kernel-map/object/memory-optimized-number-texture.js index 6df0bf2e..6ba5f013 100644 --- a/test/features/to-string/precision/unsigned/kernel-map/object/memory-optimized-number-texture.js +++ b/test/features/to-string/precision/unsigned/kernel-map/object/memory-optimized-number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision object style kernel map returns MemoryOptimizedNumberTexture'); diff --git a/test/features/to-string/precision/unsigned/kernel-map/object/number-texture.js b/test/features/to-string/precision/unsigned/kernel-map/object/number-texture.js index 22607128..7f10c43c 100644 --- a/test/features/to-string/precision/unsigned/kernel-map/object/number-texture.js +++ b/test/features/to-string/precision/unsigned/kernel-map/object/number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision object style kernel map returns NumberTexture'); diff --git a/test/features/to-string/precision/unsigned/returns/array.js b/test/features/to-string/precision/unsigned/returns/array.js index 612aad73..5164f74b 100644 --- a/test/features/to-string/precision/unsigned/returns/array.js +++ b/test/features/to-string/precision/unsigned/returns/array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision returns Array'); diff --git a/test/features/to-string/precision/unsigned/returns/array2d.js b/test/features/to-string/precision/unsigned/returns/array2d.js index eacfc731..7f668cbd 100644 --- a/test/features/to-string/precision/unsigned/returns/array2d.js +++ b/test/features/to-string/precision/unsigned/returns/array2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision returns Array2D'); diff --git a/test/features/to-string/precision/unsigned/returns/array3d.js b/test/features/to-string/precision/unsigned/returns/array3d.js index edebde18..47e302de 100644 --- a/test/features/to-string/precision/unsigned/returns/array3d.js +++ b/test/features/to-string/precision/unsigned/returns/array3d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision returns Array3d'); diff --git a/test/features/type-management.js b/test/features/type-management.js index f834a3c8..dd267948 100644 --- a/test/features/type-management.js +++ b/test/features/type-management.js @@ -1,5 +1,5 @@ const { assert, test, module: describe, only } = require('qunit'); -const { WebGLFunctionNode, WebGL2FunctionNode, CPUFunctionNode } = require('../../src'); +const { WebGLFunctionNode, WebGL2FunctionNode, CPUFunctionNode } = require('../../dist/gpu.js'); describe('features: type management'); diff --git a/test/features/unsigned-precision-textures.js b/test/features/unsigned-precision-textures.js index 167a3fcd..031247f0 100644 --- a/test/features/unsigned-precision-textures.js +++ b/test/features/unsigned-precision-textures.js @@ -1,5 +1,5 @@ const { assert, skip, test, only, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: unsigned precision textures'); diff --git a/test/index.js b/test/index.js index d24b5b6a..34a21555 100644 --- a/test/index.js +++ b/test/index.js @@ -1,72 +1,73 @@ -const { expect } = require('chai'); - -const GPU = require('../src/index.js'); - -describe('Test Node GPU', () => { - describe('gpu mode', () => { - it('should find and use gpu runner', () => { - const gpu = new GPU({ mode: 'gpu' }); - - const kernel = gpu.createKernel(function() { - return 1; - }).setOutput([1]); - - const result = kernel(); - - expect(gpu.runner.constructor).to.equal(GPU.HeadlessGLRunner); - expect(result[0]).to.equal(1); - }); - - it('supports 2x2 size', () => { - const gpu = new GPU({ mode: 'gpu' }); - - const kernel = gpu.createKernel(function() { - return this.thread.x * this.thread.y; - }).setOutput([2, 2]); - - const result = kernel(); - - expect(gpu.runner.constructor).to.equal(GPU.HeadlessGLRunner); - expect(result).to.deep.equal( - [ - Float32Array.from([0,0]), - Float32Array.from([0,1]) - ] - ); - }); - }); - - describe('cpu mode', () => { - it('should find and use gpu runner', () => { - const gpu = new GPU({ mode: 'cpu' }); - - const kernel = gpu.createKernel(function() { - return 1; - }).setOutput([1]); - - const result = kernel(); - - expect(gpu.runner.constructor).to.equal(GPU.CPURunner); - expect(result[0]).to.equal(1); - }); - - it('supports 2x2 size', () => { - const gpu = new GPU({ mode: 'cpu' }); - - const kernel = gpu.createKernel(function() { - return this.thread.x * this.thread.y; - }).setOutput([2, 2]); - - const result = kernel(); - - expect(gpu.runner.constructor).to.equal(GPU.CPURunner); - expect(result).to.deep.equal( - [ - Float32Array.from([0,0]), - Float32Array.from([0,1]) - ] - ); - }); - }); -}); - +const { module: describe, test: it } = require('qunit'); +const { expect } = require('chai'); + +const { GPU } = require('../dist/gpu.js'); + +describe('Test Node GPU', () => { + describe('gpu mode', () => { + it('should find and use gpu runner', () => { + const gpu = new GPU({ mode: 'gpu' }); + + const kernel = gpu.createKernel(function() { + return 1; + }).setOutput([1]); + + const result = kernel(); + + expect(gpu.runner.constructor).to.equal(GPU.HeadlessGLRunner); + expect(result[0]).to.equal(1); + }); + + it('supports 2x2 size', () => { + const gpu = new GPU({ mode: 'gpu' }); + + const kernel = gpu.createKernel(function() { + return this.thread.x * this.thread.y; + }).setOutput([2, 2]); + + const result = kernel(); + + expect(gpu.runner.constructor).to.equal(GPU.HeadlessGLRunner); + expect(result).to.deep.equal( + [ + Float32Array.from([0,0]), + Float32Array.from([0,1]) + ] + ); + }); + }); + + describe('cpu mode', () => { + it('should find and use gpu runner', () => { + const gpu = new GPU({ mode: 'cpu' }); + + const kernel = gpu.createKernel(function() { + return 1; + }).setOutput([1]); + + const result = kernel(); + + expect(gpu.runner.constructor).to.equal(GPU.CPURunner); + expect(result[0]).to.equal(1); + }); + + it('supports 2x2 size', () => { + const gpu = new GPU({ mode: 'cpu' }); + + const kernel = gpu.createKernel(function() { + return this.thread.x * this.thread.y; + }).setOutput([2, 2]); + + const result = kernel(); + + expect(gpu.runner.constructor).to.equal(GPU.CPURunner); + expect(result).to.deep.equal( + [ + Float32Array.from([0,0]), + Float32Array.from([0,1]) + ] + ); + }); + }); +}); + diff --git a/test/internal/.DS_Store b/test/internal/.DS_Store deleted file mode 100644 index f206f7d1..00000000 Binary files a/test/internal/.DS_Store and /dev/null differ diff --git a/test/internal/argument-texture-switching.js b/test/internal/argument-texture-switching.js index eb5a1f8b..f2ea5ccd 100644 --- a/test/internal/argument-texture-switching.js +++ b/test/internal/argument-texture-switching.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: argument texture switching'); diff --git a/test/internal/backend/.DS_Store b/test/internal/backend/.DS_Store deleted file mode 100644 index d9cd1ee4..00000000 Binary files a/test/internal/backend/.DS_Store and /dev/null differ diff --git a/test/internal/backend/cpu/function-node.js b/test/internal/backend/cpu/function-node.js index 5fe47d99..f4c51325 100644 --- a/test/internal/backend/cpu/function-node.js +++ b/test/internal/backend/cpu/function-node.js @@ -1,6 +1,6 @@ const { assert, skip, test, module: describe, only } = require('qunit'); const sinon = require('sinon'); -const { CPUFunctionNode } = require('../../../../src'); +const { CPUFunctionNode } = require('../../../../dist/gpu.js'); describe('internal: CPUFunctionNode'); diff --git a/test/internal/backend/headless-gl/kernel/index.js b/test/internal/backend/headless-gl/kernel/index.js index 7e02a453..d2252b24 100644 --- a/test/internal/backend/headless-gl/kernel/index.js +++ b/test/internal/backend/headless-gl/kernel/index.js @@ -10,7 +10,7 @@ describe('internal: HeadlessGLKernel'); } }; // this is done late on purpose! Do not change this, as it causes HeadlessGL to initialize with certain values -const { HeadlessGLKernel } = require('../../../../../src'); +const { HeadlessGLKernel } = require('../../../../../dist/gpu.js'); HeadlessGLKernel.setupFeatureChecks(); assert.ok(true); delete global.document; diff --git a/test/internal/backend/web-gl/function-node/index.js b/test/internal/backend/web-gl/function-node/index.js index dc6f1e48..def4cb5c 100644 --- a/test/internal/backend/web-gl/function-node/index.js +++ b/test/internal/backend/web-gl/function-node/index.js @@ -1,6 +1,6 @@ const { assert, skip, test, module: describe, only } = require('qunit'); const sinon = require('sinon'); -const { WebGLFunctionNode } = require('../../../../../src'); +const { WebGLFunctionNode } = require('../../../../../dist/gpu.js'); describe('internal: WebGLFunctionNode'); diff --git a/test/internal/backend/web-gl/kernel/index.js b/test/internal/backend/web-gl/kernel/index.js index 9ccd37a8..c0cbc85d 100644 --- a/test/internal/backend/web-gl/kernel/index.js +++ b/test/internal/backend/web-gl/kernel/index.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { WebGLKernel } = require('../../../../../src'); +const { WebGLKernel } = require('../../../../../dist/gpu.js'); describe('internal: WebGLKernel'); diff --git a/test/internal/backend/web-gl/kernel/setupArguments.js b/test/internal/backend/web-gl/kernel/setupArguments.js index 83e4bbc8..024e1ecc 100644 --- a/test/internal/backend/web-gl/kernel/setupArguments.js +++ b/test/internal/backend/web-gl/kernel/setupArguments.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { WebGLKernel, input } = require('../../../../../src'); +const { WebGLKernel, input } = require('../../../../../dist/gpu.js'); describe('internal WebGLKernel.setupArguments Array'); const gl = { diff --git a/test/internal/backend/web-gl/kernel/setupConstants.js b/test/internal/backend/web-gl/kernel/setupConstants.js index 6e38288e..536e72ac 100644 --- a/test/internal/backend/web-gl/kernel/setupConstants.js +++ b/test/internal/backend/web-gl/kernel/setupConstants.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { WebGLKernel, input } = require('../../../../../src'); +const { WebGLKernel, input } = require('../../../../../dist/gpu.js'); describe('internal WebGLKernel.setupConstants Array'); const gl = { diff --git a/test/internal/backend/web-gl2/.DS_Store b/test/internal/backend/web-gl2/.DS_Store deleted file mode 100644 index 3e175002..00000000 Binary files a/test/internal/backend/web-gl2/.DS_Store and /dev/null differ diff --git a/test/internal/backend/web-gl2/kernel/index.js b/test/internal/backend/web-gl2/kernel/index.js index 97221a5c..e92cd2c4 100644 --- a/test/internal/backend/web-gl2/kernel/index.js +++ b/test/internal/backend/web-gl2/kernel/index.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { WebGL2Kernel } = require('../../../../../src'); +const { WebGL2Kernel } = require('../../../../../dist/gpu.js'); describe('internal: WebGL2Kernel'); diff --git a/test/internal/backend/web-gl2/kernel/setupArguments.js b/test/internal/backend/web-gl2/kernel/setupArguments.js index b78892f2..b4f860ca 100644 --- a/test/internal/backend/web-gl2/kernel/setupArguments.js +++ b/test/internal/backend/web-gl2/kernel/setupArguments.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { WebGL2Kernel, input } = require('../../../../../src'); +const { WebGL2Kernel, input } = require('../../../../../dist/gpu.js'); describe('internal WebGL2Kernel.setupArguments Array'); const gl = { diff --git a/test/internal/backend/web-gl2/kernel/setupConstants.js b/test/internal/backend/web-gl2/kernel/setupConstants.js index d0649b22..dabcce64 100644 --- a/test/internal/backend/web-gl2/kernel/setupConstants.js +++ b/test/internal/backend/web-gl2/kernel/setupConstants.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { WebGL2Kernel, input } = require('../../../../../src'); +const { WebGL2Kernel, input } = require('../../../../../dist/gpu.js'); describe('internal WebGL2Kernel.setupConstants Array'); const gl = { diff --git a/test/internal/boolean.js b/test/internal/boolean.js index abb2a9df..a65a586f 100644 --- a/test/internal/boolean.js +++ b/test/internal/boolean.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: boolean'); diff --git a/test/internal/casting.js b/test/internal/casting.js index 89635afb..84b852b3 100644 --- a/test/internal/casting.js +++ b/test/internal/casting.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: casting'); diff --git a/test/internal/constants-texture-switching.js b/test/internal/constants-texture-switching.js index d00951bc..78d2fdd0 100644 --- a/test/internal/constants-texture-switching.js +++ b/test/internal/constants-texture-switching.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: constants texture switching'); diff --git a/test/internal/constructor-features.js b/test/internal/constructor-features.js index be654879..d0b68e00 100644 --- a/test/internal/constructor-features.js +++ b/test/internal/constructor-features.js @@ -1,5 +1,5 @@ const { assert, test, module: describe, only, skip } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: constructor features'); diff --git a/test/internal/context-inheritance.js b/test/internal/context-inheritance.js index 01f7ce4e..e44f2924 100644 --- a/test/internal/context-inheritance.js +++ b/test/internal/context-inheritance.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, WebGLKernel, WebGL2Kernel, HeadlessGLKernel } = require('../../src'); +const { GPU, WebGLKernel, WebGL2Kernel, HeadlessGLKernel } = require('../../dist/gpu.js'); describe('internal: context inheritance'); diff --git a/test/internal/deep-types.js b/test/internal/deep-types.js index 5fa1cd43..8e08a9f3 100644 --- a/test/internal/deep-types.js +++ b/test/internal/deep-types.js @@ -1,6 +1,6 @@ const sinon = require('sinon'); const { assert, test, module: describe, only, skip } = require('qunit'); -const { GPU, FunctionBuilder } = require('../../src'); +const { GPU, FunctionBuilder } = require('../../dist/gpu.js'); describe('internal: deep types'); diff --git a/test/internal/deprecated.js b/test/internal/deprecated.js index f5c2848b..1efa83a0 100644 --- a/test/internal/deprecated.js +++ b/test/internal/deprecated.js @@ -1,5 +1,5 @@ const { assert, test, module: describe, only, skip } = require('qunit'); -const { GPU, Kernel } = require('../../src'); +const { GPU, Kernel } = require('../../dist/gpu.js'); describe('internal: deprecated'); diff --git a/test/internal/function-builder.js b/test/internal/function-builder.js index 7755507a..291f71e5 100644 --- a/test/internal/function-builder.js +++ b/test/internal/function-builder.js @@ -1,5 +1,5 @@ const { assert, test, module: describe, only } = require('qunit'); -const { FunctionBuilder, CPUFunctionNode, WebGL2FunctionNode, WebGLFunctionNode } = require('../../src'); +const { FunctionBuilder, CPUFunctionNode, WebGL2FunctionNode, WebGLFunctionNode } = require('../../dist/gpu.js'); describe('internal: function builder'); diff --git a/test/internal/function-composition.js b/test/internal/function-composition.js index a65cc81d..14cc8572 100644 --- a/test/internal/function-composition.js +++ b/test/internal/function-composition.js @@ -1,6 +1,6 @@ const { assert, test, skip, module: describe, only } = require('qunit'); const sinon = require('sinon'); -const { CPUFunctionNode, FunctionBuilder, GPU, WebGL2FunctionNode, WebGLFunctionNode } = require('../../src'); +const { CPUFunctionNode, FunctionBuilder, GPU, WebGL2FunctionNode, WebGLFunctionNode } = require('../../dist/gpu.js'); describe('internal: function composition return values'); diff --git a/test/internal/function-node.js b/test/internal/function-node.js index fba0fc39..69652932 100644 --- a/test/internal/function-node.js +++ b/test/internal/function-node.js @@ -1,5 +1,5 @@ const { assert, test, module: describe, only } = require('qunit'); -const { CPUFunctionNode, WebGLFunctionNode, WebGL2FunctionNode } = require('../../src'); +const { CPUFunctionNode, WebGLFunctionNode, WebGL2FunctionNode } = require('../../dist/gpu.js'); describe('internal: function node'); diff --git a/test/internal/function-return-type-detection.js b/test/internal/function-return-type-detection.js index f8bd462a..952ed1e0 100644 --- a/test/internal/function-return-type-detection.js +++ b/test/internal/function-return-type-detection.js @@ -1,5 +1,5 @@ const { assert, test, skip, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: Function return type detection'); diff --git a/test/internal/gpu-methods.js b/test/internal/gpu-methods.js index b9acb266..dbc6617a 100644 --- a/test/internal/gpu-methods.js +++ b/test/internal/gpu-methods.js @@ -1,5 +1,5 @@ const { assert, test, skip, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: GPU methods'); diff --git a/test/internal/implied-else.js b/test/internal/implied-else.js index 9eae23b7..68e40520 100644 --- a/test/internal/implied-else.js +++ b/test/internal/implied-else.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: Implied else'); diff --git a/test/internal/kernel.js b/test/internal/kernel.js index e3fdb187..247686c9 100644 --- a/test/internal/kernel.js +++ b/test/internal/kernel.js @@ -1,5 +1,5 @@ const { assert, test, module: describe, skip } = require('qunit'); -const { GPU, CPUKernel, WebGLKernel, WebGL2Kernel, HeadlessGLKernel } = require('../../src'); +const { GPU, CPUKernel, WebGLKernel, WebGL2Kernel, HeadlessGLKernel } = require('../../dist/gpu.js'); describe('internal: kernel'); diff --git a/test/internal/loop-int.js b/test/internal/loop-int.js index d9322a7e..cda49977 100644 --- a/test/internal/loop-int.js +++ b/test/internal/loop-int.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, WebGLFunctionNode, WebGL2FunctionNode } = require('../../src'); +const { GPU, WebGLFunctionNode, WebGL2FunctionNode } = require('../../dist/gpu.js'); describe('internal: loop int'); test('loop int constant output webgl', () => { diff --git a/test/internal/loop-max.js b/test/internal/loop-max.js index eb11fa76..b06b480e 100644 --- a/test/internal/loop-max.js +++ b/test/internal/loop-max.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, WebGLFunctionNode, WebGL2FunctionNode } = require('../../src'); +const { GPU, WebGLFunctionNode, WebGL2FunctionNode } = require('../../dist/gpu.js'); describe('internal: loop max'); diff --git a/test/internal/math.random.js b/test/internal/math.random.js index b1d11c9a..b34a4ab7 100644 --- a/test/internal/math.random.js +++ b/test/internal/math.random.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('Math.random() unique'); diff --git a/test/internal/matrix-multiply-precision.js b/test/internal/matrix-multiply-precision.js index 126f20d8..d516b5cf 100644 --- a/test/internal/matrix-multiply-precision.js +++ b/test/internal/matrix-multiply-precision.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: matrix multiply precision'); diff --git a/test/internal/mixed-memory-optimize.js b/test/internal/mixed-memory-optimize.js index efdd92dd..cc3e46ea 100644 --- a/test/internal/mixed-memory-optimize.js +++ b/test/internal/mixed-memory-optimize.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: mixed memory optimize'); diff --git a/test/internal/modes.js b/test/internal/modes.js index 997c9770..a28758ee 100644 --- a/test/internal/modes.js +++ b/test/internal/modes.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU, WebGLKernel, WebGL2Kernel, HeadlessGLKernel, CPUKernel } = require('../../src'); +const { GPU, WebGLKernel, WebGL2Kernel, HeadlessGLKernel, CPUKernel } = require('../../dist/gpu.js'); describe('internal: modes'); diff --git a/test/internal/overloading.js b/test/internal/overloading.js index f97a4cf5..219f9347 100644 --- a/test/internal/overloading.js +++ b/test/internal/overloading.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: overloading'); // TODO: planned for after v2, overload generated functions so as to cut down on casting diff --git a/test/internal/precision.js b/test/internal/precision.js index e3f06cec..8948f5fd 100644 --- a/test/internal/precision.js +++ b/test/internal/precision.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: precision'); diff --git a/test/internal/texture-index.js b/test/internal/texture-index.js index 1f5af264..29c58e70 100644 --- a/test/internal/texture-index.js +++ b/test/internal/texture-index.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: texture index'); function createKernelWithNumberConstants(mode) { diff --git a/test/internal/utils.js b/test/internal/utils.js index f72f10ed..b804f225 100644 --- a/test/internal/utils.js +++ b/test/internal/utils.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { utils } = require('../../src'); +const { utils } = require('../../dist/gpu.js'); describe('internal: utils'); diff --git a/test/issues/114-create-kernel-map-run-second-time.js b/test/issues/114-create-kernel-map-run-second-time.js index 7d15c517..889e1ad1 100644 --- a/test/issues/114-create-kernel-map-run-second-time.js +++ b/test/issues/114-create-kernel-map-run-second-time.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue # 114'); function secondKernelMap(mode) { diff --git a/test/issues/116-multiple-kernels-run-again.js b/test/issues/116-multiple-kernels-run-again.js index a3bd4a22..c5231bce 100644 --- a/test/issues/116-multiple-kernels-run-again.js +++ b/test/issues/116-multiple-kernels-run-again.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #116'); diff --git a/test/issues/130-typed-array.js b/test/issues/130-typed-array.js index ab79483e..c617a9ba 100644 --- a/test/issues/130-typed-array.js +++ b/test/issues/130-typed-array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #130'); function typedArrays(mode) { diff --git a/test/issues/147-missing-constant.js b/test/issues/147-missing-constant.js index f6d8a5d9..3804e447 100644 --- a/test/issues/147-missing-constant.js +++ b/test/issues/147-missing-constant.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #147'); diff --git a/test/issues/152-for-vars.js b/test/issues/152-for-vars.js index af1eef22..848879cc 100644 --- a/test/issues/152-for-vars.js +++ b/test/issues/152-for-vars.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #152'); diff --git a/test/issues/159-3d.js b/test/issues/159-3d.js index 4f4f66ca..d78ce0ee 100644 --- a/test/issues/159-3d.js +++ b/test/issues/159-3d.js @@ -3,7 +3,7 @@ const { assert, skip, test, module: describe } = require('qunit'); describe('issue # 159'); (function() { - const { GPU } = require('../../src'); + const { GPU } = require('../../dist/gpu.js'); function threeD(mode) { const gpu = new GPU({ mode }); diff --git a/test/issues/174-webgl-context-warning.js b/test/issues/174-webgl-context-warning.js index b9329011..ce4b7c6a 100644 --- a/test/issues/174-webgl-context-warning.js +++ b/test/issues/174-webgl-context-warning.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue # 174'); diff --git a/test/issues/195-read-from-texture2d.js b/test/issues/195-read-from-texture2d.js index 00e1e68f..4d8570b9 100644 --- a/test/issues/195-read-from-texture2d.js +++ b/test/issues/195-read-from-texture2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #195'); function makeKernel(gpu) { diff --git a/test/issues/207-same-function-reuse.js b/test/issues/207-same-function-reuse.js index c117ada9..25f6e755 100644 --- a/test/issues/207-same-function-reuse.js +++ b/test/issues/207-same-function-reuse.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #207'); diff --git a/test/issues/212-funky-function-support.js b/test/issues/212-funky-function-support.js index de65e5e3..e5ed0584 100644 --- a/test/issues/212-funky-function-support.js +++ b/test/issues/212-funky-function-support.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #212'); diff --git a/test/issues/233-kernel-map-single-precision.js b/test/issues/233-kernel-map-single-precision.js index c82ac744..0f5402e5 100644 --- a/test/issues/233-kernel-map-single-precision.js +++ b/test/issues/233-kernel-map-single-precision.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue # 233'); diff --git a/test/issues/241-CPU-vs-GPU-maps-output-differently.js b/test/issues/241-CPU-vs-GPU-maps-output-differently.js index 2297a178..e86424ac 100644 --- a/test/issues/241-CPU-vs-GPU-maps-output-differently.js +++ b/test/issues/241-CPU-vs-GPU-maps-output-differently.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #241'); diff --git a/test/issues/259-atan2.js b/test/issues/259-atan2.js index 1aa9a122..30d7550d 100644 --- a/test/issues/259-atan2.js +++ b/test/issues/259-atan2.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #259'); diff --git a/test/issues/263-to-string.js b/test/issues/263-to-string.js index f811e017..7723f544 100644 --- a/test/issues/263-to-string.js +++ b/test/issues/263-to-string.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #263'); diff --git a/test/issues/267-immutable-sub-kernels.js b/test/issues/267-immutable-sub-kernels.js index eda40838..de4052f3 100644 --- a/test/issues/267-immutable-sub-kernels.js +++ b/test/issues/267-immutable-sub-kernels.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #267 kernel'); diff --git a/test/issues/270-cache.js b/test/issues/270-cache.js index d08a6e80..23a44763 100644 --- a/test/issues/270-cache.js +++ b/test/issues/270-cache.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { WebGLKernel } = require('../../src'); +const { WebGLKernel } = require('../../dist/gpu.js'); describe('issue # 270'); diff --git a/test/issues/279-wrong-canvas-size.js b/test/issues/279-wrong-canvas-size.js index ea072def..40978b3d 100644 --- a/test/issues/279-wrong-canvas-size.js +++ b/test/issues/279-wrong-canvas-size.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #279'); diff --git a/test/issues/300-nested-array-index.js b/test/issues/300-nested-array-index.js index c20d59cf..bbeb5f8a 100644 --- a/test/issues/300-nested-array-index.js +++ b/test/issues/300-nested-array-index.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #300'); diff --git a/test/issues/31-nested-var-declare-test.js b/test/issues/31-nested-var-declare-test.js index f87deb41..3e81876f 100644 --- a/test/issues/31-nested-var-declare-test.js +++ b/test/issues/31-nested-var-declare-test.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, FunctionBuilder, WebGLFunctionNode, WebGL2FunctionNode, CPUFunctionNode } = require('../../src'); +const { GPU, FunctionBuilder, WebGLFunctionNode, WebGL2FunctionNode, CPUFunctionNode } = require('../../dist/gpu.js'); describe('issue #31 redeclare'); diff --git a/test/issues/313-variable-lookup.js b/test/issues/313-variable-lookup.js index e1dd00e9..31c73276 100644 --- a/test/issues/313-variable-lookup.js +++ b/test/issues/313-variable-lookup.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #313'); diff --git a/test/issues/314-large-input-array-addressing.js b/test/issues/314-large-input-array-addressing.js index 27882652..a6dc9de3 100644 --- a/test/issues/314-large-input-array-addressing.js +++ b/test/issues/314-large-input-array-addressing.js @@ -1,59 +1,59 @@ -const { assert, skip, test, module: describe } = require('qunit'); -const { GPU, WebGLKernel, HeadlessGLKernel } = require('../../src'); - -describe('issue #314'); - -// max size of ok addressing was 8388608, 8388609 is shifted by 1 so index seems to be 8388610 -// after this fix max addressing is 2^31 which is the max a int32 can handle -// run out of heap before being able to create a butter that big! -// wanted to use uints but caused more problems than it solved -const DATA_MAX = (GPU.isHeadlessGLSupported ? HeadlessGLKernel : WebGLKernel).features.maxTextureSize*8; -const divisor = 100; -const data = new Uint16Array(DATA_MAX); -let v = 0; -for (let i = 0; i < DATA_MAX/divisor; i++) { - for (let j = 0; j < divisor; j++) { - data[i*divisor + j] = v++; - } -} -function buildLargeArrayAddressKernel(mode) { - const gpu = new GPU({ mode }); - const largeArrayAddressKernel = gpu.createKernel(function(data) { - return data[this.thread.x]; - }, { - precision: 'unsigned', - }) - .setOutput([DATA_MAX]); - - const result = largeArrayAddressKernel(data); - - let same = true; - let i = 0; - for (; i < DATA_MAX; i++) { - if (result[i] !== data[i]) { - same = false; - break; - } - } - assert.ok(same, "not all elements are the same, failed on index:" + i); - gpu.destroy(); -} - -test('Issue #314 Large array addressing - auto', () => { - buildLargeArrayAddressKernel(null); -}); - -test('Issue #314 Large array addressing - gpu', () => { - buildLargeArrayAddressKernel('gpu'); -}); - -(GPU.isWebGLSupported ? test : skip)('Issue #314 Large array addressing - webgl', () => { - buildLargeArrayAddressKernel('webgl'); -}); - -(GPU.isWebGL2Supported ? test : skip)('Issue #314 Large array addressing - webgl2', () => { - buildLargeArrayAddressKernel('webgl2'); -}); -(GPU.isHeadlessGLSupported ? test : skip)('Issue #314 Large array addressing - headlessgl', () => { - buildLargeArrayAddressKernel('headlessgl'); -}); +const { assert, skip, test, module: describe } = require('qunit'); +const { GPU, WebGLKernel, HeadlessGLKernel } = require('../../dist/gpu.js'); + +describe('issue #314'); + +// max size of ok addressing was 8388608, 8388609 is shifted by 1 so index seems to be 8388610 +// after this fix max addressing is 2^31 which is the max a int32 can handle +// run out of heap before being able to create a butter that big! +// wanted to use uints but caused more problems than it solved +const DATA_MAX = (GPU.isHeadlessGLSupported ? HeadlessGLKernel : WebGLKernel).features.maxTextureSize*8; +const divisor = 100; +const data = new Uint16Array(DATA_MAX); +let v = 0; +for (let i = 0; i < DATA_MAX/divisor; i++) { + for (let j = 0; j < divisor; j++) { + data[i*divisor + j] = v++; + } +} +function buildLargeArrayAddressKernel(mode) { + const gpu = new GPU({ mode }); + const largeArrayAddressKernel = gpu.createKernel(function(data) { + return data[this.thread.x]; + }, { + precision: 'unsigned', + }) + .setOutput([DATA_MAX]); + + const result = largeArrayAddressKernel(data); + + let same = true; + let i = 0; + for (; i < DATA_MAX; i++) { + if (result[i] !== data[i]) { + same = false; + break; + } + } + assert.ok(same, "not all elements are the same, failed on index:" + i); + gpu.destroy(); +} + +test('Issue #314 Large array addressing - auto', () => { + buildLargeArrayAddressKernel(null); +}); + +test('Issue #314 Large array addressing - gpu', () => { + buildLargeArrayAddressKernel('gpu'); +}); + +(GPU.isWebGLSupported ? test : skip)('Issue #314 Large array addressing - webgl', () => { + buildLargeArrayAddressKernel('webgl'); +}); + +(GPU.isWebGL2Supported ? test : skip)('Issue #314 Large array addressing - webgl2', () => { + buildLargeArrayAddressKernel('webgl2'); +}); +(GPU.isHeadlessGLSupported ? test : skip)('Issue #314 Large array addressing - headlessgl', () => { + buildLargeArrayAddressKernel('headlessgl'); +}); diff --git a/test/issues/335-missing-z-index-issue.js b/test/issues/335-missing-z-index-issue.js index e27d1666..add08d90 100644 --- a/test/issues/335-missing-z-index-issue.js +++ b/test/issues/335-missing-z-index-issue.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #335'); diff --git a/test/issues/346-uint8array-converted.js b/test/issues/346-uint8array-converted.js index 99b749c0..c55291f7 100644 --- a/test/issues/346-uint8array-converted.js +++ b/test/issues/346-uint8array-converted.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #346'); diff --git a/test/issues/349-division-by-factors-of-3.js b/test/issues/349-division-by-factors-of-3.js index 72462ea0..9f093d85 100644 --- a/test/issues/349-division-by-factors-of-3.js +++ b/test/issues/349-division-by-factors-of-3.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #349 divide by 3'); diff --git a/test/issues/357-modulus-issue.js b/test/issues/357-modulus-issue.js index 96b0cd48..c9db53f9 100644 --- a/test/issues/357-modulus-issue.js +++ b/test/issues/357-modulus-issue.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #357'); diff --git a/test/issues/359-addfunction-params-wrong.js b/test/issues/359-addfunction-params-wrong.js index 02186d74..3992a56f 100644 --- a/test/issues/359-addfunction-params-wrong.js +++ b/test/issues/359-addfunction-params-wrong.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #359'); diff --git a/test/issues/378-only-first-iteration.js b/test/issues/378-only-first-iteration.js index 39c5053b..af96f3df 100644 --- a/test/issues/378-only-first-iteration.js +++ b/test/issues/378-only-first-iteration.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #378'); diff --git a/test/issues/382-bad-constant.js b/test/issues/382-bad-constant.js index aa711ce5..bf942e1b 100644 --- a/test/issues/382-bad-constant.js +++ b/test/issues/382-bad-constant.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #382'); diff --git a/test/issues/390-thread-assignment.js b/test/issues/390-thread-assignment.js index d20dd92b..e7164ad6 100644 --- a/test/issues/390-thread-assignment.js +++ b/test/issues/390-thread-assignment.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { WebGLFunctionNode, WebGL2FunctionNode, CPUFunctionNode } = require('../../src'); +const { WebGLFunctionNode, WebGL2FunctionNode, CPUFunctionNode } = require('../../dist/gpu.js'); describe('issue #390'); diff --git a/test/issues/396-combine-kernels-example.js b/test/issues/396-combine-kernels-example.js index 3e381431..d2fb1323 100644 --- a/test/issues/396-combine-kernels-example.js +++ b/test/issues/396-combine-kernels-example.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #396 - combine kernels example'); diff --git a/test/issues/399-double-definition.js b/test/issues/399-double-definition.js index 515836c9..49502883 100644 --- a/test/issues/399-double-definition.js +++ b/test/issues/399-double-definition.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #399'); diff --git a/test/issues/401-cpu-canvas-check.js b/test/issues/401-cpu-canvas-check.js index 9c8c9fcd..34602a0b 100644 --- a/test/issues/401-cpu-canvas-check.js +++ b/test/issues/401-cpu-canvas-check.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU, CPUKernel } = require('../../src'); +const { GPU, CPUKernel } = require('../../dist/gpu.js'); describe('issue #401'); diff --git a/test/issues/410-if-statement.js b/test/issues/410-if-statement.js index 1aad96a6..cb02e90f 100644 --- a/test/issues/410-if-statement.js +++ b/test/issues/410-if-statement.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #410 - if statement when unsigned on NVidia'); diff --git a/test/issues/422-warnings.js b/test/issues/422-warnings.js index 71a31c7f..0d174295 100644 --- a/test/issues/422-warnings.js +++ b/test/issues/422-warnings.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #422 - warnings'); diff --git a/test/issues/470-modulus-wrong.js b/test/issues/470-modulus-wrong.js index 0f9c0e7f..12533787 100644 --- a/test/issues/470-modulus-wrong.js +++ b/test/issues/470-modulus-wrong.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #470 - modulus wrong'); diff --git a/test/issues/471-canvas-issue.js b/test/issues/471-canvas-issue.js index c5030bce..a3663b84 100644 --- a/test/issues/471-canvas-issue.js +++ b/test/issues/471-canvas-issue.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #471 - canvas issue'); diff --git a/test/issues/472-compilation-issue.js b/test/issues/472-compilation-issue.js index 19eeef70..bd03e381 100644 --- a/test/issues/472-compilation-issue.js +++ b/test/issues/472-compilation-issue.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #472 - compilation issue'); diff --git a/test/issues/473-4-pixels.js b/test/issues/473-4-pixels.js index fb4ffd94..5b7c597b 100644 --- a/test/issues/473-4-pixels.js +++ b/test/issues/473-4-pixels.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #473 - only 4 pixels are shown'); diff --git a/test/issues/487-dynamic-arguments.js b/test/issues/487-dynamic-arguments.js index 3c68bb72..812b4a59 100644 --- a/test/issues/487-dynamic-arguments.js +++ b/test/issues/487-dynamic-arguments.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #487 - pipeline dynamic arguments'); diff --git a/test/issues/493-strange-literal.js b/test/issues/493-strange-literal.js index 089032ac..c364b11a 100644 --- a/test/issues/493-strange-literal.js +++ b/test/issues/493-strange-literal.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #493 - strange literal'); diff --git a/test/issues/91-create-kernel-map-array.js b/test/issues/91-create-kernel-map-array.js index fd42645e..21e6bd17 100644 --- a/test/issues/91-create-kernel-map-array.js +++ b/test/issues/91-create-kernel-map-array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU, HeadlessGLKernel, WebGLKernel, WebGL2Kernel, CPUKernel } = require('../../src'); +const { GPU, HeadlessGLKernel, WebGLKernel, WebGL2Kernel, CPUKernel } = require('../../dist/gpu.js'); describe('issue #91'); function getResult(mode) { diff --git a/test/issues/96-param-names.js b/test/issues/96-param-names.js index 7ac7054f..aa1fc480 100644 --- a/test/issues/96-param-names.js +++ b/test/issues/96-param-names.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #96');