├── .eslintrc.js
├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── package.json
├── scripts
└── combine-types.ts
├── src
├── arithmetic.ts
├── base.ts
├── functions.ts
├── index.ts
├── vecArithmetic.ts
├── vecBase.ts
└── vecFunctions.ts
├── test
├── advanced_plane
│ ├── index.html
│ └── test.js
├── simple-wiggle
│ ├── index.html
│ └── test.js
├── sine_plane
│ ├── index.html
│ └── test.js
├── sinenoise_plane
│ ├── index.html
│ └── test.js
└── sphere
│ ├── index.html
│ └── test.js
├── tsconfig.json
├── webpack.config.js
└── yarn.lock
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | parser: '@typescript-eslint/parser',
3 | extends: [
4 | 'plugin:@typescript-eslint/recommended',
5 | 'prettier/@typescript-eslint',
6 | 'plugin:prettier/recommended',
7 | ],
8 | parserOptions: {
9 | sourceType: 'module',
10 | },
11 | ecmaFeatures: {
12 | jsx: true,
13 | },
14 | rules: {
15 | // Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
16 | 'no-unused-vars': 'off',
17 | '@typescript-eslint/no-unused-vars': [1, { argsIgnorePattern: '^_' }],
18 | '@typescript-eslint/no-inferrable-types': 'off',
19 | '@typescript-eslint/no-explicit-any': 'off',
20 | '@typescript-eslint/no-non-null-assertion': 'off',
21 | '@typescript-eslint/explicit-member-accessibility': 'off',
22 | '@typescript-eslint/ban-ts-ignore': 'off',
23 | '@typescript-eslint/explicit-function-return-type': 'off',
24 | '@typescript-eslint/camelcase': 'off',
25 | 'react/prop-types': 'off',
26 | '@typescript-eslint/ban-ts-comment': 'off',
27 | '@typescript-eslint/explicit-module-boundary-types': 'off',
28 | '@typescript-eslint/no-empty-function': 'off',
29 | '@typescript-eslint/no-empty-interface': 'off',
30 | },
31 | }
32 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | node_modules
3 | .DS_Store
4 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | src
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Dave Pagurek
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # glsl-autodiff
2 | Tired of doing math to get normals in your vertex shader? Same. Use this library to write your function once and generate derivatives automatically!
3 |
4 | - Demo
5 | - Starter Code
6 | - Why?
7 | - API Usage
8 | - Inputs and Outputs
9 | - Operations
10 | - Additional Settings
11 | - Importing in JS/TS Builds
12 | - Importing in the Browser
13 | - Contributing
14 |
15 | ## Demo
16 | 
17 |
18 | Live version in the p5 editor
19 |
20 | ### Starter Code
21 |
22 |
36 |
37 | ## Why?
38 |
39 | Sometimes, I want to displace mesh vertices in a vertex shader. After doing this, the normals of a surface should change:
40 |
41 | 
42 |
43 | However, per-vertex normals don't automatically update! Manual updating of vertex normals requires you to take the derivative of your displacement function. This library automates that process so that it takes less time and is less prone to user error. If you're interested, read a more in-depth blog post on why this is necessary and how it works.
44 |
45 | ## API Usage
46 |
47 | This exposes a `gen` function that generates GLSL that you can splice into your shader code. Inside a call to `gen()`, you provide a callback that takes in `ad`, the AutoDiff engine, and uses it to build shader code. We build shaders by essentially creating a graph of operations that we pass inputs through to arrive at an output. Every function call creates an object representing such an operation. Once we have a graph, we can automatically compute derivatives using it!
48 |
49 | The AutoDiff engine's methods are designed to look similar to how you would normally write a shader, but using method chaining instead of operator symbols, similar to how p5's Vector class works. It looks something like this in action:
50 | ```js
51 | import { gen } from `@davepagurek/glsl-autodiff'
52 |
53 | const vert = `
54 | void main(void) {
55 | vec4 objSpacePosition = vec4(aPosition, 1.0);
56 |
57 | float x = objSpacePosition.x;
58 | float y = objSpacePosition.y;
59 | ${gen((ad) => {
60 | const x = ad.param('x')
61 | const y = ad.param('y')
62 | const time = ad.param('time')
63 | const speedX = 1.5
64 | const speedY = 2.8
65 |
66 | let offset = ad.val(0)
67 | for (let i = 0; i < 3; i++) {
68 | offset = offset.add(ad.sin(
69 | ad.sum(
70 | offset.mult(0.5).add(x.mult(speedX)).add(y.mult(speedY)),
71 | time.mult(0.002),
72 | )
73 | ))
74 | }
75 | offset = offset.mult(0.1)
76 | offset.output('z')
77 | offset.outputDeriv('dzdx', x)
78 | offset.outputDeriv('dzdy', y)
79 | })}
80 | objSpacePosition.z = z;
81 | vec3 slopeX = vec3(1.0, 0.0, dzdx);
82 | vec3 slopeY = vec3(0.0, 1.0, dzdy);
83 | vNormal = uNormalMatrix * normalize(cross(slopeX, slopeY));
84 |
85 | vec4 worldSpacePosition = uModelViewMatrix * objSpacePosition;
86 | gl_Position = uProjectionMatrix * worldSpacePosition;
87 | }
88 | `
89 | ```
90 |
91 | ### Inputs and Outputs
92 |
93 | **Parameters** are variables that you create outside of AutoDiff but that you want to reference inside AutoDiff. Depending on their variable type, use one of the following methods to create them:
94 |
95 | ```typescript
96 | interface AutoDiff {
97 | param(name: string): Param
98 | vec2Param: (name: string) => VecParam
99 | vec3Param: (name: string) => VecParam
100 | vec4Param: (name: string) => VecParam
101 | }
102 | ```
103 |
104 | **Outputs** are used to store computation results from within AutoDiff into names that are accessible outside AutoDiff. You can also output the derivative of a computation with respect to an input parameter.
105 |
106 | ```typescript
107 | interface Op {
108 | output(name: string);
109 | outputDeriv(name: string, param: Param);
110 | }
111 | ```
112 |
113 | As an example, we can use `param` to reference a uniform, do some math with it, and output the result:
114 | ```js
115 | const vert = `
116 | // A uniform we want to reference
117 | uniform vec3 position;
118 |
119 | void main(void) {
120 | ${AutoDiff.gen((ad) => {
121 | // Get a computation graph node representing the uniform
122 | const position = ad.vec3Param('position')
123 |
124 | // Do stuff with it
125 | const offset = ad.sum(position.x(), position.y(), position.z())
126 |
127 | // Output it so the rest of the shader can reference it
128 | offset.output('offset')
129 | })}
130 | vec3 worldSpacePosition = position;
131 | worldSpacePosition.z += offset; // Use offset, an output, outside of AutoDiff
132 | gl_Position = uProjectionMatrix * vec4(worldSpacePosition, 1.0);
133 | }
134 | `
135 | ```
136 |
137 | ### Operations
138 |
139 | Given any scalar graph node (`Op`), use any of the following methods to generate a new node corresponding to the GLSL operation of the same name:
140 | ```typescript
141 | interface Op {
142 | neg(): Op; // Multiply by -1
143 | add(...params: Input[]): Op;
144 | sub(val: Input): Op;
145 | mult(...params: Input[]): Op;
146 | div(param: Input): Op;
147 | pow(param: Input): Op;
148 | sqrt(): Op;
149 | sin(): Op;
150 | cos(): Op;
151 | tan(): Op;
152 | mix(b: Input, amt: Input): Op;
153 | clamp(min: Input, max: Input): Op;
154 | min(...params: Input[]): Op;
155 | max(...params: Input[]): Op;
156 | ifElse(thenOp: Input, elseOp: Input): Op; // Ternary with the receiving Op being the condition
157 | vecIfElse(thenOp: VectorOp, elseOp: VectorOp): VectorOp; // Ternary but where the if/else values are vectors
158 | }
159 | ```
160 |
161 | Note that an `Input` is either another node, or a number literal.
162 |
163 | Given a vector graph node (`VectorOp`, which extends `Op`), use any of the following methods to again generate a new node with the computation result:
164 | ```typescript
165 | interface VectorOp {
166 | neg(): VectorOp;
167 | add(...params: VectorOp[]): VectorOp;
168 | scale(k: Input): VectorOp; // When multiplying by a scalar
169 | mult(...params: VectorOp[]): VectorOp; // When multiplying by another vector
170 | mix(other: VectorOp, amt: Input): VectorOp;
171 | clamp(min: VectorOp, max: VectorOp): VectorOp;
172 | min(...params: VectorOp[]): VectorOp;
173 | max(...params: VectorOp[]): VectorOp;
174 | dot(other: VectorOp): Op;
175 | length(): Op;
176 | dist(other: VectorOp): Op;
177 | }
178 | ```
179 |
180 | You can also construct nodes directly from the AutoDiff engine passed to you in the `gen` callback:
181 | ```typescript
182 | interface AutoDiff {
183 | // Create new values
184 | val: (n: number) => Op;
185 | vec2: (x: Input, y: Input) => Vec;
186 | vec3: (x: Input, y: Input, z: Input) => Vec;
187 | vec4: (x: Input, y: Input, z: Input, w: Input) => Vec;
188 |
189 | // Create a new operation with scalar inputs
190 | sum: (...params: Input[]) => any;
191 | prod: (...params: Input[]) => any;
192 | sqrt: (param: Input) => any;
193 | sin: (input: Input) => any;
194 | cos: (input: Input) => any;
195 | tan: (input: Input) => any;
196 | mix: (a: Input, b: Input, amt: Input) => any;
197 | clamp: (val: Input, min: Input, max: Input) => any;
198 | min: (...params: Input[]) => any;
199 | max: (...params: Input[]) => any;
200 | ifElse: (ifOp: Input, thenOp: Input, elseOp: Input) => any;
201 |
202 | // Create a new operation with vector inputs
203 | vecSum: (...params: VectorOp[]) => VectorOp;
204 | vecProd: (...params: VectorOp[]) => VectorOp;
205 | vecMix: (a: VectorOp, b: VectorOp, amt: Input) => VectorOp;
206 | vecClamp: (val: VectorOp, min: VectorOp, max: VectorOp) => VectorOp;
207 | vecMin: (...params: VectorOp[]) => VectorOp;
208 | vecMax: (...params: VectorOp[]) => VectorOp;
209 | dot: (a: VectorOp, b: VectorOp) => Op;
210 | length: (val: VectorOp) => Op;
211 | dist: (a: VectorOp, b: VectorOp) => Op;
212 | }
213 | ```
214 |
215 | ### Additional settings
216 |
217 | On some very rare occasions, you write code that Just Works™! For the other 99% of the time, AutoDiff includes debug options that you can change by passing an additional settings object into the `gen` function:
218 |
219 | ```typescript
220 | gen: (
221 | cb: (ad: AD) => void,
222 | settings?: Partial,
223 | ) => string;
224 |
225 | type ADSettings = {
226 | maxDepthPerVariable: number;
227 | debug: boolean;
228 | };
229 | ```
230 |
231 | When you set `debug: true`, each line in the outputted GLSL that comes directly from an code you wrote gets a comment referencing where it came from:
232 |
233 |
234 | Input
235 | | Output
236 | |
237 |
238 |
239 | const vert = `
240 | void main(void) {
241 | vec4 objSpacePosition = vec4(aPosition, 1.0);
242 | float origZ = objSpacePosition.z;
243 | float x = objSpacePosition.x;
244 | float y = objSpacePosition.y;
245 | ${AutoDiff.gen((ad) => {
246 | const x = ad.param('x')
247 | const y = ad.param('y')
248 | const time = ad.param('time')
249 | const speedX = 1.5
250 | const speedY = 2.8
251 |
252 | let offset = ad.val(0)
253 | for (let i = 0; i < 3; i++) {
254 | offset = offset.add(ad.sin(
255 | ad.sum(
256 | offset.mult(0.5).add(x.mult(speedX)).add(y.mult(speedY)),
257 | time.mult(0.002),
258 | )
259 | ))
260 | }
261 | offset = offset.mult(0.1)
262 | offset.output('z')
263 | }, { debug: true, maxDepthPerVariable: 4 })}
264 | objSpacePosition.z += z;
265 | vec4 worldSpacePosition = uModelViewMatrix * objSpacePosition;
266 | gl_Position = uProjectionMatrix * worldSpacePosition;
267 | }
268 | `
269 | |
270 |
271 | void main(void) {
272 | vec4 objSpacePosition = vec4(aPosition, 1.0);
273 | float origZ = objSpacePosition.z;
274 | float x = objSpacePosition.x;
275 | float y = objSpacePosition.y;
276 |
277 | // From vert<@file:///Users/dpagurek/Documents/Projects/glsl-autodiff/test/sine_plane/test.js:31:12
278 | float _glslad_v14=(((0.0000\*0.5000)+(x\*1.5000))+(y\*2.8000))+(time\*0.0020);
279 |
280 | // From vert<@file:///Users/dpagurek/Documents/Projects/glsl-autodiff/test/sine_plane/test.js:30:23
281 | float _glslad_v16=0.0000+(sin(_glslad_v14));
282 |
283 | // From vert<@file:///Users/dpagurek/Documents/Projects/glsl-autodiff/test/sine_plane/test.js:31:12
284 | float _glslad_v27=(((_glslad_v16\*0.5000)+(x\*1.5000))+(y\*2.8000))+(time\*0.0020);
285 |
286 | // From vert<@file:///Users/dpagurek/Documents/Projects/glsl-autodiff/test/sine_plane/test.js:30:23
287 | float _glslad_v29=_glslad_v16+(sin(_glslad_v27));
288 |
289 | // From vert<@file:///Users/dpagurek/Documents/Projects/glsl-autodiff/test/sine_plane/test.js:31:12
290 | float _glslad_v40=(((_glslad_v29\*0.5000)+(x\*1.5000))+(y\*2.8000))+(time\*0.0020);
291 | float z=((_glslad_v29+(sin(_glslad_v40)))\*0.1000);
292 |
293 | objSpacePosition.z += z;
294 | vec4 worldSpacePosition = uModelViewMatrix \* objSpacePosition;
295 | gl_Position = uProjectionMatrix \* worldSpacePosition;
296 | }
297 | |
298 |
299 |
300 |
301 | Sometimes too much or too little ends up on one line, so you can also supply `maxDepthPerVariable` to supply a maximum number of nested operations before creating an intermediate variable. If unspecified, we use `maxDepthPerVariable: 8`. To condense into as few lines as possible, use `Infinity`. To make every operation its own variable, use 1.
302 |
303 | ### Importing in JS/TS builds
304 |
305 | Add this library to your project:
306 | ```
307 | yarn add @davepagurek/glsl-autodiff
308 | ```
309 |
310 | Then, import the `gen` method:
311 | ```typescript
312 | import { gen } from '@davepagurek/glsl-autodiff'
313 |
314 | const myShader = `
315 | // some shader code here
316 | ${gen((ad) => {
317 | // Use autodiff here
318 | })}
319 | `
320 | ```
321 |
322 | ### Importing in the Browser
323 |
324 | Download the library from the Github releases tab and add the library to your HTML file:
325 | ```html
326 |
327 | ```
328 |
329 | Then, use the global `AutoDiff` variable which includes the `gen` function:
330 | ```js
331 | const myShader = `
332 | // some shader code here
333 | ${AutoDiff.gen((ad) => {
334 | // Use autodiff here
335 | })}
336 | `
337 | ```
338 |
339 | ## Contributing
340 |
341 | Want to help out? There are a number of things I'd like to get done at some point that are written down for posterity in the Issues tab that I'd love help on!
342 |
343 | Setting up the repo:
344 |
345 | ```
346 | git clone git@github.com:davepagurek/glsl-autodiff.git
347 | cd glsl-autodiff
348 | yarn install
349 | ```
350 |
351 | Compiling `build/autodiff.js` and `build/autodiff.d.ts`:
352 | ```
353 | yarn build
354 | ```
355 |
356 | Pushing all compiled code to Github Pages for demos (if you are me or have write permissions):
357 | ```
358 | yarn deploy
359 | ```
360 |
361 | Publishing a new version to NPM:
362 | ```
363 | yarn publish
364 | ```
365 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@davepagurek/glsl-autodiff",
3 | "version": "0.0.20",
4 | "main": "build/autodiff.js",
5 | "author": "Dave Pagurek ",
6 | "license": "MIT",
7 | "types": "build/autodiff.d.ts",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/davepagurek/glsl-autodiff.git"
11 | },
12 | "bugs": {
13 | "url": "https://github.com/davepagurek/glsl-autodiff/issues"
14 | },
15 | "homepage": "https://github.com/davepagurek/glsl-autodiff",
16 | "dependencies": {
17 | "lodash": "^4.17.21"
18 | },
19 | "devDependencies": {
20 | "@types/node": "^15.12.5",
21 | "gh-pages": "^3.2.3",
22 | "ts-loader": "^9.2.3",
23 | "ts-node": "^10.0.0",
24 | "typescript": "^4.3.4",
25 | "webpack": "^5.41.1",
26 | "webpack-cli": "^4.7.2"
27 | },
28 | "scripts": {
29 | "build": "yarn generate:js && yarn generate:types",
30 | "generate:js": "yarn run webpack",
31 | "generate:types": "yarn run ts-node scripts/combine-types.ts",
32 | "deploy": "yarn build && yarn run gh-pages -d .",
33 | "publish": "npm publish --access public"
34 | },
35 | "files": [
36 | "build"
37 | ]
38 | }
39 |
--------------------------------------------------------------------------------
/scripts/combine-types.ts:
--------------------------------------------------------------------------------
1 | import fs from 'fs'
2 | import path from 'path'
3 |
4 | const outFile = 'autodiff.d.ts'
5 | const buildDirectory = path.resolve(
6 | __dirname,
7 | '../build',
8 | )
9 | const typeFiles = fs
10 | .readdirSync(buildDirectory, { withFileTypes: true })
11 | .filter((dirEnt) => dirEnt.isFile())
12 | .filter(({ name }) => name.endsWith('.d.ts'))
13 | .filter(({ name }) => name !== outFile)
14 |
15 | let combined = ''
16 | typeFiles.forEach(({ name }) => {
17 | const types = fs.readFileSync(path.resolve(buildDirectory, name), 'utf8')
18 |
19 | // Remove imports for now
20 | combined += types
21 | .replace(/^import.*$/mg, '')
22 | .replace(/import\(".\/[^"]+"\)\./g, '')
23 | .replace(/declare module '[^']+' \{\n([^}]+)\}/mg, 'export $1')
24 | })
25 | fs.writeFileSync(path.resolve(buildDirectory, outFile), combined)
26 |
--------------------------------------------------------------------------------
/src/arithmetic.ts:
--------------------------------------------------------------------------------
1 | import { Input, Op, Param, ADBase, ADConstructor, UserInput } from './base'
2 |
3 | export class Neg extends Op {
4 | definition() {
5 | return `-${this.dependsOn[0].ref()}`
6 | }
7 | derivative(param: Param) {
8 | return '-' + this.dependsOn[0].derivRef(param)
9 | }
10 | }
11 |
12 | export class Sum extends Op {
13 | definition() {
14 | return this.dependsOn.map((op) => op.ref()).join('+')
15 | }
16 | derivative(param: Param) {
17 | return this.dependsOn.map((op) => op.derivRef(param)).join('+')
18 | }
19 | }
20 |
21 | export class Mult extends Op {
22 | definition() {
23 | return this.dependsOn.map((op) => op.ref()).join('*')
24 | }
25 | derivative(param: Param) {
26 | const [f, g] = this.dependsOn
27 | const fIsConst = f.isConst(param)
28 | const gIsConst = g.isConst(param)
29 | if (fIsConst && !gIsConst) {
30 | return `${f.ref()}*${g.derivRef(param)}`
31 | } else if (!fIsConst && gIsConst) {
32 | return `${g.ref()}*${f.derivRef(param)}`
33 | } else {
34 | return `${f.ref()}*${g.derivRef(param)}+${g.ref()}*${f.derivRef(param)}`
35 | }
36 | }
37 | }
38 |
39 | export class Div extends Op {
40 | definition() {
41 | return this.dependsOn.map((op) => op.ref()).join('/')
42 | }
43 | derivative(param: Param) {
44 | const [f, g] = this.dependsOn
45 | return `(${f.derivRef(param)}*${g.ref()}-${g.derivRef(param)}*${f.ref()})/(${g.ref()}*${g.ref()})`
46 | }
47 | }
48 |
49 | export class Pow extends Op {
50 | definition() {
51 | return `pow(${this.dependsOn[0].ref()},${this.dependsOn[1].ref()})`
52 | }
53 | derivative(param: Param) {
54 | const [a, b] = this.dependsOn
55 | if (b.isConst()) {
56 | return `${b.ref()}*pow(${a.ref()},${b.ref()}-1.0)*${a.derivRef(param)}`
57 | } else if (a.isConst()) {
58 | return `pow(${a.ref()},${b.ref()})*log(${a.ref()})*${b.derivRef(param)}`
59 | } else {
60 | // f = a^b
61 | // ln(f) = ln(a^b) ln() both sides
62 | // ln(f) = b*ln(a) logarithm rules
63 | // e^(lnf) = e^(b*ln(a)) exp() both sides
64 | // f = e^(b*ln(a)) simplify
65 | // d/dx f = d/dx e^(b*ln(a)) differentiate both sides
66 | // d/dx f = e^(b*ln(a)) * d/dx b*ln(a) derivative of e^u
67 | // d/dx f = a^b * d/dx b*ln(a) exponential rules
68 | // d/dx f = a^b * (b*(1/a * da/dx) + ln(a)*(db/dx)) product rule
69 | // t1 t2 t3
70 | const t1 = `pow(${a.ref()},${b.ref()})`
71 | const t2 = `${b.ref()}*(1.0/${a.ref()}*${a.derivRef(param)})`
72 | const t3 = `log(${a.ref()})*${b.derivRef(param)}`
73 | return `${t1}*(${t2}+${t3})`
74 | }
75 | }
76 | }
77 |
78 | declare module './base' {
79 | interface Op {
80 | neg(): Op
81 | add(...params: Input[]): Op
82 | sub(val: Input): Op
83 | mult(...params: Input[]): Op
84 | div(param: Input): Op
85 | pow(param: Input): Op
86 | sqrt(): Op
87 | }
88 | }
89 |
90 | Op.prototype.neg = UserInput(function() {
91 | return new Neg(this.ad, this)
92 | })
93 | Op.prototype.add = UserInput(function(...params: Input[]) {
94 | if (params.length === 0) {
95 | throw new Error(`add() called with too few arguments: ${params}`)
96 | } else {
97 | return new Sum(this.ad, this, ...this.ad.convertVals(params))
98 | }
99 | })
100 | Op.prototype.sub = UserInput(function(val: Input) {
101 | return this.add(this.ad.convertVal(val).neg())
102 | })
103 | Op.prototype.mult = UserInput(function(...params: Input[]) {
104 | if (params.length === 0) {
105 | throw new Error(`mult() called with too few arguments: ${params}`)
106 | } else if (params.length === 1) {
107 | return new Mult(this.ad, this, this.ad.convertVal(params[0]))
108 | } else {
109 | return this.mult(params[0]).mult(...params.slice(1))
110 | }
111 | })
112 | Op.prototype.div = UserInput(function(param: Input) {
113 | return new Div(this.ad, this, this.ad.convertVal(param))
114 | })
115 | Op.prototype.pow = UserInput(function(param: Input) {
116 | return new Pow(this.ad, this, this.ad.convertVal(param))
117 | })
118 | Op.prototype.sqrt = UserInput(function() { return this.pow(0.5) })
119 |
120 | export function WithArithmetic(Base: T) {
121 | class AutoDiff extends Base {
122 | sum = UserInput(function(...params: Input[]) {
123 | if (params.length === 0) {
124 | throw new Error(`sum() called with too few arguments: ${params}`)
125 | } else {
126 | const first = this.convertVal(params[0])
127 | if (params.length > 1) {
128 | return first.add(...params.slice(1))
129 | } else {
130 | return first
131 | }
132 | }
133 | })
134 | prod = UserInput(function(...params: Input[]) {
135 | if (params.length === 0) {
136 | throw new Error(`prod() called with too few arguments: ${params}`)
137 | } else {
138 | const first = this.convertVal(params[0])
139 | if (params.length > 1) {
140 | return first.mult(...params.slice(1))
141 | } else {
142 | return first
143 | }
144 | }
145 | })
146 | sqrt = UserInput(function(param: Input) {
147 | return this.convertVal(param).sqrt()
148 | })
149 | }
150 | return AutoDiff
151 | }
152 |
--------------------------------------------------------------------------------
/src/base.ts:
--------------------------------------------------------------------------------
1 | export type Input = Op | number
2 |
3 | export interface ADBase {
4 | getNextID(): number
5 | val(n: number): Value
6 | registerParam(param: Op, name: string)
7 | param(name: string): Param
8 | convertVal(param: Input): Op
9 | convertVals(params: Input[]): Op[]
10 | output(name: string, op: Op): ADBase
11 | outputDeriv(name: string, param: Param | string, op: Op): ADBase
12 | settings: ADSettings
13 | }
14 |
15 | export type ADSettings = {
16 | maxDepthPerVariable: number
17 | debug: boolean
18 | }
19 |
20 | export type ADConstructor = new (...args: any[]) => ADBase
21 |
22 | // https://stackoverflow.com/a/27074218
23 | export const getStack = () => {
24 | const e = new Error()
25 | if (!e.stack) try {
26 | // IE requires the Error to actually be throw or else the Error's 'stack'
27 | // property is undefined.
28 | throw e
29 | } catch (e) {
30 | if (!e.stack) {
31 | return [] // IE < 10, likely
32 | }
33 | }
34 | const frameRE = /:(\d+):(?:\d+)[^\d]*$/
35 | const stack = e.stack?.toString().split(/\r\n|\n/).filter((line) => line.match(frameRE)) ?? []
36 | return stack
37 | }
38 |
39 | // If we know a function will be called directly by the user, wrap it with
40 | // this so we can add extra debug info
41 | export function UserInput Op>(fn: T): T {
42 | return function(...args: any[]) {
43 | const op = fn.apply(this, args)
44 |
45 | if (op.ad.settings.debug) {
46 | const stack = getStack()
47 | op.srcLine = stack[2] ?? ''
48 | }
49 | return op
50 | } as T
51 | }
52 |
53 | export abstract class Op {
54 | public ad: ADBase
55 | public id: number
56 | public dependsOn: Op[]
57 | public usedIn: Op[] = []
58 | public srcLine: string = ''
59 | public internalDerivatives: { op: Op, param: Param }[] = []
60 |
61 | constructor(ad: ADBase, ...params: Op[]) {
62 | this.ad = ad
63 | this.id = ad.getNextID()
64 | this.dependsOn = params
65 | for (const param of params) {
66 | param.usedIn.push(this)
67 | }
68 | }
69 |
70 | public scalar() { return true }
71 |
72 | public size() { return 1 }
73 |
74 | public glslType() {
75 | if (this.scalar()) {
76 | return 'float'
77 | } else {
78 | return `vec${this.size()}`
79 | }
80 | }
81 |
82 | public depth() {
83 | // Force usage of a temp variable if used in multiple spots
84 | if (this.usedIn.length > 1) return 1
85 |
86 | const depDepth = Math.max(0, ...this.dependsOn.map((op) => op.depth()))
87 | const depth = depDepth + 1
88 |
89 | if (depth > this.ad.settings.maxDepthPerVariable) {
90 | return 1
91 | } else {
92 | return depth
93 | }
94 | }
95 |
96 | public useTempVar() {
97 | return this.depth() === 1
98 | }
99 |
100 | public ref(): string {
101 | if (this.useTempVar()) {
102 | return `_glslad_v${this.id}`
103 | } else {
104 | return `(${this.definition()})`
105 | }
106 | }
107 |
108 | public zeroDerivative() {
109 | return '0.0'
110 | }
111 |
112 | public derivRef(param: Param): string {
113 | if (this.isConst(param)) {
114 | return this.zeroDerivative()
115 | } else if (this.useTempVar()) {
116 | return `_glslad_dv${this.id}_d${param.safeName()}`
117 | } else {
118 | return `(${this.derivative(param)})`
119 | }
120 | }
121 |
122 | public initializer(): string {
123 | if (this.useTempVar()) {
124 | let line = `${this.glslType()} ${this.ref()}=${this.definition()};`
125 | if (this.ad.settings.debug && this.srcLine) {
126 | line = `\n// From ${this.srcLine}\n` + line
127 | }
128 | line += '\n'
129 | return line
130 | } else {
131 | return ''
132 | }
133 | }
134 |
135 | public derivInitializer(param: Param): string {
136 | if (this.isConst(param) || !this.useTempVar()) {
137 | return ''
138 | } else {
139 | return `${this.glslType()} ${this.derivRef(param)}=${this.derivative(param)};\n`
140 | }
141 | }
142 |
143 | public isConst(param?: Param): boolean {
144 | return this.dependsOn.every((op) => op.isConst(param))
145 | }
146 |
147 | public outputDependencies({ deps, derivDeps }: { deps: Set; derivDeps: Map> }): string {
148 | let code = ''
149 | for (const op of this.dependsOn) {
150 | if (!deps.has(op)) {
151 | deps.add(op)
152 | code += op.outputDependencies({ deps, derivDeps })
153 | code += op.initializer()
154 | }
155 | }
156 |
157 | for (const { param, op } of this.internalDerivatives) {
158 | if (!derivDeps.get(param)?.has(op)) {
159 | const paramDerivDeps = derivDeps.get(param) ?? new Set()
160 | paramDerivDeps.add(op)
161 | derivDeps.set(param, paramDerivDeps)
162 | code += op.outputDerivDependencies(param, { deps, derivDeps })
163 | code += op.derivInitializer(param)
164 | }
165 | }
166 |
167 | return code
168 | }
169 |
170 | public outputDerivDependencies(param: Param, { deps, derivDeps }: { deps: Set; derivDeps: Map> }): string {
171 | if (this.isConst()) return ''
172 | let code = ''
173 | for (const op of this.dependsOn) {
174 | if (!deps.has(op)) {
175 | deps.add(op)
176 | code += op.outputDependencies({ deps, derivDeps })
177 | code += op.initializer()
178 | }
179 |
180 | if (!derivDeps.get(param)?.has(op) && !op.isConst(param)) {
181 | const paramDerivDeps = derivDeps.get(param) ?? new Set()
182 | paramDerivDeps.add(op)
183 | derivDeps.set(param, paramDerivDeps)
184 | code += op.outputDerivDependencies(param, { deps, derivDeps })
185 | code += op.derivInitializer(param)
186 | }
187 | }
188 |
189 | for (const { param, op } of this.internalDerivatives) {
190 | if (!derivDeps.get(param)?.has(op)) {
191 | const paramDerivDeps = derivDeps.get(param) ?? new Set()
192 | paramDerivDeps.add(op)
193 | derivDeps.set(param, paramDerivDeps)
194 | code += op.outputDependencies({ deps, derivDeps })
195 | code += op.derivInitializer(param)
196 | }
197 | }
198 |
199 | return code
200 | }
201 |
202 | public output(name: string) { return this.ad.output(name, this) }
203 | public outputDeriv(name: string, param: Param | string) { return this.ad.outputDeriv(name, param, this) }
204 |
205 | public abstract definition(): string
206 | public abstract derivative(param: Param): string
207 | }
208 |
209 | export abstract class BooleanOp extends Op {
210 | abstract operator(): string
211 | definition() {
212 | return this.dependsOn.map((op) => op.ref()).join(this.operator())
213 | }
214 | derivative(): string {
215 | throw new Error('unimplemented')
216 | }
217 | isConst() {
218 | // They might not actually be constant, but we don't have derivatives
219 | // for these so we just treat them like they are
220 | return true;
221 | }
222 | glslType() {
223 | return 'bool'
224 | }
225 | }
226 |
227 | export class EqOp extends BooleanOp {
228 | operator() {
229 | return '=='
230 | }
231 | }
232 |
233 | export class NeOp extends BooleanOp {
234 | operator() {
235 | return '!='
236 | }
237 | }
238 |
239 | export class LtOp extends BooleanOp {
240 | operator() {
241 | return '<'
242 | }
243 | }
244 |
245 | export class LeOp extends BooleanOp {
246 | operator() {
247 | return '<='
248 | }
249 | }
250 |
251 | export class GtOp extends BooleanOp {
252 | operator() {
253 | return '>'
254 | }
255 | }
256 |
257 | export class GeOp extends BooleanOp {
258 | operator() {
259 | return '>='
260 | }
261 | }
262 |
263 | export class NotOp extends BooleanOp {
264 | operator() {
265 | return '!'
266 | }
267 | definition() {
268 | return this.operator() + this.dependsOn[0].ref()
269 | }
270 | }
271 |
272 | export class AndOp extends BooleanOp {
273 | operator() {
274 | return '&&'
275 | }
276 | }
277 |
278 | export class OrOp extends BooleanOp {
279 | operator() {
280 | return '||'
281 | }
282 | }
283 |
284 | export abstract class OpLiteral extends Op {
285 | public override initializer() { return '' }
286 | public override derivInitializer() { return '' }
287 | public override ref() { return this.definition() }
288 | public override derivRef(param: Param) { return this.derivative(param) }
289 | }
290 |
291 | export class Value extends OpLiteral {
292 | private val: number
293 |
294 | constructor(ad: ADBase, val: number) {
295 | super(ad)
296 | this.val = val
297 | }
298 |
299 | isConst() { return true }
300 | definition() {
301 | const str = `${this.val.toFixed(4)}`
302 | return this.val < 0 ? `(${str})` : str
303 | }
304 | derivative() { return '0.0' }
305 | }
306 |
307 | export class Param extends OpLiteral {
308 | public name: string
309 |
310 | constructor(ad: ADBase, name: string, ...dependsOn: Op[]) {
311 | super(ad, ...dependsOn)
312 | this.name = name
313 | this.ad.registerParam(this, name)
314 | }
315 |
316 | safeName() {
317 | // A version of the name that can be used in temp variable
318 | // names
319 | return this.name.split('').map((c) => {
320 | if (c.match(/[\w\d]/)) {
321 | return c
322 | } else {
323 | return '_'
324 | }
325 | }).join('') + this.id // Add id to ensure uniqueness
326 | }
327 |
328 | isConst(param?: Param) {
329 | if (param) {
330 | return param !== this
331 | } else {
332 | return false
333 | }
334 | }
335 | definition() { return this.name }
336 | derivative(param: Param) {
337 | if (param === this) {
338 | return '1.0'
339 | } else {
340 | return '0.0'
341 | }
342 | }
343 | }
344 |
--------------------------------------------------------------------------------
/src/functions.ts:
--------------------------------------------------------------------------------
1 | import { Input, Op, Param, ADBase, ADConstructor, UserInput } from './base'
2 |
3 | export class Sin extends Op {
4 | definition() {
5 | return `sin(${this.dependsOn[0].ref()})`
6 | }
7 | derivative(param: Param) {
8 | return `cos(${this.dependsOn[0].ref()})*${this.dependsOn[0].derivRef(param)}`
9 | }
10 | }
11 |
12 | export class Cos extends Op {
13 | definition() {
14 | return `cos(${this.dependsOn[0].ref()})`
15 | }
16 | derivative(param: Param) {
17 | return `-sin(${this.dependsOn[0].ref()})*${this.dependsOn[0].derivRef(param)}`
18 | }
19 | }
20 |
21 | export class Mix extends Op {
22 | definition() {
23 | return `mix(${this.dependsOn.map((op) => op.ref()).join(',')})`
24 | }
25 | derivative(param: Param) {
26 | const [a, b, mix] = this.dependsOn
27 | const aDeriv = `(1.0-${a.ref()})*${mix.derivRef(param)}+(-${a.derivRef(param)})*${mix.ref()}`
28 | const bDeriv = `${b.ref()}*${mix.derivRef(param)}+${b.derivRef(param)}*${mix.ref()}`
29 | return `${aDeriv}+${bDeriv}`
30 | }
31 | }
32 |
33 | export class Clamp extends Op {
34 | definition() {
35 | return `clamp(${this.dependsOn.map((op) => op.ref()).join(',')})`
36 | }
37 | derivative(param: Param) {
38 | const [v, min, max] = this.dependsOn
39 | return `${v.ref()}<${min.ref()} ? 0.0 : (${v.ref()}>${max.ref()} ? 0.0 : ${v.derivRef(param)})`
40 | }
41 | }
42 |
43 | export class Min extends Op {
44 | definition() {
45 | return `min(${this.dependsOn.map((op) => op.ref()).join(',')})`
46 | }
47 | derivative(param: Param) {
48 | const [a, b] = this.dependsOn
49 | return `${a.ref()}<${b.ref()} ? ${a.derivRef(param)} : ${b.derivRef(param)}`
50 | }
51 | }
52 |
53 | export class Max extends Op {
54 | definition() {
55 | return `max(${this.dependsOn.map((op) => op.ref()).join(',')})`
56 | }
57 | derivative(param: Param) {
58 | const [a, b] = this.dependsOn
59 | return `${a.ref()}>${b.ref()} ? ${a.derivRef(param)} : ${b.derivRef(param)}`
60 | }
61 | }
62 |
63 | export class IfElse extends Op {
64 | definition() {
65 | const [condition, thenOp, elseOp] = this.dependsOn
66 | return `${condition.ref()}?${thenOp.ref()}:${elseOp.ref()}`
67 | }
68 | derivative(param: Param) {
69 | const [condition, thenOp, elseOp] = this.dependsOn
70 | return `${condition.ref()}?${thenOp.derivRef(param)}:${elseOp.derivRef(param)}`
71 | }
72 | }
73 |
74 | export class Abs extends Op {
75 | definition() {
76 | return `abs(${this.dependsOn[0].ref()})`
77 | }
78 | derivative(param: Param) {
79 | return '0.0'
80 | }
81 | }
82 |
83 | declare module './base' {
84 | interface Op {
85 | sin(): Op
86 | cos(): Op
87 | tan(): Op
88 | mix(b: Input, amt: Input): Op
89 | clamp(min: Input, max: Input): Op
90 | min(...params: Input[]): Op
91 | max(...params: Input[]): Op
92 | ifElse(thenOp: Input, elseOp: Input): Op
93 | }
94 | }
95 |
96 | Op.prototype.sin = UserInput(function() {
97 | return new Sin(this.ad, this)
98 | })
99 | Op.prototype.cos = UserInput(function() {
100 | return new Cos(this.ad, this)
101 | })
102 | Op.prototype.tan = UserInput(function() {
103 | // TODO make this its own class to optimize it
104 | return this.sin().div(this.cos())
105 | })
106 | Op.prototype.mix = UserInput(function(b: Input, amt: Input) {
107 | return new Mix(this.ad, this, this.ad.convertVal(b), this.ad.convertVal(amt))
108 | })
109 | Op.prototype.clamp = UserInput(function(min: Input, max: Input) {
110 | return new Clamp(this.ad, this, this.ad.convertVal(min), this.ad.convertVal(max))
111 | })
112 | Op.prototype.min = UserInput(function(...params: Input[]) {
113 | return params.reduce(
114 | (acc, next) => new Min(this.ad, acc, this.ad.convertVal(next)),
115 | this,
116 | )
117 | })
118 | Op.prototype.max = UserInput(function(...params: Input[]) {
119 | return params.reduce(
120 | (acc, next) => new Max(this.ad, acc, this.ad.convertVal(next)),
121 | this,
122 | )
123 | })
124 | Op.prototype.ifElse = UserInput(function(thenOp: Input, elseOp: Input) {
125 | return new IfElse(this.ad, this, this.ad.convertVal(thenOp), this.ad.convertVal(elseOp))
126 | })
127 |
128 | export function WithFunctions(Base: T) {
129 | class AutoDiff extends Base {
130 | sin = UserInput(function(input: Input) {
131 | return this.convertVal(input).sin()
132 | })
133 | cos = UserInput(function(input: Input) {
134 | return this.convertVal(input).cos()
135 | })
136 | tan = UserInput(function(input: Input) {
137 | return this.convertVal(input).tan()
138 | })
139 | mix = UserInput(function(a: Input, b: Input, amt: Input) {
140 | return this.convertVal(a).mix(b, amt)
141 | })
142 | clamp = UserInput(function(val: Input, min: Input, max: Input) {
143 | return this.convertVal(val).clamp(min, max)
144 | })
145 | min = UserInput(function(...params: Input[]) {
146 | if (params.length === 0) {
147 | throw new Error(`No arguments passed to min()!`)
148 | } else {
149 | const first = this.convertVal(params[0])
150 | if (params.length > 1) {
151 | return first.min(...params.slice(1))
152 | } else {
153 | return first
154 | }
155 | }
156 | })
157 | max = UserInput(function(...params: Input[]) {
158 | if (params.length === 0) {
159 | throw new Error(`No arguments passed to min()!`)
160 | } else {
161 | const first = this.convertVal(params[0])
162 | if (params.length > 1) {
163 | return first.max(...params.slice(1))
164 | } else {
165 | return first
166 | }
167 | }
168 | })
169 | ifElse = UserInput(function(ifOp: Input, thenOp: Input, elseOp: Input) {
170 | return this.convertVal(ifOp).ifElse(thenOp, elseOp)
171 | })
172 | }
173 | return AutoDiff
174 | }
175 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import { ADSettings, Input, Param, Op, Value, ADBase, UserInput } from './base'
2 | import { WithArithmetic } from './arithmetic'
3 | import { WithFunctions } from './functions'
4 | import { WithVecBase } from './vecBase'
5 | import { WithVecArithmetic } from './vecArithmetic'
6 | import { WithVecFunctions } from './vecFunctions'
7 |
8 | class AutoDiffImpl implements ADBase {
9 | protected nextID = 0
10 | public getNextID(): number {
11 | const id = this.nextID
12 | this.nextID++
13 | return id
14 | }
15 |
16 | public settings: ADSettings = {
17 | maxDepthPerVariable: 8,
18 | debug: false,
19 | }
20 |
21 | protected params: { [key: string]: Param } = {}
22 | protected outputs: { [key: string]: Op } = {}
23 | protected derivOutputs: { [param: string]: { [key: string]: Op } } = {}
24 |
25 | public val = UserInput(function(n: number) { return new Value(this, n) })
26 | public registerParam(param, name) {
27 | this.params[name] = param
28 | }
29 | public param = UserInput(function(name: string) {
30 | return new Param(this, name)
31 | })
32 |
33 | public convertVal(param: Input): Op {
34 | if (param instanceof Op) {
35 | return param
36 | } else {
37 | return this.val(param)
38 | }
39 | }
40 | public convertVals(params: Input[]): Op[] {
41 | return params.map((param) => this.convertVal(param))
42 | }
43 |
44 | public output(name: string, op: Op) {
45 | this.outputs[name] = op
46 | return this
47 | }
48 |
49 | public outputDeriv(name: string, param: Param | string, op: Op) {
50 | const paramName = typeof param === 'string' ? param : param.name
51 | this.derivOutputs[paramName] = this.derivOutputs[paramName] || {}
52 | this.derivOutputs[paramName][name] = op
53 | return this
54 | }
55 |
56 | public gen(): string {
57 | let code = ''
58 |
59 | // Add initializers for outputs
60 | const deps = new Set()
61 | const derivDeps = new Map>()
62 |
63 | for (const name in this.outputs) {
64 | code += this.outputs[name].outputDependencies({ deps, derivDeps })
65 | code += this.outputs[name].initializer()
66 | deps.add(this.outputs[name])
67 | code += `${this.outputs[name].glslType()} ${name}=${this.outputs[name].ref()};\n`
68 | }
69 | for (const param in this.derivOutputs) {
70 | const paramOp = this.params[param]
71 | for (const name in this.derivOutputs[param]) {
72 | code += this.derivOutputs[param][name].outputDerivDependencies(paramOp, { deps, derivDeps })
73 | code += this.derivOutputs[param][name].derivInitializer(paramOp)
74 | code += `${this.derivOutputs[param][name].glslType()} ${name}=${this.derivOutputs[param][name].derivRef(paramOp)};\n`
75 | const paramDerivDeps = derivDeps.get(paramOp) ?? new Set()
76 | paramDerivDeps.add(this.derivOutputs[param][name])
77 | derivDeps.set(paramOp, paramDerivDeps)
78 | }
79 | }
80 |
81 | return code
82 | }
83 | }
84 |
85 | // TODO figure out a better way of writing this that Typescript can still infer the type of
86 | const ExtendedAD = WithVecFunctions(WithVecArithmetic(WithVecBase(WithFunctions(WithArithmetic(AutoDiffImpl)))))
87 | type GetType = T extends new (...args: any[]) => infer V ? V : never
88 | export type AD = GetType
89 |
90 | export const gen = (cb: (ad: AD) => void, settings: Partial = {}): string => {
91 | const ad = new ExtendedAD()
92 | for (const setting in settings) {
93 | ad.settings[setting] = settings[setting]
94 | }
95 | cb(ad)
96 | return ad.gen()
97 | }
98 |
--------------------------------------------------------------------------------
/src/vecArithmetic.ts:
--------------------------------------------------------------------------------
1 | import { Input, Param, ADBase, ADConstructor, UserInput } from './base'
2 | import { VectorOp, WithVecDependencies } from './vecBase'
3 |
4 | export class VecNeg extends WithVecDependencies {
5 | definition() {
6 | return `-${this.dependsOn[0].ref()}`
7 | }
8 | derivative(param: Param) {
9 | return '-' + this.dependsOn[0].derivRef(param)
10 | }
11 | }
12 |
13 | export class VecSum extends WithVecDependencies {
14 | definition() {
15 | return this.dependsOn.map((op) => op.ref()).join('+')
16 | }
17 | derivative(param: Param) {
18 | return this.dependsOn.map((op) => op.derivRef(param)).join('+')
19 | }
20 | }
21 |
22 | export class VecScale extends WithVecDependencies {
23 | definition() {
24 | return this.dependsOn.map((op) => op.ref()).join('*')
25 | }
26 | derivative(param: Param) {
27 | const [f, g] = this.dependsOn
28 | return `${f.ref()}*${g.derivRef(param)}+${g.ref()}*${f.derivRef(param)}`
29 | }
30 | }
31 |
32 | export class VecMult extends WithVecDependencies {
33 | definition() {
34 | return this.dependsOn.map((op) => op.ref()).join('*')
35 | }
36 | derivative(param: Param) {
37 | const [f, g] = this.dependsOn
38 | // Multiplying two vectors in glsl does elementwise multiplication
39 | return `${f.ref()}*${g.derivRef(param)}+${g.ref()}*${f.derivRef(param)}`
40 | }
41 | }
42 |
43 | declare module './vecBase' {
44 | interface VectorOp {
45 | neg(): VectorOp
46 | add(...params: VectorOp[]): VectorOp
47 | scale(k: Input): VectorOp
48 | mult(...params: VectorOp[]): VectorOp
49 | }
50 | }
51 | VectorOp.prototype.neg = UserInput(function() {
52 | return new VecNeg(this.ad, this)
53 | })
54 | VectorOp.prototype.add = UserInput(function(...params: VectorOp[]) {
55 | return new VecSum(this.ad, this, ...params)
56 | })
57 | VectorOp.prototype.scale = UserInput(function(k: Input) {
58 | return new VecScale(this.ad, this, this.ad.convertVal(k))
59 | })
60 | VectorOp.prototype.mult = UserInput(function(...params: VectorOp[]) {
61 | if (params.length === 0) {
62 | throw new Error(`mult() called with too few arguments: ${params}`)
63 | } else if (params.length === 1) {
64 | return new VecMult(this.ad, this, params[0])
65 | } else {
66 | return this.mult(params[0]).mult(...params.slice(1))
67 | }
68 | })
69 |
70 | export function WithVecArithmetic(Base: T) {
71 | class AutoDiff extends Base {
72 | vecSum = UserInput(function(...params: VectorOp[]) {
73 | if (params.length === 0) {
74 | throw new Error('No arguments passed to vecSum()!')
75 | } else if (params.length === 1) {
76 | return params[0]
77 | } else {
78 | return params[0].add(...params.slice(1))
79 | }
80 | })
81 | vecProd = UserInput(function(...params: VectorOp[]) {
82 | return params.reduce((acc, next) => acc.mult(next))
83 | })
84 | }
85 | return AutoDiff
86 | }
87 |
--------------------------------------------------------------------------------
/src/vecBase.ts:
--------------------------------------------------------------------------------
1 | import { Op, OpLiteral, ADBase, Param, Input, ADConstructor, UserInput, EqOp } from './base'
2 |
3 | export interface VecOp extends Op {
4 | x(): Op
5 | y(): Op
6 | z(): Op
7 | w(): Op
8 | definition(): string
9 | derivative(param: Param): string
10 | size(): number
11 | }
12 |
13 | export class VecElementRef extends Op {
14 | public prop: string
15 |
16 | constructor(ad: ADBase, prop: string, vec: VecOp) {
17 | super(ad, vec)
18 | this.prop = prop
19 | }
20 |
21 | definition() { return `${this.dependsOn[0].ref()}.${this.prop}` }
22 | derivative(param: Param) { return `${this.dependsOn[0].derivRef(param)}.${this.prop}` }
23 | }
24 |
25 | export class VecParamElementRef extends Param {
26 | public prop: string
27 | public name: string
28 |
29 | constructor(ad: ADBase, prop: string, vec: VecOp) {
30 | super(ad, `_glslad_r${vec.id}_${prop}`, vec)
31 | this.prop = prop
32 | this.name = `_glslad_r${vec.id}_${prop}`
33 | this.ad.registerParam(this, this.name)
34 | }
35 |
36 | public isConst(param?: Param) {
37 | if (param) {
38 | return param !== this
39 | } else {
40 | return false
41 | }
42 | }
43 |
44 | definition() { return `${this.dependsOn[0].ref()}.${this.prop}` }
45 | derivative(param: Param) {
46 | if (param === this) {
47 | return '1.0'
48 | } else {
49 | return '0.0'
50 | }
51 | }
52 | }
53 |
54 | export function Cache(target: Object, propertyKey: string, descriptor: PropertyDescriptor) {
55 | const originalMethod = descriptor.value
56 | let created = false
57 | const cache = new Map()
58 | descriptor.value = function(...args: any[]) {
59 | let cached = cache.get(this)
60 | if (!cached) {
61 | cached = originalMethod.apply(this, ...args)
62 | cache.set(this, cached)
63 | }
64 | return cached
65 | }
66 | return descriptor
67 | }
68 |
69 |
70 |
71 | export abstract class VectorOp extends Op {
72 | scalar() { return false }
73 |
74 | abstract size(): number
75 |
76 | @Cache
77 | public x(): Op { return new VecElementRef(this.ad, 'x', this) }
78 |
79 | @Cache
80 | public y(): Op { return new VecElementRef(this.ad, 'y', this) }
81 |
82 | @Cache
83 | public z(): Op { return new VecElementRef(this.ad, 'z', this) }
84 |
85 | @Cache
86 | public w(): Op { return new VecElementRef(this.ad, 'w', this) }
87 |
88 | public getVecElementRef(el: string) {
89 | if (el === 'x') {
90 | return this.x()
91 | } else if (el === 'y') {
92 | return this.y()
93 | } else if (el === 'z') {
94 | return this.z()
95 | } else if (el === 'w') {
96 | return this.w()
97 | } else {
98 | throw new Error(`Can't get element ref ${el}`)
99 | }
100 | }
101 |
102 | public glslType() {
103 | return `vec${this.size()}`
104 | }
105 |
106 | zeroDerivative() {
107 | return `${this.glslType()}(0.0)`
108 | }
109 |
110 | public u() { return this.x() }
111 | public v() { return this.y() }
112 | public r() { return this.x() }
113 | public g() { return this.y() }
114 | public b() { return this.z() }
115 | public a() { return this.w() }
116 | // I really wish I could just do a loop but I also want TS to statically type this,
117 | // so instead I just found permutations of all combinations and generated code to
118 | // paste in.
119 | // TODO make these refs instead of new vectors
120 | xyzw() { return new Vec(this.ad, this.x(), this.y(), this.z(), this.w()) }
121 | xywz() { return new Vec(this.ad, this.x(), this.y(), this.w(), this.z()) }
122 | xzyw() { return new Vec(this.ad, this.x(), this.z(), this.y(), this.w()) }
123 | xzwy() { return new Vec(this.ad, this.x(), this.z(), this.w(), this.y()) }
124 | xwyz() { return new Vec(this.ad, this.x(), this.w(), this.y(), this.z()) }
125 | xwzy() { return new Vec(this.ad, this.x(), this.w(), this.z(), this.y()) }
126 | yxzw() { return new Vec(this.ad, this.y(), this.x(), this.z(), this.w()) }
127 | yxwz() { return new Vec(this.ad, this.y(), this.x(), this.w(), this.z()) }
128 | yzxw() { return new Vec(this.ad, this.y(), this.z(), this.x(), this.w()) }
129 | yzwx() { return new Vec(this.ad, this.y(), this.z(), this.w(), this.x()) }
130 | ywxz() { return new Vec(this.ad, this.y(), this.w(), this.x(), this.z()) }
131 | ywzx() { return new Vec(this.ad, this.y(), this.w(), this.z(), this.x()) }
132 | zxyw() { return new Vec(this.ad, this.z(), this.x(), this.y(), this.w()) }
133 | zxwy() { return new Vec(this.ad, this.z(), this.x(), this.w(), this.y()) }
134 | zyxw() { return new Vec(this.ad, this.z(), this.y(), this.x(), this.w()) }
135 | zywx() { return new Vec(this.ad, this.z(), this.y(), this.w(), this.x()) }
136 | zwxy() { return new Vec(this.ad, this.z(), this.w(), this.x(), this.y()) }
137 | zwyx() { return new Vec(this.ad, this.z(), this.w(), this.y(), this.x()) }
138 | wxyz() { return new Vec(this.ad, this.w(), this.x(), this.y(), this.z()) }
139 | wxzy() { return new Vec(this.ad, this.w(), this.x(), this.z(), this.y()) }
140 | wyxz() { return new Vec(this.ad, this.w(), this.y(), this.x(), this.z()) }
141 | wyzx() { return new Vec(this.ad, this.w(), this.y(), this.z(), this.x()) }
142 | wzxy() { return new Vec(this.ad, this.w(), this.z(), this.x(), this.y()) }
143 | wzyx() { return new Vec(this.ad, this.w(), this.z(), this.y(), this.x()) }
144 | xyz() { return new Vec(this.ad, this.x(), this.y(), this.z()) }
145 | xzy() { return new Vec(this.ad, this.x(), this.z(), this.y()) }
146 | yxz() { return new Vec(this.ad, this.y(), this.x(), this.z()) }
147 | yzx() { return new Vec(this.ad, this.y(), this.z(), this.x()) }
148 | zxy() { return new Vec(this.ad, this.z(), this.x(), this.y()) }
149 | zyx() { return new Vec(this.ad, this.z(), this.y(), this.x()) }
150 | xyw() { return new Vec(this.ad, this.x(), this.y(), this.w()) }
151 | xwy() { return new Vec(this.ad, this.x(), this.w(), this.y()) }
152 | yxw() { return new Vec(this.ad, this.y(), this.x(), this.w()) }
153 | ywx() { return new Vec(this.ad, this.y(), this.w(), this.x()) }
154 | wxy() { return new Vec(this.ad, this.w(), this.x(), this.y()) }
155 | wyx() { return new Vec(this.ad, this.w(), this.y(), this.x()) }
156 | xy() { return new Vec(this.ad, this.x(), this.y()) }
157 | yx() { return new Vec(this.ad, this.y(), this.x()) }
158 | xzw() { return new Vec(this.ad, this.x(), this.z(), this.w()) }
159 | xwz() { return new Vec(this.ad, this.x(), this.w(), this.z()) }
160 | zxw() { return new Vec(this.ad, this.z(), this.x(), this.w()) }
161 | zwx() { return new Vec(this.ad, this.z(), this.w(), this.x()) }
162 | wxz() { return new Vec(this.ad, this.w(), this.x(), this.z()) }
163 | wzx() { return new Vec(this.ad, this.w(), this.z(), this.x()) }
164 | xz() { return new Vec(this.ad, this.x(), this.z()) }
165 | zx() { return new Vec(this.ad, this.z(), this.x()) }
166 | xw() { return new Vec(this.ad, this.x(), this.w()) }
167 | wx() { return new Vec(this.ad, this.w(), this.x()) }
168 | yzw() { return new Vec(this.ad, this.y(), this.z(), this.w()) }
169 | ywz() { return new Vec(this.ad, this.y(), this.w(), this.z()) }
170 | zyw() { return new Vec(this.ad, this.z(), this.y(), this.w()) }
171 | zwy() { return new Vec(this.ad, this.z(), this.w(), this.y()) }
172 | wyz() { return new Vec(this.ad, this.w(), this.y(), this.z()) }
173 | wzy() { return new Vec(this.ad, this.w(), this.z(), this.y()) }
174 | yz() { return new Vec(this.ad, this.y(), this.z()) }
175 | zy() { return new Vec(this.ad, this.z(), this.y()) }
176 | yw() { return new Vec(this.ad, this.y(), this.w()) }
177 | wy() { return new Vec(this.ad, this.w(), this.y()) }
178 | zw() { return new Vec(this.ad, this.z(), this.w()) }
179 | wz() { return new Vec(this.ad, this.w(), this.z()) }
180 | rgba() { return new Vec(this.ad, this.r(), this.g(), this.b(), this.a()) }
181 | rgab() { return new Vec(this.ad, this.r(), this.g(), this.a(), this.b()) }
182 | rbga() { return new Vec(this.ad, this.r(), this.b(), this.g(), this.a()) }
183 | rbag() { return new Vec(this.ad, this.r(), this.b(), this.a(), this.g()) }
184 | ragb() { return new Vec(this.ad, this.r(), this.a(), this.g(), this.b()) }
185 | rabg() { return new Vec(this.ad, this.r(), this.a(), this.b(), this.g()) }
186 | grba() { return new Vec(this.ad, this.g(), this.r(), this.b(), this.a()) }
187 | grab() { return new Vec(this.ad, this.g(), this.r(), this.a(), this.b()) }
188 | gbra() { return new Vec(this.ad, this.g(), this.b(), this.r(), this.a()) }
189 | gbar() { return new Vec(this.ad, this.g(), this.b(), this.a(), this.r()) }
190 | garb() { return new Vec(this.ad, this.g(), this.a(), this.r(), this.b()) }
191 | gabr() { return new Vec(this.ad, this.g(), this.a(), this.b(), this.r()) }
192 | brga() { return new Vec(this.ad, this.b(), this.r(), this.g(), this.a()) }
193 | brag() { return new Vec(this.ad, this.b(), this.r(), this.a(), this.g()) }
194 | bgra() { return new Vec(this.ad, this.b(), this.g(), this.r(), this.a()) }
195 | bgar() { return new Vec(this.ad, this.b(), this.g(), this.a(), this.r()) }
196 | barg() { return new Vec(this.ad, this.b(), this.a(), this.r(), this.g()) }
197 | bagr() { return new Vec(this.ad, this.b(), this.a(), this.g(), this.r()) }
198 | argb() { return new Vec(this.ad, this.a(), this.r(), this.g(), this.b()) }
199 | arbg() { return new Vec(this.ad, this.a(), this.r(), this.b(), this.g()) }
200 | agrb() { return new Vec(this.ad, this.a(), this.g(), this.r(), this.b()) }
201 | agbr() { return new Vec(this.ad, this.a(), this.g(), this.b(), this.r()) }
202 | abrg() { return new Vec(this.ad, this.a(), this.b(), this.r(), this.g()) }
203 | abgr() { return new Vec(this.ad, this.a(), this.b(), this.g(), this.r()) }
204 | rgb() { return new Vec(this.ad, this.r(), this.g(), this.b()) }
205 | rbg() { return new Vec(this.ad, this.r(), this.b(), this.g()) }
206 | grb() { return new Vec(this.ad, this.g(), this.r(), this.b()) }
207 | gbr() { return new Vec(this.ad, this.g(), this.b(), this.r()) }
208 | brg() { return new Vec(this.ad, this.b(), this.r(), this.g()) }
209 | bgr() { return new Vec(this.ad, this.b(), this.g(), this.r()) }
210 | rga() { return new Vec(this.ad, this.r(), this.g(), this.a()) }
211 | rag() { return new Vec(this.ad, this.r(), this.a(), this.g()) }
212 | gra() { return new Vec(this.ad, this.g(), this.r(), this.a()) }
213 | gar() { return new Vec(this.ad, this.g(), this.a(), this.r()) }
214 | arg() { return new Vec(this.ad, this.a(), this.r(), this.g()) }
215 | agr() { return new Vec(this.ad, this.a(), this.g(), this.r()) }
216 | rg() { return new Vec(this.ad, this.r(), this.g()) }
217 | gr() { return new Vec(this.ad, this.g(), this.r()) }
218 | rba() { return new Vec(this.ad, this.r(), this.b(), this.a()) }
219 | rab() { return new Vec(this.ad, this.r(), this.a(), this.b()) }
220 | bra() { return new Vec(this.ad, this.b(), this.r(), this.a()) }
221 | bar() { return new Vec(this.ad, this.b(), this.a(), this.r()) }
222 | arb() { return new Vec(this.ad, this.a(), this.r(), this.b()) }
223 | abr() { return new Vec(this.ad, this.a(), this.b(), this.r()) }
224 | rb() { return new Vec(this.ad, this.r(), this.b()) }
225 | br() { return new Vec(this.ad, this.b(), this.r()) }
226 | ra() { return new Vec(this.ad, this.r(), this.a()) }
227 | ar() { return new Vec(this.ad, this.a(), this.r()) }
228 | gba() { return new Vec(this.ad, this.g(), this.b(), this.a()) }
229 | gab() { return new Vec(this.ad, this.g(), this.a(), this.b()) }
230 | bga() { return new Vec(this.ad, this.b(), this.g(), this.a()) }
231 | bag() { return new Vec(this.ad, this.b(), this.a(), this.g()) }
232 | agb() { return new Vec(this.ad, this.a(), this.g(), this.b()) }
233 | abg() { return new Vec(this.ad, this.a(), this.b(), this.g()) }
234 | gb() { return new Vec(this.ad, this.g(), this.b()) }
235 | bg() { return new Vec(this.ad, this.b(), this.g()) }
236 | ga() { return new Vec(this.ad, this.g(), this.a()) }
237 | ag() { return new Vec(this.ad, this.a(), this.g()) }
238 | ba() { return new Vec(this.ad, this.b(), this.a()) }
239 | ab() { return new Vec(this.ad, this.a(), this.b()) }
240 | uv() { return new Vec(this.ad, this.u(), this.v()) }
241 | vu() { return new Vec(this.ad, this.v(), this.u()) }
242 | }
243 |
244 | export abstract class WithVecDependencies extends VectorOp {
245 | public get vecDependsOn() {
246 | return this.dependsOn as VecOp[]
247 | }
248 |
249 | public size() {
250 | return this.vecDependsOn[0].size()
251 | }
252 | }
253 |
254 | export abstract class ScalarWithVecDependencies extends Op {
255 | public get vecDependsOn() {
256 | return this.dependsOn as VecOp[]
257 | }
258 |
259 | public size() {
260 | return this.vecDependsOn[0].size()
261 | }
262 | }
263 |
264 | export class OffsetJacobian extends WithVecDependencies {
265 | constructor(ad, ...args) {
266 | super(ad, ...args)
267 | this.internalDerivatives.push(
268 | { op: this.offset(), param: this.position().x() },
269 | { op: this.offset(), param: this.position().y() },
270 | { op: this.offset(), param: this.position().z() },
271 | )
272 | for (const { op } of this.internalDerivatives) {
273 | op.usedIn.push(this)
274 | }
275 | }
276 |
277 | public size(): number {
278 | return 3
279 | }
280 |
281 | private position() {
282 | return this.dependsOn[0] as VecParam
283 | }
284 |
285 | private offset() {
286 | return this.dependsOn[1] as VectorOp
287 | }
288 |
289 | glslType() {
290 | return 'mat3'
291 | }
292 |
293 | definition() {
294 | const dodx = this.offset().derivRef(this.position().x())
295 | const dody = this.offset().derivRef(this.position().y())
296 | const dodz = this.offset().derivRef(this.position().z())
297 | return `mat3(${dodx},${dody},${dodz})`
298 | }
299 | derivative(_param: Param): string {
300 | throw new Error('Unimplemented')
301 | }
302 |
303 | public dot(vec3: VectorOp) {
304 | return new Mat3Dot(this.ad, this, vec3)
305 | }
306 | }
307 |
308 | export class Mat3Dot extends VectorOp {
309 | public size() {
310 | return 3
311 | }
312 |
313 | private mat3() {
314 | return this.dependsOn[0] as OffsetJacobian
315 | }
316 |
317 | private vec3() {
318 | return this.dependsOn[1] as VectorOp
319 | }
320 |
321 | definition() {
322 | return `${this.mat3().ref()}*${this.vec3().ref()}`
323 | }
324 | derivative(_param: Param): string {
325 | throw new Error('Unimplemented')
326 | }
327 | }
328 |
329 | export class Vec extends VectorOp {
330 | public size(): number {
331 | return this.dependsOn.length
332 | }
333 |
334 | definition() {
335 | return `vec${this.size()}(${this.dependsOn.map((op) => op.ref()).join(',')})`
336 | }
337 | derivative(param: Param) {
338 | return `vec${this.size()}(${this.dependsOn.map((op) => op.derivRef(param)).join(',')})`
339 | }
340 |
341 | public x() { return this.dependsOn[0] }
342 | public y() { return this.dependsOn[1] }
343 | public z() { return this.dependsOn[2] }
344 | public w() { return this.dependsOn[3] }
345 | }
346 |
347 | export class VecParam extends VectorOp {
348 | private name: string
349 | private _size: number
350 | public size() { return this._size }
351 |
352 | constructor(ad: ADBase, name: string, size: number) {
353 | super(ad)
354 | this.name = name
355 | this._size = size
356 | }
357 |
358 | @Cache
359 | public x() { return new VecParamElementRef(this.ad, 'x', this) }
360 |
361 | @Cache
362 | public y() { return new VecParamElementRef(this.ad, 'y', this) }
363 |
364 | @Cache
365 | public z() { return new VecParamElementRef(this.ad, 'z', this) }
366 |
367 | @Cache
368 | public w() { return new VecParamElementRef(this.ad, 'w', this) }
369 |
370 | private getElems() {
371 | return 'xyzw'
372 | .split('')
373 | .slice(0, this.size())
374 | .map((el) => this.getVecElementRef(el))
375 | }
376 |
377 | definition() { return this.name }
378 | derivative(param: Param) {
379 | return `vec${this.size()}(${this.getElems().map((el) => el.derivRef(param)).join(',')})`
380 | }
381 |
382 | public isConst(param?: Param) {
383 | if (param) {
384 | return param !== this.x() && param !== this.y() && param !== this.z()
385 | } else {
386 | return false
387 | }
388 | }
389 |
390 | public override initializer() { return '' }
391 | public override ref() { return this.definition() }
392 | public override derivInitializer(param: Param) {
393 | if (this.isConst(param) || !this.useTempVar()) {
394 | return ''
395 | } else {
396 | return `vec${this.size()} ${this.derivRef(param)}=${this.derivative(param)};\n`
397 | }
398 | }
399 | }
400 |
401 | export function WithVecBase(Base: T) {
402 | class AutoDiff extends Base {
403 | vec2Param = UserInput(function(name: string) {
404 | return new VecParam(this, name, 2)
405 | })
406 | vec3Param = UserInput(function(name: string) {
407 | return new VecParam(this, name, 3)
408 | })
409 | vec4Param = UserInput(function(name: string) {
410 | return new VecParam(this, name, 4)
411 | })
412 | vec2 = UserInput(function(x: Input, y: Input) {
413 | return new Vec(this, this.convertVal(x), this.convertVal(y))
414 | })
415 | vec3 = UserInput(function(x: Input, y: Input, z: Input) {
416 | return new Vec(this, ...this.convertVals([x, y, z]))
417 | })
418 | vec4 = UserInput(function(x: Input, y: Input, z: Input, w: Input) {
419 | return new Vec(this, ...this.convertVals([x, y, z, w]))
420 | })
421 | }
422 | return AutoDiff
423 | }
424 |
--------------------------------------------------------------------------------
/src/vecFunctions.ts:
--------------------------------------------------------------------------------
1 | import { Input, Op, Param, ADBase, ADConstructor, UserInput, EqOp, AndOp, Value, LtOp } from './base'
2 | import { Vec, VecParam, VectorOp, WithVecDependencies, ScalarWithVecDependencies, OffsetJacobian } from './vecBase'
3 | import { VecMult, VecSum } from './vecArithmetic'
4 | import { Abs } from './functions'
5 | import { Mult } from './arithmetic'
6 |
7 | export class VecMix extends WithVecDependencies {
8 | definition() {
9 | return `mix(${this.dependsOn.map((op) => op.ref()).join(',')})`
10 | }
11 | derivative(param: Param) {
12 | const [a, b, mix] = this.dependsOn
13 | const aDeriv = `(1.0-${a.ref()})*${mix.derivRef(param)}+(-${a.derivRef(param)})*${mix.ref()}`
14 | const bDeriv = `${b.ref()}*${mix.derivRef(param)}+${b.derivRef(param)}*${mix.ref()}`
15 | return `${aDeriv}+${bDeriv}`
16 | }
17 | }
18 |
19 | export class VecClamp extends WithVecDependencies {
20 | definition() {
21 | return `clamp(${this.dependsOn.map((op) => op.ref()).join(',')})`
22 | }
23 | derivative(param: Param) {
24 | // Get an expression for the derivative of just one element in the vector
25 | const elemClamp = (v, min, max) => `${v.ref()}<${min.ref()} ? 0.0 : (${v.ref()}>${max.ref()} ? 0.0 : ${v.derivRef(param)})`
26 |
27 | // Get refs for each element of each parameter
28 | const toRefs = (vec) => 'xyzw'.split('').slice(0, vec.size()).map((el) => vec.getVecElementRef(el))
29 | const [vecC, vecMin, vecMax] = this.vecDependsOn.map(toRefs)
30 |
31 | // Construct a vector out of the elementwise derivatives
32 | const innerDef = Array(this.size()).fill(0).map((_, i) => elemClamp(vecC[i], vecMin[i], vecMax[i])).join(',')
33 | return `vec${this.size()}(${innerDef})`
34 | }
35 | }
36 |
37 | export class VecMin extends WithVecDependencies {
38 | definition() {
39 | return `min(${this.dependsOn.map((op) => op.ref()).join(',')})`
40 | }
41 | derivative(param: Param) {
42 | // Get an expression for the derivative of just one element in the vector
43 | const elemMin = (a, b) => `${a.ref()}<${b.ref()} ? ${a.derivRef(param)} : ${b.derivRef(param)}`
44 |
45 | // Get refs for each element of each parameter
46 | const toRefs = (vec) => 'xyzw'.split('').slice(0, vec.size()).map((el) => vec.getVecElementRef(el))
47 | const [vecA, vecB] = this.vecDependsOn.map(toRefs)
48 |
49 | // Construct a vector out of the elementwise derivatives
50 | const innerDef = Array(this.size()).fill(0).map((_, i) => elemMin(vecA[i], vecB[i])).join(',')
51 | return `vec${this.size()}(${innerDef})`
52 | }
53 | }
54 |
55 | export class VecMax extends WithVecDependencies {
56 | definition() {
57 | return `max(${this.dependsOn.map((op) => op.ref()).join(',')})`
58 | }
59 | derivative(param: Param) {
60 | // Get an expression for the derivative of just one element in the vector
61 | const elemMax = (a, b) => `${a.ref()}>${b.ref()} ? ${a.derivRef(param)} : ${b.derivRef(param)}`
62 |
63 | // Get refs for each element of each parameter
64 | const toRefs = (vec) => 'xyzw'.split('').slice(0, vec.size()).map((el) => vec.getVecElementRef(el))
65 | const [vecA, vecB] = this.vecDependsOn.map(toRefs)
66 |
67 | // Construct a vector out of the elementwise derivatives
68 | const innerDef = Array(this.size()).fill(0).map((_, i) => elemMax(vecA[i], vecB[i])).join(',')
69 | return `vec${this.size()}(${innerDef})`
70 | }
71 | }
72 |
73 | export class VecIfElse extends WithVecDependencies {
74 | override size() {
75 | return this.vecDependsOn[1].size()
76 | }
77 | definition() {
78 | const [condition, thenOp, elseOp] = this.dependsOn
79 | return `${condition.ref()}?${thenOp.ref()}:${elseOp.ref()}`
80 | }
81 | derivative(param: Param) {
82 | const [condition, thenOp, elseOp] = this.dependsOn
83 | return `${condition.ref()}?${thenOp.derivRef(param)}:${elseOp.derivRef(param)}`
84 | }
85 | }
86 |
87 | export class VecNormalize extends WithVecDependencies {
88 | override size() {
89 | return this.vecDependsOn[0].size()
90 | }
91 | definition() {
92 | const [input] = this.dependsOn
93 | return `normalize(${input.ref()})`
94 | }
95 | derivative(param: Param): string {
96 | throw new Error('unimplemented')
97 | }
98 | }
99 |
100 | export class VecAbs extends WithVecDependencies {
101 | override size() {
102 | return this.vecDependsOn[0].size()
103 | }
104 | definition() {
105 | const [input] = this.dependsOn
106 | return `abs(${input.ref()})}`
107 | }
108 | derivative(param: Param): string {
109 | return '0.0'
110 | }
111 | }
112 |
113 | export class Dot extends ScalarWithVecDependencies {
114 | definition() {
115 | return `dot(${this.dependsOn.map((v) => v.ref()).join(',')})`
116 | }
117 | derivative(param: Param) {
118 | const [f, g] = this.vecDependsOn
119 | return 'xyzw'
120 | .split('')
121 | .slice(0, this.size())
122 | .map((el) => `${f.ref()}.${el}*${g.derivRef(param)}.${el}+${g.ref()}.${el}*${f.derivRef(param)}.${el}`)
123 | .join('+')
124 | }
125 | }
126 |
127 | export class Length extends ScalarWithVecDependencies {
128 | override scalar() { return true }
129 | definition() { return `length(${this.dependsOn[0].ref()})` }
130 | derivative(param: Param) {
131 | const outerDeriv = `0.5/length(${this.dependsOn[0].ref()})`
132 | const innerDeriv = 'xyzw'
133 | .split('')
134 | .slice(0, this.size())
135 | .map((el) => `2.0*${this.dependsOn[0].ref()}.${el}*${this.dependsOn[0].derivRef(param)}.${el}`)
136 | .join('+')
137 | return `${outerDeriv}*${innerDeriv}`
138 | }
139 | }
140 |
141 | export class Dist extends ScalarWithVecDependencies {
142 | definition() { return `distance(${this.dependsOn.map((v) => v.ref()).join(',')})` }
143 | derivative(param: Param) {
144 | const outerDeriv = `0.5/distance(${this.dependsOn.map((v) => v.ref()).join(',')})`
145 | const innerDeriv = 'xyzw'
146 | .split('')
147 | .slice(0, this.size())
148 | .map((el) => {
149 | const diff = this.dependsOn.map((v) => v.ref()).join('-')
150 | const derivDiff = this.dependsOn.map((v) => v.derivRef(param)).join('-')
151 | return `2.0*(${diff}).${el}*(${derivDiff}).${el}`
152 | })
153 | .join('+')
154 | return `${outerDeriv}*${innerDeriv}`
155 | }
156 | }
157 |
158 | export class Cross extends WithVecDependencies {
159 | override size() {
160 | return this.vecDependsOn[0].size()
161 | }
162 | definition() {
163 | const [a, b] = this.dependsOn
164 | return `cross(${a.ref()},${b.ref()})`
165 | }
166 | derivative(param: Param): string {
167 | throw new Error('unimplemented')
168 | }
169 | }
170 |
171 | export class Normalize extends WithVecDependencies {
172 | override size() {
173 | return this.vecDependsOn[0].size()
174 | }
175 | definition() {
176 | const [a, b] = this.dependsOn
177 | return `normalize(${a.ref()}})`
178 | }
179 | derivative(param: Param): string {
180 | throw new Error('unimplemented')
181 | }
182 | }
183 |
184 | declare module './vecBase' {
185 | interface VectorOp {
186 | mix(other: VectorOp, amt: Input): VectorOp
187 | clamp(min: VectorOp, max: VectorOp): VectorOp
188 | min(...params: VectorOp[]): VectorOp
189 | max(...params: VectorOp[]): VectorOp
190 | dot(other: VectorOp): Op
191 | length(): Op
192 | dist(other: VectorOp): Op
193 | adjustNormal(normal: VecParam, position: VecParam): VectorOp
194 | }
195 | }
196 | declare module './base' {
197 | interface Op {
198 | vecIfElse(thenOp: VectorOp, elseOp: VectorOp): VectorOp
199 | }
200 | }
201 |
202 | VectorOp.prototype.mix = UserInput(function(other: VectorOp, amt: Input) {
203 | return new VecMix(this.ad, this, other, this.ad.convertVal(amt))
204 | })
205 | VectorOp.prototype.clamp = UserInput(function(min: VectorOp, max: VectorOp) {
206 | return new VecClamp(this.ad, this, min, max)
207 | })
208 | VectorOp.prototype.min = UserInput(function(...params: VectorOp[]) {
209 | return params.reduce(
210 | (acc, next) => new VecMin(this.ad, acc, next),
211 | this,
212 | )
213 | })
214 | VectorOp.prototype.max = UserInput(function(...params: VectorOp[]) {
215 | return params.reduce(
216 | (acc, next) => new VecMax(this.ad, acc, next),
217 | this,
218 | )
219 | })
220 | VectorOp.prototype.dot = UserInput(function(other: VectorOp) {
221 | return new Dot(this.ad, this, other)
222 | })
223 | VectorOp.prototype.length = UserInput(function() {
224 | return new Length(this.ad, this)
225 | })
226 | VectorOp.prototype.dist = UserInput(function(other: VectorOp) {
227 | return new Dist(this.ad, this, other)
228 | })
229 | Op.prototype.vecIfElse = UserInput(function(thenOp: VectorOp, elseOp: VectorOp) {
230 | return new VecIfElse(this.ad, this, thenOp, elseOp)
231 | })
232 | VectorOp.prototype.adjustNormal = function(normal: VecParam, position: VecParam) {
233 | const x = new Vec(this.ad, ...this.ad.convertVals([1, 0, 0]))
234 | const y = new Vec(this.ad, ...this.ad.convertVals([0, 1, 0]))
235 | const yEq0 = new EqOp(this.ad, normal.y(), new Value(this.ad, 0))
236 | const zEq0 = new EqOp(this.ad, normal.z(), new Value(this.ad, 0))
237 | const normalIsX = new AndOp(this.ad, yEq0, zEq0)
238 | const other = normalIsX.vecIfElse(y, x)
239 | const v = new VecNormalize(this.ad, new Cross(this.ad, other, normal))
240 | const u = new Cross(this.ad, v, normal)
241 | const jacobian = new OffsetJacobian(this.ad, position, this)
242 | const dodu = new VecMult(this.ad, jacobian, u)
243 | const dodv = new VecMult(this.ad, jacobian, v)
244 | return new VecNormalize(this.ad, new Cross(
245 | this.ad,
246 | new VecSum(this.ad, u, dodu),
247 | new VecSum(this.ad, v, dodv),
248 | ))
249 | }
250 |
251 | export function WithVecFunctions(Base: T) {
252 | class AutoDiff extends Base {
253 | vecMix = UserInput(function(a: VectorOp, b: VectorOp, amt: Input) {
254 | return a.mix(b, amt)
255 | })
256 | vecClamp = UserInput(function(val: VectorOp, min: VectorOp, max: VectorOp) {
257 | return val.clamp(min, max)
258 | })
259 | vecMin = UserInput(function(...params: VectorOp[]) {
260 | if (params.length === 0) {
261 | throw new Error(`No arguments passed to vecMin()!`)
262 | } else {
263 | return params.reduce((acc, next) => acc.min(next))
264 | }
265 | })
266 | vecMax = UserInput(function(...params: VectorOp[]) {
267 | if (params.length === 0) {
268 | throw new Error(`No arguments passed to vecMax()!`)
269 | } else {
270 | return params.reduce((acc, next) => acc.max(next))
271 | }
272 | })
273 | dot = UserInput(function(a: VectorOp, b: VectorOp) {
274 | return a.dot(b)
275 | })
276 | length = UserInput(function(val: VectorOp) {
277 | return val.length()
278 | })
279 | dist = UserInput(function(a: VectorOp, b: VectorOp) {
280 | return a.dist(b)
281 | })
282 | }
283 | return AutoDiff
284 | }
285 |
--------------------------------------------------------------------------------
/test/advanced_plane/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | glsl-autodiff test
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test/advanced_plane/test.js:
--------------------------------------------------------------------------------
1 | const vert = `
2 | attribute vec3 aPosition;
3 | attribute vec3 aNormal;
4 | attribute vec2 aTexCoord;
5 |
6 | uniform mat4 uModelViewMatrix;
7 | uniform mat4 uProjectionMatrix;
8 | uniform mat3 uNormalMatrix;
9 |
10 | uniform float time;
11 |
12 | varying vec2 vTexCoord;
13 | varying vec3 vNormal;
14 | varying vec3 vPosition;
15 |
16 | void main(void) {
17 | vec4 objSpacePosition = vec4(aPosition, 1.0);
18 | float origZ = objSpacePosition.z;
19 | ${AutoDiff.gen((ad) => {
20 | const aTexCoord = ad.vec2Param('aTexCoord')
21 | const time = ad.param('time')
22 |
23 | const displace_sin = (vec, magnitude, t, waviness, angle) => {
24 | const cos_angle = ad.cos(angle)
25 | const sin_angle = ad.sin(angle)
26 | const dist = vec.dot(ad.vec2(cos_angle, sin_angle))
27 | return magnitude.mult(ad.sin(t.add(dist.mult(waviness))))
28 | }
29 |
30 | const displace_rad = (vec, magnitude, t, waviness, center) => {
31 | const dist = vec.dist(center)
32 | const timeScaledDist = t.add(dist.mult(waviness))
33 |
34 | return magnitude.mult(
35 | ad.sum(
36 | ad.sin(timeScaledDist.mult(6)),
37 | ad.sin(timeScaledDist),
38 | -1
39 | ).max(0).pow(2),
40 | )
41 | }
42 |
43 | let offset = ad.val(0)
44 | offset = offset.add(displace_sin(aTexCoord, ad.sin(time).mult(0.5), time.mult(5), ad.val(5), ad.val(2*Math.PI/8)))
45 | offset = offset.add(displace_sin(aTexCoord, ad.sin(time.add(10)).add(5).mult(0.15), time.mult(5).add(50), ad.val(10), ad.val(2*Math.PI*0.4)))
46 | offset = offset.sub(displace_rad(aTexCoord, ad.sin(time).add(1), time.mult(1.5).add(8), ad.val(4), ad.vec2(-0.5, -0.5)))
47 | offset = offset.mult(0.08)
48 |
49 | offset.output('z')
50 | offset.outputDeriv('dzdx', aTexCoord.x())
51 | offset.outputDeriv('dzdy', aTexCoord.y())
52 | })}
53 | objSpacePosition.z += z;
54 | vec3 slopeX = vec3(1.0, 0.0, dzdx);
55 | vec3 slopeY = vec3(0.0, 1.0, dzdy);
56 | vec4 worldSpacePosition = uModelViewMatrix * objSpacePosition;
57 | gl_Position = uProjectionMatrix * worldSpacePosition;
58 | vTexCoord = aTexCoord;
59 | vPosition = worldSpacePosition.xyz;
60 | vNormal = uNormalMatrix * normalize(cross(slopeX, slopeY));
61 | }
62 | `
63 | console.log(vert)
64 |
65 | const frag = `
66 | precision mediump float;
67 | const int MAX_LIGHTS = 3;
68 |
69 | varying vec2 vTexCoord;
70 | varying vec3 vNormal;
71 | varying vec3 vPosition;
72 |
73 | uniform sampler2D img;
74 | uniform int numLights;
75 | uniform vec3 lightPositions[MAX_LIGHTS];
76 | uniform vec3 lightColors[MAX_LIGHTS];
77 | uniform float lightStrengths[MAX_LIGHTS];
78 | uniform vec3 ambientLight;
79 | uniform float materialShininess;
80 |
81 | void main(void) {
82 | vec3 materialColor = texture2D(img, vTexCoord).rgb;
83 | vec3 normal = normalize(vNormal);
84 | vec3 color = vec3(0.0, 0.0, 0.0);
85 | for (int i = 0; i < MAX_LIGHTS; i++) {
86 | if (i >= numLights) break;
87 | vec3 lightPosition = lightPositions[i];
88 | float distanceSquared = 0.0; /*0.00015*dot(
89 | lightPosition - vPosition,
90 | lightPosition - vPosition);*/
91 | vec3 lightDir = normalize(lightPosition - vPosition);
92 | float lambertian = max(dot(lightDir, normal), 0.0);
93 | color += lambertian * materialColor * lightColors[i] *
94 | lightStrengths[i] / (1.0 + distanceSquared);
95 | vec3 viewDir = normalize(-vPosition);
96 | float spec = pow(
97 | max(dot(viewDir, reflect(-lightDir, normal)), 0.0),
98 | materialShininess);
99 | color += spec * lightStrengths[i] * lightColors[i] /
100 | (1.0 + distanceSquared);
101 | }
102 | color += ambientLight * materialColor;
103 | gl_FragColor = vec4(color, 1.0);
104 | }
105 | `
106 |
107 | let distortShader
108 | let texture
109 | function setup() {
110 | createCanvas(800, 600, WEBGL)
111 | distortShader = createShader(vert, frag)
112 | texture = createGraphics(500, 500)
113 | }
114 |
115 | const lights = [{
116 | position: [200, 50, -100],
117 | color: [1, 1, 1],
118 | strength: 0.5,
119 | },
120 | {
121 | position: [-200, -50, -100],
122 | color: [1, 1, 1],
123 | strength: 0.5,
124 | },
125 | ];
126 |
127 | function draw() {
128 | texture.background(255, 0, 0)
129 | texture.fill(255)
130 | texture.noStroke()
131 | texture.textSize(70)
132 | texture.textAlign(CENTER, CENTER)
133 | texture.text('hello, world', texture.width / 2, texture.height / 2)
134 |
135 | background(0)
136 |
137 | const shininess = 1000
138 | const ambient = [0.2, 0.2, 0.2]
139 |
140 | orbitControl()
141 | noStroke()
142 | shader(distortShader)
143 | distortShader.setUniform('img', texture)
144 | distortShader.setUniform('lightPositions', lights.map(l => l.position).flat())
145 | distortShader.setUniform('lightColors', lights.map(l => l.color).flat())
146 | distortShader.setUniform('lightStrengths', lights.map(l => l.strength).flat())
147 | distortShader.setUniform('numLights', lights.length)
148 | distortShader.setUniform('ambientLight', ambient)
149 | distortShader.setUniform('materialShininess', shininess)
150 | distortShader.setUniform('time', frameCount*.005)
151 | push()
152 | const r = 200
153 | scale(r)
154 | plane(1, 1, 40, 40)
155 | pop()
156 | }
157 |
--------------------------------------------------------------------------------
/test/simple-wiggle/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | glsl-autodiff test
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test/simple-wiggle/test.js:
--------------------------------------------------------------------------------
1 | const vert = `
2 | attribute vec3 aPosition;
3 | attribute vec3 aNormal;
4 | attribute vec2 aTexCoord;
5 |
6 | uniform mat4 uModelViewMatrix;
7 | uniform mat4 uProjectionMatrix;
8 | uniform mat3 uNormalMatrix;
9 |
10 | uniform float time;
11 |
12 | varying vec2 vTexCoord;
13 | varying vec3 vNormal;
14 | varying vec3 vPosition;
15 |
16 | void main(void) {
17 | vec4 objSpacePosition = vec4(aPosition, 1.0);
18 | float origZ = objSpacePosition.z;
19 | ${AutoDiff.gen((ad) => {
20 | const pos = ad.vec3Param('objSpacePosition')
21 | const y = pos.y()
22 | const time = ad.param('time')
23 |
24 | offset = ad.vec3(time.mult(0.005).add(y.mult(2)).sin().mult(0.5), 0, 0)
25 | offset.output('offset')
26 | offset.adjustNormal(ad.vec3Param('aNormal'), pos).output('normal')
27 | //offset.output('z')
28 | //offset.outputDeriv('dzdx', x)
29 | //offset.outputDeriv('dzdy', y)
30 | }, { debug: true, maxDepthPerVariable: 8 })}
31 | objSpacePosition.xyz += offset;
32 | //vec3 slopeX = vec3(1.0, 0.0, dzdx);
33 | //vec3 slopeY = vec3(0.0, 1.0, dzdy);
34 | vec4 worldSpacePosition = uModelViewMatrix * objSpacePosition;
35 | gl_Position = uProjectionMatrix * worldSpacePosition;
36 | vTexCoord = aTexCoord;
37 | vPosition = worldSpacePosition.xyz;
38 | //vNormal = uNormalMatrix * aNormal;
39 | //normal=cross(_glslad_v66,_glslad_v65);
40 | //normal=_glslad_v66;
41 | vNormal = uNormalMatrix * normal;
42 | }
43 | `
44 | console.log(vert)
45 |
46 | const frag = `
47 | precision mediump float;
48 | const int MAX_LIGHTS = 3;
49 |
50 | varying vec2 vTexCoord;
51 | varying vec3 vNormal;
52 | varying vec3 vPosition;
53 |
54 | uniform sampler2D img;
55 | uniform int numLights;
56 | uniform vec3 lightPositions[MAX_LIGHTS];
57 | uniform vec3 lightColors[MAX_LIGHTS];
58 | uniform float lightStrengths[MAX_LIGHTS];
59 | uniform vec3 ambientLight;
60 | uniform float materialShininess;
61 |
62 | void main(void) {
63 | vec3 materialColor = texture2D(img, vTexCoord).rgb;
64 | vec3 normal = normalize(vNormal);
65 | gl_FragColor = vec4(abs(normal), 1.); return;
66 | //gl_FragColor = length(vNormal) * vec4(1.); return;
67 | vec3 color = vec3(0.0, 0.0, 0.0);
68 | for (int i = 0; i < MAX_LIGHTS; i++) {
69 | if (i >= numLights) break;
70 | vec3 lightPosition = lightPositions[i];
71 | float distanceSquared = 0.0; /*0.00015*dot(
72 | lightPosition - vPosition,
73 | lightPosition - vPosition);*/
74 | vec3 lightDir = normalize(lightPosition - vPosition);
75 | float lambertian = max(dot(lightDir, normal), 0.0);
76 | color += lambertian * materialColor * lightColors[i] *
77 | lightStrengths[i] / (1.0 + distanceSquared);
78 | vec3 viewDir = normalize(-vPosition);
79 | float spec = pow(
80 | max(dot(viewDir, reflect(-lightDir, normal)), 0.0),
81 | materialShininess);
82 | color += spec * lightStrengths[i] * lightColors[i] /
83 | (1.0 + distanceSquared);
84 | }
85 | color += ambientLight * materialColor;
86 | gl_FragColor = vec4(color, 1.0);
87 | }
88 | `
89 |
90 | let distortShader
91 | let texture
92 | function setup() {
93 | createCanvas(800, 600, WEBGL)
94 | distortShader = createShader(vert, frag)
95 | texture = createGraphics(500, 500)
96 | }
97 |
98 | const lights = [{
99 | position: [200, 50, -100],
100 | color: [1, 1, 1],
101 | strength: 0.5,
102 | },
103 | {
104 | position: [-200, -50, -100],
105 | color: [1, 1, 1],
106 | strength: 0.5,
107 | },
108 | ];
109 |
110 | function draw() {
111 | texture.background(255, 0, 0)
112 | texture.fill(255)
113 | texture.noStroke()
114 | texture.textSize(70)
115 | texture.textAlign(CENTER, CENTER)
116 | texture.text('hello, world', texture.width / 2, texture.height / 2)
117 |
118 | background(0)
119 |
120 | const shininess = 1000
121 | const ambient = [0.2, 0.2, 0.2]
122 |
123 | orbitControl()
124 | noStroke()
125 | shader(distortShader)
126 | distortShader.setUniform('img', texture)
127 | distortShader.setUniform('lightPositions', lights.map(l => l.position).flat())
128 | distortShader.setUniform('lightColors', lights.map(l => l.color).flat())
129 | distortShader.setUniform('lightStrengths', lights.map(l => l.strength).flat())
130 | distortShader.setUniform('numLights', lights.length)
131 | distortShader.setUniform('ambientLight', ambient)
132 | distortShader.setUniform('materialShininess', shininess)
133 | distortShader.setUniform('time', millis())
134 | push()
135 | sphere(200, 60, 30)
136 | pop()
137 | }
138 |
--------------------------------------------------------------------------------
/test/sine_plane/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | glsl-autodiff test
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test/sine_plane/test.js:
--------------------------------------------------------------------------------
1 | const vert = `
2 | attribute vec3 aPosition;
3 | attribute vec3 aNormal;
4 | attribute vec2 aTexCoord;
5 |
6 | uniform mat4 uModelViewMatrix;
7 | uniform mat4 uProjectionMatrix;
8 | uniform mat3 uNormalMatrix;
9 |
10 | uniform float time;
11 |
12 | varying vec2 vTexCoord;
13 | varying vec3 vNormal;
14 | varying vec3 vPosition;
15 |
16 | void main(void) {
17 | vec4 objSpacePosition = vec4(aPosition, 1.0);
18 | float origZ = objSpacePosition.z;
19 | float x = objSpacePosition.x;
20 | float y = objSpacePosition.y;
21 | ${AutoDiff.gen((ad) => {
22 | const x = ad.param('x')
23 | const y = ad.param('y')
24 | const time = ad.param('time')
25 | const speedX = 1.5
26 | const speedY = 2.8
27 |
28 | let offset = ad.val(0)
29 | for (let i = 0; i < 3; i++) {
30 | offset = offset.add(ad.sin(
31 | ad.sum(
32 | offset.mult(0.5).add(x.mult(speedX)).add(y.mult(speedY)),
33 | time.mult(0.002),
34 | )
35 | ))
36 | }
37 | offset = offset.mult(0.1)
38 | offset.output('z')
39 | offset.outputDeriv('dzdx', x)
40 | offset.outputDeriv('dzdy', y)
41 | }, { debug: true, maxDepthPerVariable: 4 })}
42 | objSpacePosition.z += z;
43 | vec3 slopeX = vec3(1.0, 0.0, dzdx);
44 | vec3 slopeY = vec3(0.0, 1.0, dzdy);
45 | vec4 worldSpacePosition = uModelViewMatrix * objSpacePosition;
46 | gl_Position = uProjectionMatrix * worldSpacePosition;
47 | vTexCoord = aTexCoord;
48 | vPosition = worldSpacePosition.xyz;
49 | vNormal = uNormalMatrix * normalize(cross(slopeX, slopeY));
50 | }
51 | `
52 | console.log(vert)
53 |
54 | const frag = `
55 | precision mediump float;
56 | const int MAX_LIGHTS = 3;
57 |
58 | varying vec2 vTexCoord;
59 | varying vec3 vNormal;
60 | varying vec3 vPosition;
61 |
62 | uniform sampler2D img;
63 | uniform int numLights;
64 | uniform vec3 lightPositions[MAX_LIGHTS];
65 | uniform vec3 lightColors[MAX_LIGHTS];
66 | uniform float lightStrengths[MAX_LIGHTS];
67 | uniform vec3 ambientLight;
68 | uniform float materialShininess;
69 |
70 | void main(void) {
71 | vec3 materialColor = texture2D(img, vTexCoord).rgb;
72 | vec3 normal = normalize(vNormal);
73 | vec3 color = vec3(0.0, 0.0, 0.0);
74 | for (int i = 0; i < MAX_LIGHTS; i++) {
75 | if (i >= numLights) break;
76 | vec3 lightPosition = lightPositions[i];
77 | float distanceSquared = 0.0; /*0.00015*dot(
78 | lightPosition - vPosition,
79 | lightPosition - vPosition);*/
80 | vec3 lightDir = normalize(lightPosition - vPosition);
81 | float lambertian = max(dot(lightDir, normal), 0.0);
82 | color += lambertian * materialColor * lightColors[i] *
83 | lightStrengths[i] / (1.0 + distanceSquared);
84 | vec3 viewDir = normalize(-vPosition);
85 | float spec = pow(
86 | max(dot(viewDir, reflect(-lightDir, normal)), 0.0),
87 | materialShininess);
88 | color += spec * lightStrengths[i] * lightColors[i] /
89 | (1.0 + distanceSquared);
90 | }
91 | color += ambientLight * materialColor;
92 | gl_FragColor = vec4(color, 1.0);
93 | }
94 | `
95 |
96 | let distortShader
97 | let texture
98 | function setup() {
99 | createCanvas(800, 600, WEBGL)
100 | distortShader = createShader(vert, frag)
101 | texture = createGraphics(500, 500)
102 | }
103 |
104 | const lights = [{
105 | position: [200, 50, -100],
106 | color: [1, 1, 1],
107 | strength: 0.5,
108 | },
109 | {
110 | position: [-200, -50, -100],
111 | color: [1, 1, 1],
112 | strength: 0.5,
113 | },
114 | ];
115 |
116 | function draw() {
117 | texture.background(255, 0, 0)
118 | texture.fill(255)
119 | texture.noStroke()
120 | texture.textSize(70)
121 | texture.textAlign(CENTER, CENTER)
122 | texture.text('hello, world', texture.width / 2, texture.height / 2)
123 |
124 | background(0)
125 |
126 | const shininess = 1000
127 | const ambient = [0.2, 0.2, 0.2]
128 |
129 | orbitControl()
130 | noStroke()
131 | shader(distortShader)
132 | distortShader.setUniform('img', texture)
133 | distortShader.setUniform('lightPositions', lights.map(l => l.position).flat())
134 | distortShader.setUniform('lightColors', lights.map(l => l.color).flat())
135 | distortShader.setUniform('lightStrengths', lights.map(l => l.strength).flat())
136 | distortShader.setUniform('numLights', lights.length)
137 | distortShader.setUniform('ambientLight', ambient)
138 | distortShader.setUniform('materialShininess', shininess)
139 | distortShader.setUniform('time', millis())
140 | push()
141 | const r = 200
142 | scale(r)
143 | plane(1, 1, 20, 20)
144 | pop()
145 | }
146 |
--------------------------------------------------------------------------------
/test/sinenoise_plane/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | glsl-autodiff test
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test/sinenoise_plane/test.js:
--------------------------------------------------------------------------------
1 | const vert = `
2 | //standard vertex shader
3 | #ifdef GL_ES
4 | precision mediump float;
5 | #endif
6 |
7 | // attributes, in
8 | attribute vec3 aPosition;
9 | attribute vec3 aNormal;
10 | attribute vec2 aTexCoord;
11 | attribute vec4 aVertexColor;
12 |
13 | // attributes, out
14 | varying vec2 vTexCoord;
15 | varying vec3 vNormal;
16 | varying vec3 vPosition;
17 |
18 | uniform float time;
19 | uniform float wind;
20 | uniform float anchor;
21 | uniform float height;
22 |
23 | // matrices
24 | uniform mat4 uModelViewMatrix;
25 | uniform mat4 uProjectionMatrix;
26 | uniform mat3 uNormalMatrix;
27 |
28 |
29 | /*float sinnoise(vec2 u ){
30 | vec2 zoom = vec2(4.0,4.0);
31 | vec2 offset = vec2(10.,1.);
32 | vec2 cumul = u*zoom+offset;
33 | float a_x = 0.4;
34 | float a_y = 0.4;
35 | for(int i=1; i< 4; i++){
36 | float float_i = float(i);
37 | cumul.x+= a_x*sin(float_i*cumul.y+time);
38 | cumul.y+= a_y*cos(float_i*cumul.x+time);
39 | };
40 |
41 | float r = sin(cumul.x*cumul.y)*.5+.5;
42 | r = smoothstep(-0.5,1.5,r);
43 | return r;
44 |
45 | }*/
46 |
47 | void main() {
48 | vec3 pos = aPosition;
49 | vec3 inputNorm = aNormal;
50 | float var_height = height;
51 |
52 | float var_anchor = -pos.x;
53 | if(anchor == 1.) var_anchor = -pos.y;
54 | if(anchor == 2.) var_anchor = pos.x;
55 | if(anchor == 3.) var_anchor = pos.y;
56 |
57 | ${AutoDiff.gen((ad) => {
58 | const pos = ad.vec2Param('pos.xy')
59 | const time = ad.param('time')
60 | const var_anchor = ad.param('var_anchor')
61 | const var_height = ad.param('var_height')
62 | const wind = ad.param('wind')
63 |
64 | const smoothstep = (edge0, edge1, x) => {
65 | const t = x.sub(edge0).div(edge1.sub(edge0)).clamp(0, 1)
66 | return t.mult(t).mult(t.mult(-2).add(3))
67 | }
68 |
69 | const sinnoise = (u) => {
70 | const zoom = ad.vec2(4, 4)
71 | const offset = ad.vec2(10, 1)
72 | let cumul = u.mult(zoom).add(offset)
73 | const a = ad.vec2(0.4, 0.4)
74 | for (let i = 1; i < 4; i++) {
75 | cumul = cumul.add(
76 | ad
77 | .vec2(
78 | ad.sin(ad.val(i).mult(cumul.y()).add(time)),
79 | ad.sin(ad.val(i).mult(cumul.x()).add(time)),
80 | )
81 | .mult(a),
82 | )
83 | }
84 |
85 | const r = ad.sin(cumul.x().mult(cumul.y())).mult(0.5).add(0.5)
86 | return smoothstep(ad.val(-0.5), ad.val(1.5), r)
87 | }
88 |
89 | const sn = sinnoise(pos.neg().scale(0.1))
90 | const z = sn.mult(var_anchor.mult(2).sub(1)).mult(var_height).mult(wind)
91 | z.output('z')
92 | z.outputDeriv('dzdx', pos.x())
93 | z.outputDeriv('dzdy', pos.y())
94 | })}
95 |
96 | //float sn = sinnoise(-pos.xy*.10);
97 | //pos.z = sn * (var_anchor*2.-1.) * var_height * wind;
98 | pos.z = z;
99 | vec3 slopeX = vec3(1.0, 0.0, dzdx);
100 | vec3 slopeY = vec3(0.0, 1.0, dzdy);
101 | vNormal = uNormalMatrix * normalize(cross(slopeX, slopeY));
102 |
103 | gl_Position = uProjectionMatrix *
104 | uModelViewMatrix *
105 | vec4(pos, 1.0);
106 |
107 | vPosition = pos;
108 | vTexCoord = aTexCoord;
109 |
110 | }
111 | `
112 | console.log(vert)
113 |
114 | const frag = `
115 | precision mediump float;
116 | const int MAX_LIGHTS = 3;
117 |
118 | varying vec2 vTexCoord;
119 | varying vec3 vNormal;
120 | varying vec3 vPosition;
121 |
122 | uniform sampler2D img;
123 | uniform int numLights;
124 | uniform vec3 lightPositions[MAX_LIGHTS];
125 | uniform vec3 lightColors[MAX_LIGHTS];
126 | uniform float lightStrengths[MAX_LIGHTS];
127 | uniform vec3 ambientLight;
128 | uniform float materialShininess;
129 |
130 | void main() {
131 |
132 | vec3 materialColor = texture2D(img, vTexCoord).rgb;
133 | vec3 normal = normalize(vNormal);
134 | vec3 color = vec3(0.0, 0.0, 0.0);
135 | for (int i = 0; i < MAX_LIGHTS; i++) {
136 | if (i >= numLights) break;
137 | vec3 toLightNormal = normal;
138 | vec3 lightPosition = lightPositions[i];
139 | float distanceSquared = 0.0; /*0.00015*dot(
140 | lightPosition - vPosition,
141 | lightPosition - vPosition);*/
142 | vec3 lightDir = normalize(lightPosition - vPosition);
143 | if (dot(lightDir, toLightNormal) < 0.0) {
144 | toLightNormal *= -1.0;
145 | }
146 | float lambertian = max(dot(lightDir, toLightNormal), 0.0);
147 | color += lambertian * materialColor * lightColors[i] *
148 | lightStrengths[i] / (1.0 + distanceSquared);
149 | vec3 viewDir = normalize(-vPosition);
150 | float spec = pow(
151 | max(dot(viewDir, reflect(-lightDir, toLightNormal)), 0.0),
152 | materialShininess);
153 | color += spec * lightStrengths[i] * lightColors[i] /
154 | (1.0 + distanceSquared);
155 | }
156 | color += ambientLight * materialColor;
157 | gl_FragColor = vec4(color, 1.0);
158 | //gl_FragColor = vec4(normal, 1.0);
159 | }
160 | `
161 |
162 | let distortShader
163 | let texture
164 | function setup() {
165 | createCanvas(800, 600, WEBGL)
166 | distortShader = createShader(vert, frag)
167 | texture = createGraphics(500, 500)
168 | }
169 |
170 | const lights = [{
171 | position: [200, 50, -100],
172 | color: [1, 1, 1],
173 | strength: 0.5,
174 | },
175 | {
176 | position: [-200, -50, -100],
177 | color: [1, 1, 1],
178 | strength: 0.5,
179 | },
180 | ];
181 |
182 | function draw() {
183 | texture.background(255, 0, 0)
184 | texture.fill(255)
185 | texture.noStroke()
186 | texture.textSize(70)
187 | texture.textAlign(CENTER, CENTER)
188 | texture.text('hello, world', texture.width / 2, texture.height / 2)
189 |
190 | background(0)
191 |
192 | const shininess = 1000
193 | const ambient = [0.2, 0.2, 0.2]
194 |
195 | orbitControl()
196 | noStroke()
197 | shader(distortShader)
198 | distortShader.setUniform('height', 0.4)
199 | distortShader.setUniform('wind', 1)
200 | distortShader.setUniform('anchor', 0)
201 | distortShader.setUniform('time', frameCount*.005)
202 | distortShader.setUniform('img', texture)
203 | distortShader.setUniform('lightPositions', lights.map(l => l.position).flat())
204 | distortShader.setUniform('lightColors', lights.map(l => l.color).flat())
205 | distortShader.setUniform('lightStrengths', lights.map(l => l.strength).flat())
206 | distortShader.setUniform('numLights', lights.length)
207 | distortShader.setUniform('ambientLight', ambient)
208 | distortShader.setUniform('materialShininess', shininess)
209 | push()
210 | const r = 200
211 | scale(r)
212 | plane(1, 1, 40, 40)
213 | pop()
214 | }
215 |
--------------------------------------------------------------------------------
/test/sphere/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | glsl-autodiff test
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test/sphere/test.js:
--------------------------------------------------------------------------------
1 | const vert = `
2 | attribute vec3 aPosition;
3 | attribute vec3 aNormal;
4 | attribute vec2 aTexCoord;
5 |
6 | uniform mat4 uModelViewMatrix;
7 | uniform mat4 uProjectionMatrix;
8 | uniform mat3 uNormalMatrix;
9 |
10 | uniform float time;
11 |
12 | varying vec2 vTexCoord;
13 | varying vec3 vNormal;
14 | varying vec3 vPosition;
15 |
16 | void main(void) {
17 | vec4 objSpacePosition = vec4(aPosition, 1.0);
18 | float origZ = objSpacePosition.z;
19 | ${AutoDiff.gen((ad) => {
20 | const pos = ad.vec3Param('objSpacePosition')
21 | const x = pos.x()
22 | const y = pos.y()
23 | const time = ad.param('time')
24 | const speedX = 1.5
25 | const speedY = 2.8
26 |
27 | let offset = ad.val(0)
28 | for (let i = 0; i < 3; i++) {
29 | offset = offset.add(ad.sin(
30 | ad.sum(
31 | offset.mult(0.5).add(x.mult(speedX)).add(y.mult(speedY)),
32 | time.mult(0.002),
33 | )
34 | ))
35 | }
36 | offset = offset.mult(0.1)
37 | offset = ad.vec3(0, 0, offset)
38 | offset.output('offset')
39 | offset.adjustNormal(ad.vec3Param('aNormal'), pos).output('normal')
40 | //offset.output('z')
41 | //offset.outputDeriv('dzdx', x)
42 | //offset.outputDeriv('dzdy', y)
43 | }, { debug: true, maxDepthPerVariable: 4 })}
44 | objSpacePosition.xyz += offset;
45 | //vec3 slopeX = vec3(1.0, 0.0, dzdx);
46 | //vec3 slopeY = vec3(0.0, 1.0, dzdy);
47 | vec4 worldSpacePosition = uModelViewMatrix * objSpacePosition;
48 | gl_Position = uProjectionMatrix * worldSpacePosition;
49 | vTexCoord = aTexCoord;
50 | vPosition = worldSpacePosition.xyz;
51 | //vNormal = uNormalMatrix * aNormal;
52 | //normal=cross(_glslad_v66,_glslad_v65);
53 | //normal=_glslad_v66;
54 | vNormal = uNormalMatrix * normal;
55 | }
56 | `
57 | console.log(vert)
58 |
59 | const frag = `
60 | precision mediump float;
61 | const int MAX_LIGHTS = 3;
62 |
63 | varying vec2 vTexCoord;
64 | varying vec3 vNormal;
65 | varying vec3 vPosition;
66 |
67 | uniform sampler2D img;
68 | uniform int numLights;
69 | uniform vec3 lightPositions[MAX_LIGHTS];
70 | uniform vec3 lightColors[MAX_LIGHTS];
71 | uniform float lightStrengths[MAX_LIGHTS];
72 | uniform vec3 ambientLight;
73 | uniform float materialShininess;
74 |
75 | void main(void) {
76 | vec3 materialColor = texture2D(img, vTexCoord).rgb;
77 | vec3 normal = normalize(vNormal);
78 | gl_FragColor = vec4(abs(normal), 1.); return;
79 | //gl_FragColor = length(vNormal) * vec4(1.); return;
80 | vec3 color = vec3(0.0, 0.0, 0.0);
81 | for (int i = 0; i < MAX_LIGHTS; i++) {
82 | if (i >= numLights) break;
83 | vec3 lightPosition = lightPositions[i];
84 | float distanceSquared = 0.0; /*0.00015*dot(
85 | lightPosition - vPosition,
86 | lightPosition - vPosition);*/
87 | vec3 lightDir = normalize(lightPosition - vPosition);
88 | float lambertian = max(dot(lightDir, normal), 0.0);
89 | color += lambertian * materialColor * lightColors[i] *
90 | lightStrengths[i] / (1.0 + distanceSquared);
91 | vec3 viewDir = normalize(-vPosition);
92 | float spec = pow(
93 | max(dot(viewDir, reflect(-lightDir, normal)), 0.0),
94 | materialShininess);
95 | color += spec * lightStrengths[i] * lightColors[i] /
96 | (1.0 + distanceSquared);
97 | }
98 | color += ambientLight * materialColor;
99 | gl_FragColor = vec4(color, 1.0);
100 | }
101 | `
102 |
103 | let distortShader
104 | let texture
105 | function setup() {
106 | createCanvas(800, 600, WEBGL)
107 | distortShader = createShader(vert, frag)
108 | texture = createGraphics(500, 500)
109 | }
110 |
111 | const lights = [{
112 | position: [200, 50, -100],
113 | color: [1, 1, 1],
114 | strength: 0.5,
115 | },
116 | {
117 | position: [-200, -50, -100],
118 | color: [1, 1, 1],
119 | strength: 0.5,
120 | },
121 | ];
122 |
123 | function draw() {
124 | texture.background(255, 0, 0)
125 | texture.fill(255)
126 | texture.noStroke()
127 | texture.textSize(70)
128 | texture.textAlign(CENTER, CENTER)
129 | texture.text('hello, world', texture.width / 2, texture.height / 2)
130 |
131 | background(0)
132 |
133 | const shininess = 1000
134 | const ambient = [0.2, 0.2, 0.2]
135 |
136 | orbitControl()
137 | noStroke()
138 | shader(distortShader)
139 | distortShader.setUniform('img', texture)
140 | distortShader.setUniform('lightPositions', lights.map(l => l.position).flat())
141 | distortShader.setUniform('lightColors', lights.map(l => l.color).flat())
142 | distortShader.setUniform('lightStrengths', lights.map(l => l.strength).flat())
143 | distortShader.setUniform('numLights', lights.length)
144 | distortShader.setUniform('ambientLight', ambient)
145 | distortShader.setUniform('materialShininess', shininess)
146 | distortShader.setUniform('time', millis())
147 | push()
148 | sphere(200, 60, 30)
149 | pop()
150 | }
151 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["es2015", "dom"],
4 | "outDir": "build",
5 | "allowJs": true,
6 | "experimentalDecorators": true,
7 | "emitDecoratorMetadata": true,
8 | "noImplicitAny": false,
9 | "downlevelIteration": true,
10 | "module": "commonjs",
11 | "strictPropertyInitialization": true,
12 | "forceConsistentCasingInFileNames": true,
13 | "esModuleInterop": true,
14 | "moduleResolution": "node",
15 | "removeComments": true,
16 | "target": "es6",
17 | "sourceMap": true,
18 | "strictNullChecks": true,
19 | "downlevelIteration": true,
20 | "declaration": true
21 | },
22 | "include": ["./src"],
23 | "exclude": [
24 | "node_modules",
25 | "*/node_modules"
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | module.exports = (env, argv) => {
4 | const mode = argv.mode ?? 'production'
5 | const config = {
6 | context: path.resolve(__dirname, 'src'),
7 | entry: './index.ts',
8 | mode,
9 | module: {
10 | rules: [{
11 | test: /\.tsx?$/,
12 | use: 'ts-loader',
13 | exclude: /node_modules/
14 | }]
15 | },
16 | output: {
17 | filename: 'autodiff.js',
18 | path: path.resolve(__dirname, 'build'),
19 | libraryTarget: 'umd',
20 | library: 'AutoDiff',
21 | },
22 | resolve: {
23 | extensions: ['.tsx', '.ts', '.jsx', '.js']
24 | },
25 | }
26 |
27 | if (mode === 'development') {
28 | config.devtool = 'inline-source-map'
29 | }
30 |
31 | return config
32 | };
33 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@discoveryjs/json-ext@^0.5.0":
6 | version "0.5.3"
7 | resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz#90420f9f9c6d3987f176a19a7d8e764271a2f55d"
8 | integrity sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g==
9 |
10 | "@tsconfig/node10@^1.0.7":
11 | version "1.0.8"
12 | resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9"
13 | integrity sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==
14 |
15 | "@tsconfig/node12@^1.0.7":
16 | version "1.0.9"
17 | resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.9.tgz#62c1f6dee2ebd9aead80dc3afa56810e58e1a04c"
18 | integrity sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==
19 |
20 | "@tsconfig/node14@^1.0.0":
21 | version "1.0.1"
22 | resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2"
23 | integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==
24 |
25 | "@tsconfig/node16@^1.0.1":
26 | version "1.0.1"
27 | resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.1.tgz#a6ca6a9a0ff366af433f42f5f0e124794ff6b8f1"
28 | integrity sha512-FTgBI767POY/lKNDNbIzgAX6miIDBs6NTCbdlDb8TrWovHsSvaVIZDlTqym29C6UqhzwcJx4CYr+AlrMywA0cA==
29 |
30 | "@types/eslint-scope@^3.7.0":
31 | version "3.7.0"
32 | resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.0.tgz#4792816e31119ebd506902a482caec4951fabd86"
33 | integrity sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==
34 | dependencies:
35 | "@types/eslint" "*"
36 | "@types/estree" "*"
37 |
38 | "@types/eslint@*":
39 | version "7.2.13"
40 | resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.13.tgz#e0ca7219ba5ded402062ad6f926d491ebb29dd53"
41 | integrity sha512-LKmQCWAlnVHvvXq4oasNUMTJJb2GwSyTY8+1C7OH5ILR8mPLaljv1jxL1bXW3xB3jFbQxTKxJAvI8PyjB09aBg==
42 | dependencies:
43 | "@types/estree" "*"
44 | "@types/json-schema" "*"
45 |
46 | "@types/estree@*", "@types/estree@^0.0.48":
47 | version "0.0.48"
48 | resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.48.tgz#18dc8091b285df90db2f25aa7d906cfc394b7f74"
49 | integrity sha512-LfZwXoGUDo0C3me81HXgkBg5CTQYb6xzEl+fNmbO4JdRiSKQ8A0GD1OBBvKAIsbCUgoyAty7m99GqqMQe784ew==
50 |
51 | "@types/json-schema@*", "@types/json-schema@^7.0.6":
52 | version "7.0.7"
53 | resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad"
54 | integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==
55 |
56 | "@types/node@*", "@types/node@^15.12.5":
57 | version "15.12.5"
58 | resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.5.tgz#9a78318a45d75c9523d2396131bd3cca54b2d185"
59 | integrity sha512-se3yX7UHv5Bscf8f1ERKvQOD6sTyycH3hdaoozvaLxgUiY5lIGEeH37AD0G0Qi9kPqihPn0HOfd2yaIEN9VwEg==
60 |
61 | "@webassemblyjs/ast@1.11.0":
62 | version "1.11.0"
63 | resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.0.tgz#a5aa679efdc9e51707a4207139da57920555961f"
64 | integrity sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==
65 | dependencies:
66 | "@webassemblyjs/helper-numbers" "1.11.0"
67 | "@webassemblyjs/helper-wasm-bytecode" "1.11.0"
68 |
69 | "@webassemblyjs/floating-point-hex-parser@1.11.0":
70 | version "1.11.0"
71 | resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz#34d62052f453cd43101d72eab4966a022587947c"
72 | integrity sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==
73 |
74 | "@webassemblyjs/helper-api-error@1.11.0":
75 | version "1.11.0"
76 | resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz#aaea8fb3b923f4aaa9b512ff541b013ffb68d2d4"
77 | integrity sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==
78 |
79 | "@webassemblyjs/helper-buffer@1.11.0":
80 | version "1.11.0"
81 | resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz#d026c25d175e388a7dbda9694e91e743cbe9b642"
82 | integrity sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==
83 |
84 | "@webassemblyjs/helper-numbers@1.11.0":
85 | version "1.11.0"
86 | resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz#7ab04172d54e312cc6ea4286d7d9fa27c88cd4f9"
87 | integrity sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==
88 | dependencies:
89 | "@webassemblyjs/floating-point-hex-parser" "1.11.0"
90 | "@webassemblyjs/helper-api-error" "1.11.0"
91 | "@xtuc/long" "4.2.2"
92 |
93 | "@webassemblyjs/helper-wasm-bytecode@1.11.0":
94 | version "1.11.0"
95 | resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz#85fdcda4129902fe86f81abf7e7236953ec5a4e1"
96 | integrity sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==
97 |
98 | "@webassemblyjs/helper-wasm-section@1.11.0":
99 | version "1.11.0"
100 | resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz#9ce2cc89300262509c801b4af113d1ca25c1a75b"
101 | integrity sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==
102 | dependencies:
103 | "@webassemblyjs/ast" "1.11.0"
104 | "@webassemblyjs/helper-buffer" "1.11.0"
105 | "@webassemblyjs/helper-wasm-bytecode" "1.11.0"
106 | "@webassemblyjs/wasm-gen" "1.11.0"
107 |
108 | "@webassemblyjs/ieee754@1.11.0":
109 | version "1.11.0"
110 | resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz#46975d583f9828f5d094ac210e219441c4e6f5cf"
111 | integrity sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==
112 | dependencies:
113 | "@xtuc/ieee754" "^1.2.0"
114 |
115 | "@webassemblyjs/leb128@1.11.0":
116 | version "1.11.0"
117 | resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.0.tgz#f7353de1df38aa201cba9fb88b43f41f75ff403b"
118 | integrity sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==
119 | dependencies:
120 | "@xtuc/long" "4.2.2"
121 |
122 | "@webassemblyjs/utf8@1.11.0":
123 | version "1.11.0"
124 | resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.0.tgz#86e48f959cf49e0e5091f069a709b862f5a2cadf"
125 | integrity sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==
126 |
127 | "@webassemblyjs/wasm-edit@1.11.0":
128 | version "1.11.0"
129 | resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz#ee4a5c9f677046a210542ae63897094c2027cb78"
130 | integrity sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==
131 | dependencies:
132 | "@webassemblyjs/ast" "1.11.0"
133 | "@webassemblyjs/helper-buffer" "1.11.0"
134 | "@webassemblyjs/helper-wasm-bytecode" "1.11.0"
135 | "@webassemblyjs/helper-wasm-section" "1.11.0"
136 | "@webassemblyjs/wasm-gen" "1.11.0"
137 | "@webassemblyjs/wasm-opt" "1.11.0"
138 | "@webassemblyjs/wasm-parser" "1.11.0"
139 | "@webassemblyjs/wast-printer" "1.11.0"
140 |
141 | "@webassemblyjs/wasm-gen@1.11.0":
142 | version "1.11.0"
143 | resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz#3cdb35e70082d42a35166988dda64f24ceb97abe"
144 | integrity sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==
145 | dependencies:
146 | "@webassemblyjs/ast" "1.11.0"
147 | "@webassemblyjs/helper-wasm-bytecode" "1.11.0"
148 | "@webassemblyjs/ieee754" "1.11.0"
149 | "@webassemblyjs/leb128" "1.11.0"
150 | "@webassemblyjs/utf8" "1.11.0"
151 |
152 | "@webassemblyjs/wasm-opt@1.11.0":
153 | version "1.11.0"
154 | resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz#1638ae188137f4bb031f568a413cd24d32f92978"
155 | integrity sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==
156 | dependencies:
157 | "@webassemblyjs/ast" "1.11.0"
158 | "@webassemblyjs/helper-buffer" "1.11.0"
159 | "@webassemblyjs/wasm-gen" "1.11.0"
160 | "@webassemblyjs/wasm-parser" "1.11.0"
161 |
162 | "@webassemblyjs/wasm-parser@1.11.0":
163 | version "1.11.0"
164 | resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz#3e680b8830d5b13d1ec86cc42f38f3d4a7700754"
165 | integrity sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==
166 | dependencies:
167 | "@webassemblyjs/ast" "1.11.0"
168 | "@webassemblyjs/helper-api-error" "1.11.0"
169 | "@webassemblyjs/helper-wasm-bytecode" "1.11.0"
170 | "@webassemblyjs/ieee754" "1.11.0"
171 | "@webassemblyjs/leb128" "1.11.0"
172 | "@webassemblyjs/utf8" "1.11.0"
173 |
174 | "@webassemblyjs/wast-printer@1.11.0":
175 | version "1.11.0"
176 | resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz#680d1f6a5365d6d401974a8e949e05474e1fab7e"
177 | integrity sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==
178 | dependencies:
179 | "@webassemblyjs/ast" "1.11.0"
180 | "@xtuc/long" "4.2.2"
181 |
182 | "@webpack-cli/configtest@^1.0.4":
183 | version "1.0.4"
184 | resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.0.4.tgz#f03ce6311c0883a83d04569e2c03c6238316d2aa"
185 | integrity sha512-cs3XLy+UcxiP6bj0A6u7MLLuwdXJ1c3Dtc0RkKg+wiI1g/Ti1om8+/2hc2A2B60NbBNAbMgyBMHvyymWm/j4wQ==
186 |
187 | "@webpack-cli/info@^1.3.0":
188 | version "1.3.0"
189 | resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.3.0.tgz#9d78a31101a960997a4acd41ffd9b9300627fe2b"
190 | integrity sha512-ASiVB3t9LOKHs5DyVUcxpraBXDOKubYu/ihHhU+t1UPpxsivg6Od2E2qU4gJCekfEddzRBzHhzA/Acyw/mlK/w==
191 | dependencies:
192 | envinfo "^7.7.3"
193 |
194 | "@webpack-cli/serve@^1.5.1":
195 | version "1.5.1"
196 | resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.5.1.tgz#b5fde2f0f79c1e120307c415a4c1d5eb15a6f278"
197 | integrity sha512-4vSVUiOPJLmr45S8rMGy7WDvpWxfFxfP/Qx/cxZFCfvoypTYpPPL1X8VIZMe0WTA+Jr7blUxwUSEZNkjoMTgSw==
198 |
199 | "@xtuc/ieee754@^1.2.0":
200 | version "1.2.0"
201 | resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
202 | integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==
203 |
204 | "@xtuc/long@4.2.2":
205 | version "4.2.2"
206 | resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
207 | integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
208 |
209 | acorn@^8.2.1:
210 | version "8.4.1"
211 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c"
212 | integrity sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==
213 |
214 | ajv-keywords@^3.5.2:
215 | version "3.5.2"
216 | resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d"
217 | integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==
218 |
219 | ajv@^6.12.5:
220 | version "6.12.6"
221 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
222 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
223 | dependencies:
224 | fast-deep-equal "^3.1.1"
225 | fast-json-stable-stringify "^2.0.0"
226 | json-schema-traverse "^0.4.1"
227 | uri-js "^4.2.2"
228 |
229 | ansi-styles@^4.1.0:
230 | version "4.3.0"
231 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
232 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
233 | dependencies:
234 | color-convert "^2.0.1"
235 |
236 | arg@^4.1.0:
237 | version "4.1.3"
238 | resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
239 | integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
240 |
241 | array-union@^1.0.1:
242 | version "1.0.2"
243 | resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
244 | integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=
245 | dependencies:
246 | array-uniq "^1.0.1"
247 |
248 | array-uniq@^1.0.1:
249 | version "1.0.3"
250 | resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
251 | integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=
252 |
253 | async@^2.6.1:
254 | version "2.6.3"
255 | resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
256 | integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==
257 | dependencies:
258 | lodash "^4.17.14"
259 |
260 | balanced-match@^1.0.0:
261 | version "1.0.2"
262 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
263 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
264 |
265 | brace-expansion@^1.1.7:
266 | version "1.1.11"
267 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
268 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
269 | dependencies:
270 | balanced-match "^1.0.0"
271 | concat-map "0.0.1"
272 |
273 | braces@^3.0.1:
274 | version "3.0.2"
275 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
276 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
277 | dependencies:
278 | fill-range "^7.0.1"
279 |
280 | browserslist@^4.14.5:
281 | version "4.16.6"
282 | resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2"
283 | integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==
284 | dependencies:
285 | caniuse-lite "^1.0.30001219"
286 | colorette "^1.2.2"
287 | electron-to-chromium "^1.3.723"
288 | escalade "^3.1.1"
289 | node-releases "^1.1.71"
290 |
291 | buffer-from@^1.0.0:
292 | version "1.1.1"
293 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
294 | integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
295 |
296 | caniuse-lite@^1.0.30001219:
297 | version "1.0.30001241"
298 | resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001241.tgz#cd3fae47eb3d7691692b406568d7a3e5b23c7598"
299 | integrity sha512-1uoSZ1Pq1VpH0WerIMqwptXHNNGfdl7d1cJUFs80CwQ/lVzdhTvsFZCeNFslze7AjsQnb4C85tzclPa1VShbeQ==
300 |
301 | chalk@^4.1.0:
302 | version "4.1.1"
303 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad"
304 | integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==
305 | dependencies:
306 | ansi-styles "^4.1.0"
307 | supports-color "^7.1.0"
308 |
309 | chrome-trace-event@^1.0.2:
310 | version "1.0.3"
311 | resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac"
312 | integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==
313 |
314 | clone-deep@^4.0.1:
315 | version "4.0.1"
316 | resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387"
317 | integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==
318 | dependencies:
319 | is-plain-object "^2.0.4"
320 | kind-of "^6.0.2"
321 | shallow-clone "^3.0.0"
322 |
323 | color-convert@^2.0.1:
324 | version "2.0.1"
325 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
326 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
327 | dependencies:
328 | color-name "~1.1.4"
329 |
330 | color-name@~1.1.4:
331 | version "1.1.4"
332 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
333 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
334 |
335 | colorette@^1.2.1, colorette@^1.2.2:
336 | version "1.2.2"
337 | resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
338 | integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==
339 |
340 | commander@^2.18.0, commander@^2.20.0:
341 | version "2.20.3"
342 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
343 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
344 |
345 | commander@^7.0.0:
346 | version "7.2.0"
347 | resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
348 | integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
349 |
350 | commondir@^1.0.1:
351 | version "1.0.1"
352 | resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
353 | integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=
354 |
355 | concat-map@0.0.1:
356 | version "0.0.1"
357 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
358 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
359 |
360 | create-require@^1.1.0:
361 | version "1.1.1"
362 | resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
363 | integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
364 |
365 | cross-spawn@^7.0.3:
366 | version "7.0.3"
367 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
368 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
369 | dependencies:
370 | path-key "^3.1.0"
371 | shebang-command "^2.0.0"
372 | which "^2.0.1"
373 |
374 | diff@^4.0.1:
375 | version "4.0.2"
376 | resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
377 | integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
378 |
379 | electron-to-chromium@^1.3.723:
380 | version "1.3.762"
381 | resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.762.tgz#3fa4e3bcbda539b50e3aa23041627063a5cffe61"
382 | integrity sha512-LehWjRpfPcK8F1Lf/NZoAwWLWnjJVo0SZeQ9j/tvnBWYcT99qDqgo4raAfS2oTKZjPrR/jxruh85DGgDUmywEA==
383 |
384 | email-addresses@^3.0.1:
385 | version "3.1.0"
386 | resolved "https://registry.yarnpkg.com/email-addresses/-/email-addresses-3.1.0.tgz#cabf7e085cbdb63008a70319a74e6136188812fb"
387 | integrity sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==
388 |
389 | enhanced-resolve@^5.0.0, enhanced-resolve@^5.8.0:
390 | version "5.8.2"
391 | resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz#15ddc779345cbb73e97c611cd00c01c1e7bf4d8b"
392 | integrity sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==
393 | dependencies:
394 | graceful-fs "^4.2.4"
395 | tapable "^2.2.0"
396 |
397 | envinfo@^7.7.3:
398 | version "7.8.1"
399 | resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475"
400 | integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==
401 |
402 | es-module-lexer@^0.6.0:
403 | version "0.6.0"
404 | resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.6.0.tgz#e72ab05b7412e62b9be37c37a09bdb6000d706f0"
405 | integrity sha512-f8kcHX1ArhllUtb/wVSyvygoKCznIjnxhLxy7TCvIiMdT7fL4ZDTIKaadMe6eLvOXg6Wk02UeoFgUoZ2EKZZUA==
406 |
407 | escalade@^3.1.1:
408 | version "3.1.1"
409 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
410 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
411 |
412 | escape-string-regexp@^1.0.2:
413 | version "1.0.5"
414 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
415 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
416 |
417 | eslint-scope@5.1.1:
418 | version "5.1.1"
419 | resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
420 | integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
421 | dependencies:
422 | esrecurse "^4.3.0"
423 | estraverse "^4.1.1"
424 |
425 | esrecurse@^4.3.0:
426 | version "4.3.0"
427 | resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
428 | integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
429 | dependencies:
430 | estraverse "^5.2.0"
431 |
432 | estraverse@^4.1.1:
433 | version "4.3.0"
434 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
435 | integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
436 |
437 | estraverse@^5.2.0:
438 | version "5.2.0"
439 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880"
440 | integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==
441 |
442 | events@^3.2.0:
443 | version "3.3.0"
444 | resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
445 | integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
446 |
447 | execa@^5.0.0:
448 | version "5.1.1"
449 | resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
450 | integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
451 | dependencies:
452 | cross-spawn "^7.0.3"
453 | get-stream "^6.0.0"
454 | human-signals "^2.1.0"
455 | is-stream "^2.0.0"
456 | merge-stream "^2.0.0"
457 | npm-run-path "^4.0.1"
458 | onetime "^5.1.2"
459 | signal-exit "^3.0.3"
460 | strip-final-newline "^2.0.0"
461 |
462 | fast-deep-equal@^3.1.1:
463 | version "3.1.3"
464 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
465 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
466 |
467 | fast-json-stable-stringify@^2.0.0:
468 | version "2.1.0"
469 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
470 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
471 |
472 | fastest-levenshtein@^1.0.12:
473 | version "1.0.12"
474 | resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2"
475 | integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==
476 |
477 | filename-reserved-regex@^2.0.0:
478 | version "2.0.0"
479 | resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229"
480 | integrity sha1-q/c9+rc10EVECr/qLZHzieu/oik=
481 |
482 | filenamify@^4.3.0:
483 | version "4.3.0"
484 | resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-4.3.0.tgz#62391cb58f02b09971c9d4f9d63b3cf9aba03106"
485 | integrity sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==
486 | dependencies:
487 | filename-reserved-regex "^2.0.0"
488 | strip-outer "^1.0.1"
489 | trim-repeated "^1.0.0"
490 |
491 | fill-range@^7.0.1:
492 | version "7.0.1"
493 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
494 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
495 | dependencies:
496 | to-regex-range "^5.0.1"
497 |
498 | find-cache-dir@^3.3.1:
499 | version "3.3.1"
500 | resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880"
501 | integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==
502 | dependencies:
503 | commondir "^1.0.1"
504 | make-dir "^3.0.2"
505 | pkg-dir "^4.1.0"
506 |
507 | find-up@^4.0.0:
508 | version "4.1.0"
509 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
510 | integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
511 | dependencies:
512 | locate-path "^5.0.0"
513 | path-exists "^4.0.0"
514 |
515 | fs-extra@^8.1.0:
516 | version "8.1.0"
517 | resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
518 | integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
519 | dependencies:
520 | graceful-fs "^4.2.0"
521 | jsonfile "^4.0.0"
522 | universalify "^0.1.0"
523 |
524 | fs.realpath@^1.0.0:
525 | version "1.0.0"
526 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
527 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
528 |
529 | function-bind@^1.1.1:
530 | version "1.1.1"
531 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
532 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
533 |
534 | get-stream@^6.0.0:
535 | version "6.0.1"
536 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
537 | integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
538 |
539 | gh-pages@^3.2.3:
540 | version "3.2.3"
541 | resolved "https://registry.yarnpkg.com/gh-pages/-/gh-pages-3.2.3.tgz#897e5f15e111f42af57d21d430b83e5cdf29472c"
542 | integrity sha512-jA1PbapQ1jqzacECfjUaO9gV8uBgU6XNMV0oXLtfCX3haGLe5Atq8BxlrADhbD6/UdG9j6tZLWAkAybndOXTJg==
543 | dependencies:
544 | async "^2.6.1"
545 | commander "^2.18.0"
546 | email-addresses "^3.0.1"
547 | filenamify "^4.3.0"
548 | find-cache-dir "^3.3.1"
549 | fs-extra "^8.1.0"
550 | globby "^6.1.0"
551 |
552 | glob-to-regexp@^0.4.1:
553 | version "0.4.1"
554 | resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
555 | integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
556 |
557 | glob@^7.0.3:
558 | version "7.1.7"
559 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90"
560 | integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==
561 | dependencies:
562 | fs.realpath "^1.0.0"
563 | inflight "^1.0.4"
564 | inherits "2"
565 | minimatch "^3.0.4"
566 | once "^1.3.0"
567 | path-is-absolute "^1.0.0"
568 |
569 | globby@^6.1.0:
570 | version "6.1.0"
571 | resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c"
572 | integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=
573 | dependencies:
574 | array-union "^1.0.1"
575 | glob "^7.0.3"
576 | object-assign "^4.0.1"
577 | pify "^2.0.0"
578 | pinkie-promise "^2.0.0"
579 |
580 | graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4:
581 | version "4.2.6"
582 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
583 | integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
584 |
585 | has-flag@^4.0.0:
586 | version "4.0.0"
587 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
588 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
589 |
590 | has@^1.0.3:
591 | version "1.0.3"
592 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
593 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
594 | dependencies:
595 | function-bind "^1.1.1"
596 |
597 | human-signals@^2.1.0:
598 | version "2.1.0"
599 | resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
600 | integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
601 |
602 | import-local@^3.0.2:
603 | version "3.0.2"
604 | resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.2.tgz#a8cfd0431d1de4a2199703d003e3e62364fa6db6"
605 | integrity sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==
606 | dependencies:
607 | pkg-dir "^4.2.0"
608 | resolve-cwd "^3.0.0"
609 |
610 | inflight@^1.0.4:
611 | version "1.0.6"
612 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
613 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
614 | dependencies:
615 | once "^1.3.0"
616 | wrappy "1"
617 |
618 | inherits@2:
619 | version "2.0.4"
620 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
621 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
622 |
623 | interpret@^2.2.0:
624 | version "2.2.0"
625 | resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9"
626 | integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==
627 |
628 | is-core-module@^2.2.0:
629 | version "2.4.0"
630 | resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1"
631 | integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==
632 | dependencies:
633 | has "^1.0.3"
634 |
635 | is-number@^7.0.0:
636 | version "7.0.0"
637 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
638 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
639 |
640 | is-plain-object@^2.0.4:
641 | version "2.0.4"
642 | resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
643 | integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==
644 | dependencies:
645 | isobject "^3.0.1"
646 |
647 | is-stream@^2.0.0:
648 | version "2.0.0"
649 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3"
650 | integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==
651 |
652 | isexe@^2.0.0:
653 | version "2.0.0"
654 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
655 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
656 |
657 | isobject@^3.0.1:
658 | version "3.0.1"
659 | resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
660 | integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
661 |
662 | jest-worker@^27.0.2:
663 | version "27.0.6"
664 | resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.6.tgz#a5fdb1e14ad34eb228cfe162d9f729cdbfa28aed"
665 | integrity sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA==
666 | dependencies:
667 | "@types/node" "*"
668 | merge-stream "^2.0.0"
669 | supports-color "^8.0.0"
670 |
671 | json-parse-better-errors@^1.0.2:
672 | version "1.0.2"
673 | resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
674 | integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==
675 |
676 | json-schema-traverse@^0.4.1:
677 | version "0.4.1"
678 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
679 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
680 |
681 | jsonfile@^4.0.0:
682 | version "4.0.0"
683 | resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
684 | integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
685 | optionalDependencies:
686 | graceful-fs "^4.1.6"
687 |
688 | kind-of@^6.0.2:
689 | version "6.0.3"
690 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
691 | integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
692 |
693 | loader-runner@^4.2.0:
694 | version "4.2.0"
695 | resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384"
696 | integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==
697 |
698 | locate-path@^5.0.0:
699 | version "5.0.0"
700 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
701 | integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
702 | dependencies:
703 | p-locate "^4.1.0"
704 |
705 | lodash@^4.17.14, lodash@^4.17.21:
706 | version "4.17.21"
707 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
708 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
709 |
710 | lru-cache@^6.0.0:
711 | version "6.0.0"
712 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
713 | integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
714 | dependencies:
715 | yallist "^4.0.0"
716 |
717 | make-dir@^3.0.2:
718 | version "3.1.0"
719 | resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
720 | integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==
721 | dependencies:
722 | semver "^6.0.0"
723 |
724 | make-error@^1.1.1:
725 | version "1.3.6"
726 | resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
727 | integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
728 |
729 | merge-stream@^2.0.0:
730 | version "2.0.0"
731 | resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
732 | integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
733 |
734 | micromatch@^4.0.0:
735 | version "4.0.4"
736 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
737 | integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
738 | dependencies:
739 | braces "^3.0.1"
740 | picomatch "^2.2.3"
741 |
742 | mime-db@1.48.0:
743 | version "1.48.0"
744 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d"
745 | integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==
746 |
747 | mime-types@^2.1.27:
748 | version "2.1.31"
749 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.31.tgz#a00d76b74317c61f9c2db2218b8e9f8e9c5c9e6b"
750 | integrity sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==
751 | dependencies:
752 | mime-db "1.48.0"
753 |
754 | mimic-fn@^2.1.0:
755 | version "2.1.0"
756 | resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
757 | integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
758 |
759 | minimatch@^3.0.4:
760 | version "3.0.4"
761 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
762 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
763 | dependencies:
764 | brace-expansion "^1.1.7"
765 |
766 | neo-async@^2.6.2:
767 | version "2.6.2"
768 | resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
769 | integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
770 |
771 | node-releases@^1.1.71:
772 | version "1.1.73"
773 | resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.73.tgz#dd4e81ddd5277ff846b80b52bb40c49edf7a7b20"
774 | integrity sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==
775 |
776 | npm-run-path@^4.0.1:
777 | version "4.0.1"
778 | resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
779 | integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
780 | dependencies:
781 | path-key "^3.0.0"
782 |
783 | object-assign@^4.0.1:
784 | version "4.1.1"
785 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
786 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
787 |
788 | once@^1.3.0:
789 | version "1.4.0"
790 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
791 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
792 | dependencies:
793 | wrappy "1"
794 |
795 | onetime@^5.1.2:
796 | version "5.1.2"
797 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
798 | integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
799 | dependencies:
800 | mimic-fn "^2.1.0"
801 |
802 | p-limit@^2.2.0:
803 | version "2.3.0"
804 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
805 | integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
806 | dependencies:
807 | p-try "^2.0.0"
808 |
809 | p-limit@^3.1.0:
810 | version "3.1.0"
811 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
812 | integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
813 | dependencies:
814 | yocto-queue "^0.1.0"
815 |
816 | p-locate@^4.1.0:
817 | version "4.1.0"
818 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07"
819 | integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
820 | dependencies:
821 | p-limit "^2.2.0"
822 |
823 | p-try@^2.0.0:
824 | version "2.2.0"
825 | resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
826 | integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
827 |
828 | path-exists@^4.0.0:
829 | version "4.0.0"
830 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
831 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
832 |
833 | path-is-absolute@^1.0.0:
834 | version "1.0.1"
835 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
836 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
837 |
838 | path-key@^3.0.0, path-key@^3.1.0:
839 | version "3.1.1"
840 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
841 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
842 |
843 | path-parse@^1.0.6:
844 | version "1.0.7"
845 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
846 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
847 |
848 | picomatch@^2.2.3:
849 | version "2.3.0"
850 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
851 | integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
852 |
853 | pify@^2.0.0:
854 | version "2.3.0"
855 | resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
856 | integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw=
857 |
858 | pinkie-promise@^2.0.0:
859 | version "2.0.1"
860 | resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
861 | integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o=
862 | dependencies:
863 | pinkie "^2.0.0"
864 |
865 | pinkie@^2.0.0:
866 | version "2.0.4"
867 | resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
868 | integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
869 |
870 | pkg-dir@^4.1.0, pkg-dir@^4.2.0:
871 | version "4.2.0"
872 | resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
873 | integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
874 | dependencies:
875 | find-up "^4.0.0"
876 |
877 | punycode@^2.1.0:
878 | version "2.1.1"
879 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
880 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
881 |
882 | randombytes@^2.1.0:
883 | version "2.1.0"
884 | resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
885 | integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
886 | dependencies:
887 | safe-buffer "^5.1.0"
888 |
889 | rechoir@^0.7.0:
890 | version "0.7.0"
891 | resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.0.tgz#32650fd52c21ab252aa5d65b19310441c7e03aca"
892 | integrity sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==
893 | dependencies:
894 | resolve "^1.9.0"
895 |
896 | resolve-cwd@^3.0.0:
897 | version "3.0.0"
898 | resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d"
899 | integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==
900 | dependencies:
901 | resolve-from "^5.0.0"
902 |
903 | resolve-from@^5.0.0:
904 | version "5.0.0"
905 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
906 | integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
907 |
908 | resolve@^1.9.0:
909 | version "1.20.0"
910 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
911 | integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
912 | dependencies:
913 | is-core-module "^2.2.0"
914 | path-parse "^1.0.6"
915 |
916 | safe-buffer@^5.1.0:
917 | version "5.2.1"
918 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
919 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
920 |
921 | schema-utils@^3.0.0:
922 | version "3.0.0"
923 | resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef"
924 | integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==
925 | dependencies:
926 | "@types/json-schema" "^7.0.6"
927 | ajv "^6.12.5"
928 | ajv-keywords "^3.5.2"
929 |
930 | semver@^6.0.0:
931 | version "6.3.0"
932 | resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
933 | integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
934 |
935 | semver@^7.3.4:
936 | version "7.3.5"
937 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
938 | integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
939 | dependencies:
940 | lru-cache "^6.0.0"
941 |
942 | serialize-javascript@^6.0.0:
943 | version "6.0.0"
944 | resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8"
945 | integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==
946 | dependencies:
947 | randombytes "^2.1.0"
948 |
949 | shallow-clone@^3.0.0:
950 | version "3.0.1"
951 | resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3"
952 | integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==
953 | dependencies:
954 | kind-of "^6.0.2"
955 |
956 | shebang-command@^2.0.0:
957 | version "2.0.0"
958 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
959 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
960 | dependencies:
961 | shebang-regex "^3.0.0"
962 |
963 | shebang-regex@^3.0.0:
964 | version "3.0.0"
965 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
966 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
967 |
968 | signal-exit@^3.0.3:
969 | version "3.0.3"
970 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
971 | integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
972 |
973 | source-list-map@^2.0.1:
974 | version "2.0.1"
975 | resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
976 | integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==
977 |
978 | source-map-support@^0.5.17, source-map-support@~0.5.19:
979 | version "0.5.19"
980 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
981 | integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
982 | dependencies:
983 | buffer-from "^1.0.0"
984 | source-map "^0.6.0"
985 |
986 | source-map@^0.6.0, source-map@^0.6.1:
987 | version "0.6.1"
988 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
989 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
990 |
991 | source-map@~0.7.2:
992 | version "0.7.3"
993 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
994 | integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
995 |
996 | strip-final-newline@^2.0.0:
997 | version "2.0.0"
998 | resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
999 | integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
1000 |
1001 | strip-outer@^1.0.1:
1002 | version "1.0.1"
1003 | resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631"
1004 | integrity sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==
1005 | dependencies:
1006 | escape-string-regexp "^1.0.2"
1007 |
1008 | supports-color@^7.1.0:
1009 | version "7.2.0"
1010 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
1011 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
1012 | dependencies:
1013 | has-flag "^4.0.0"
1014 |
1015 | supports-color@^8.0.0:
1016 | version "8.1.1"
1017 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
1018 | integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
1019 | dependencies:
1020 | has-flag "^4.0.0"
1021 |
1022 | tapable@^2.1.1, tapable@^2.2.0:
1023 | version "2.2.0"
1024 | resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b"
1025 | integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==
1026 |
1027 | terser-webpack-plugin@^5.1.3:
1028 | version "5.1.4"
1029 | resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz#c369cf8a47aa9922bd0d8a94fe3d3da11a7678a1"
1030 | integrity sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==
1031 | dependencies:
1032 | jest-worker "^27.0.2"
1033 | p-limit "^3.1.0"
1034 | schema-utils "^3.0.0"
1035 | serialize-javascript "^6.0.0"
1036 | source-map "^0.6.1"
1037 | terser "^5.7.0"
1038 |
1039 | terser@^5.7.0:
1040 | version "5.7.1"
1041 | resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.1.tgz#2dc7a61009b66bb638305cb2a824763b116bf784"
1042 | integrity sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg==
1043 | dependencies:
1044 | commander "^2.20.0"
1045 | source-map "~0.7.2"
1046 | source-map-support "~0.5.19"
1047 |
1048 | to-regex-range@^5.0.1:
1049 | version "5.0.1"
1050 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
1051 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
1052 | dependencies:
1053 | is-number "^7.0.0"
1054 |
1055 | trim-repeated@^1.0.0:
1056 | version "1.0.0"
1057 | resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21"
1058 | integrity sha1-42RqLqTokTEr9+rObPsFOAvAHCE=
1059 | dependencies:
1060 | escape-string-regexp "^1.0.2"
1061 |
1062 | ts-loader@^9.2.3:
1063 | version "9.2.3"
1064 | resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.3.tgz#dc3b6362a4d4382493cd4f138d345f419656de68"
1065 | integrity sha512-sEyWiU3JMHBL55CIeC4iqJQadI0U70A5af0kvgbNLHVNz2ACztQg0j/9x10bjjIht8WfFYLKfn4L6tkZ+pu+8Q==
1066 | dependencies:
1067 | chalk "^4.1.0"
1068 | enhanced-resolve "^5.0.0"
1069 | micromatch "^4.0.0"
1070 | semver "^7.3.4"
1071 |
1072 | ts-node@^10.0.0:
1073 | version "10.0.0"
1074 | resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.0.0.tgz#05f10b9a716b0b624129ad44f0ea05dac84ba3be"
1075 | integrity sha512-ROWeOIUvfFbPZkoDis0L/55Fk+6gFQNZwwKPLinacRl6tsxstTF1DbAcLKkovwnpKMVvOMHP1TIbnwXwtLg1gg==
1076 | dependencies:
1077 | "@tsconfig/node10" "^1.0.7"
1078 | "@tsconfig/node12" "^1.0.7"
1079 | "@tsconfig/node14" "^1.0.0"
1080 | "@tsconfig/node16" "^1.0.1"
1081 | arg "^4.1.0"
1082 | create-require "^1.1.0"
1083 | diff "^4.0.1"
1084 | make-error "^1.1.1"
1085 | source-map-support "^0.5.17"
1086 | yn "3.1.1"
1087 |
1088 | typescript@^4.3.4:
1089 | version "4.3.4"
1090 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.4.tgz#3f85b986945bcf31071decdd96cf8bfa65f9dcbc"
1091 | integrity sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==
1092 |
1093 | universalify@^0.1.0:
1094 | version "0.1.2"
1095 | resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
1096 | integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
1097 |
1098 | uri-js@^4.2.2:
1099 | version "4.4.1"
1100 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
1101 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
1102 | dependencies:
1103 | punycode "^2.1.0"
1104 |
1105 | v8-compile-cache@^2.2.0:
1106 | version "2.3.0"
1107 | resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
1108 | integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
1109 |
1110 | watchpack@^2.2.0:
1111 | version "2.2.0"
1112 | resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.2.0.tgz#47d78f5415fe550ecd740f99fe2882323a58b1ce"
1113 | integrity sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==
1114 | dependencies:
1115 | glob-to-regexp "^0.4.1"
1116 | graceful-fs "^4.1.2"
1117 |
1118 | webpack-cli@^4.7.2:
1119 | version "4.7.2"
1120 | resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.7.2.tgz#a718db600de6d3906a4357e059ae584a89f4c1a5"
1121 | integrity sha512-mEoLmnmOIZQNiRl0ebnjzQ74Hk0iKS5SiEEnpq3dRezoyR3yPaeQZCMCe+db4524pj1Pd5ghZXjT41KLzIhSLw==
1122 | dependencies:
1123 | "@discoveryjs/json-ext" "^0.5.0"
1124 | "@webpack-cli/configtest" "^1.0.4"
1125 | "@webpack-cli/info" "^1.3.0"
1126 | "@webpack-cli/serve" "^1.5.1"
1127 | colorette "^1.2.1"
1128 | commander "^7.0.0"
1129 | execa "^5.0.0"
1130 | fastest-levenshtein "^1.0.12"
1131 | import-local "^3.0.2"
1132 | interpret "^2.2.0"
1133 | rechoir "^0.7.0"
1134 | v8-compile-cache "^2.2.0"
1135 | webpack-merge "^5.7.3"
1136 |
1137 | webpack-merge@^5.7.3:
1138 | version "5.8.0"
1139 | resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61"
1140 | integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==
1141 | dependencies:
1142 | clone-deep "^4.0.1"
1143 | wildcard "^2.0.0"
1144 |
1145 | webpack-sources@^2.3.0:
1146 | version "2.3.0"
1147 | resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.3.0.tgz#9ed2de69b25143a4c18847586ad9eccb19278cfa"
1148 | integrity sha512-WyOdtwSvOML1kbgtXbTDnEW0jkJ7hZr/bDByIwszhWd/4XX1A3XMkrbFMsuH4+/MfLlZCUzlAdg4r7jaGKEIgQ==
1149 | dependencies:
1150 | source-list-map "^2.0.1"
1151 | source-map "^0.6.1"
1152 |
1153 | webpack@^5.41.1:
1154 | version "5.41.1"
1155 | resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.41.1.tgz#23fa1d82c95c222d3fc3163806b9a833fe52b253"
1156 | integrity sha512-AJZIIsqJ/MVTmegEq9Tlw5mk5EHdGiJbDdz9qP15vmUH+oxI1FdWcL0E9EO8K/zKaRPWqEs7G/OPxq1P61u5Ug==
1157 | dependencies:
1158 | "@types/eslint-scope" "^3.7.0"
1159 | "@types/estree" "^0.0.48"
1160 | "@webassemblyjs/ast" "1.11.0"
1161 | "@webassemblyjs/wasm-edit" "1.11.0"
1162 | "@webassemblyjs/wasm-parser" "1.11.0"
1163 | acorn "^8.2.1"
1164 | browserslist "^4.14.5"
1165 | chrome-trace-event "^1.0.2"
1166 | enhanced-resolve "^5.8.0"
1167 | es-module-lexer "^0.6.0"
1168 | eslint-scope "5.1.1"
1169 | events "^3.2.0"
1170 | glob-to-regexp "^0.4.1"
1171 | graceful-fs "^4.2.4"
1172 | json-parse-better-errors "^1.0.2"
1173 | loader-runner "^4.2.0"
1174 | mime-types "^2.1.27"
1175 | neo-async "^2.6.2"
1176 | schema-utils "^3.0.0"
1177 | tapable "^2.1.1"
1178 | terser-webpack-plugin "^5.1.3"
1179 | watchpack "^2.2.0"
1180 | webpack-sources "^2.3.0"
1181 |
1182 | which@^2.0.1:
1183 | version "2.0.2"
1184 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
1185 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
1186 | dependencies:
1187 | isexe "^2.0.0"
1188 |
1189 | wildcard@^2.0.0:
1190 | version "2.0.0"
1191 | resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec"
1192 | integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==
1193 |
1194 | wrappy@1:
1195 | version "1.0.2"
1196 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
1197 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
1198 |
1199 | yallist@^4.0.0:
1200 | version "4.0.0"
1201 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
1202 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
1203 |
1204 | yn@3.1.1:
1205 | version "3.1.1"
1206 | resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
1207 | integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
1208 |
1209 | yocto-queue@^0.1.0:
1210 | version "0.1.0"
1211 | resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
1212 | integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
1213 |
--------------------------------------------------------------------------------