├── .eslintrc.json ├── .github ├── eslint.json └── workflows │ └── node.js.yml ├── .gitignore ├── LICENSE ├── README.md ├── package.json ├── rollup.config.js ├── src ├── attitude.js ├── index.js ├── math.js ├── matrix.js ├── sinpi.js ├── vector.js └── versor.js ├── test ├── .eslintrc.json ├── attitude-test.js └── inDelta.js └── yarn.lock /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint:recommended", 3 | "parserOptions": { 4 | "sourceType": "module", 5 | "ecmaVersion": 8 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.github/eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "problemMatcher": [ 3 | { 4 | "owner": "eslint-compact", 5 | "pattern": [ 6 | { 7 | "regexp": "^(.+):\\sline\\s(\\d+),\\scol\\s(\\d+),\\s(Error|Warning|Info)\\s-\\s(.+)\\s\\((.+)\\)$", 8 | "file": 1, 9 | "line": 2, 10 | "column": 3, 11 | "severity": 4, 12 | "message": 5, 13 | "code": 6 14 | } 15 | ] 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | # https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 2 | 3 | name: Node.js CI 4 | 5 | on: 6 | push: 7 | branches: [ main ] 8 | pull_request: 9 | branches: [ main ] 10 | 11 | jobs: 12 | build: 13 | 14 | runs-on: ubuntu-latest 15 | 16 | strategy: 17 | matrix: 18 | node-version: [14.x] 19 | 20 | steps: 21 | - uses: actions/checkout@v2 22 | - name: Use Node.js ${{ matrix.node-version }} 23 | uses: actions/setup-node@v1 24 | with: 25 | node-version: ${{ matrix.node-version }} 26 | - run: yarn --frozen-lockfile 27 | - run: | 28 | echo ::add-matcher::.github/eslint.json 29 | yarn run eslint src test --format=compact 30 | - run: yarn test 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.sublime-workspace 2 | .DS_Store 3 | dist/ 4 | test/output/ 5 | node_modules 6 | npm-debug.log 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020-2021 Philippe Rivière 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # attitude 2 | 3 | _Attitude: orientation of an object in space._ 4 | 5 | A rotation of the sphere can be represented in various ways, such as: 6 | 7 | - [Euler Angles](#euler-angles) 8 | - [Axis-Angle](#axis-angle) 9 | - [Rotation Matrix](#rotation-matrix) 10 | - [Unit Quaternion](#unit-quaternion) (aka versor) 11 | - [Rotation Vector](#rotation-vector) 12 | 13 | The **attitude** module allows conversions and computations between all these representations. 14 | 15 | See https://observablehq.com/@fil/attitude for details. 16 | 17 | 18 | ## Installing 19 | 20 | If you use NPM, `npm install attitude`. Otherwise, download the [latest release](https://github.com/Fil/attitude/releases/latest). AMD, CommonJS, and vanilla environments are supported. In vanilla, an `attitude` global is exported: 21 | 22 | ```html 23 | 24 | 29 | ``` 30 | 31 | [Try attitude in your browser.](https://observablehq.com/collection/@fil/attitude) 32 | 33 | 34 | ## Representations 35 | 36 | 37 | ### Euler Angles 38 | 39 | `[lambda, phi, gamma]`, in degrees. 40 | 41 | ### Axis-Angle 42 | 43 | `{ axis: [lon, lat], angle: alpha }`, in degrees. 44 | 45 | ### Rotation Matrix 46 | 47 | ~~~{js} 48 | [ [r11, r12, r13], 49 | [r21, r22, r23], 50 | [r31, r32, r33] ] 51 | ~~~ 52 | 53 | ### Unit Quaternion 54 | 55 | `q = [q0, q1, q2, q3, q4]` is also called a *versor* when its norm is equal to 1. 56 | 57 | ### Rotation Vector 58 | 59 | `[ x, y, z ]` = *f(a)B*, where *f(a)* is a scalar encoding the angle, and *B* a unit vector in cartesian coordinates. 60 | 61 | *Note:* there are many ways to encode the angle, we have to settle on a default. The useful functions *f(a)* are: 62 | - *tan(a/4)*: stereographic, ‘Modified Rodrigues Parameters’. 63 | - *tan(a/2)*: gnomonic, ‘Rodrigues Parameters’, ‘Gibbs vector’. 64 | - *a*: equidistant, logarithm vector. 65 | - (vector part of the) unit quaternion: Euler angles. 66 | 67 | Defaults to the stereographic vector representation. 68 | 69 | 70 | ## API Reference 71 | 72 | # attitude([angles]) 73 | 74 | Returns an *attitude* object. Sets the rotation’s Euler angles if the *angles* argument is specified. *attitude* is equivalent to [d3.geoRotation(angles)](https://github.com/d3/d3-geo/blob/master/README.md#geoRotation), and can be used as a function to rotate a point [longitude, latitude]. 75 | 76 | ### Operations 77 | 78 | # *attitude*.invert(point) 79 | 80 | Returns the *inverse* rotation of the point. 81 | 82 | # *attitude*.inverse() 83 | 84 | Returns a new attitude, inverse of the original. 85 | 86 | # *attitude*.compose(b) 87 | 88 | Returns a new attitude, composition of the original with the argument. When *c* = *a*.compose(*b*) is applied to a point *p*, the result *c*(*p*) = *a*(*b*(*p*)): in other words, the rotation *b* will be applied first, then rotation *a*. 89 | 90 | # *attitude*.power(power) 91 | 92 | Returns a new partial attitude. *a*.power(2) is twice the rotation *a*, *a*.power(.5) is half the rotation *a*. 93 | 94 | # *attitude*.arc(A, B) 95 | 96 | Returns a new attitude that brings the point *A* to *B* by the shortest (geodesic) path. 97 | 98 | # *attitude*.interpolateTo(b) 99 | 100 | Returns an interpolator that continuously transitions the original *attitude* to the argument. The result is a function of *t* that is equivalent to *attitude* for *t* = 0, and equivalent to *b* for *t* = 1. Useful for [spherical linear interpolation (SLERP)](https://observablehq.com/d/b3c52ccf8f22ef2b?collection=@fil/attitude). 101 | 102 | 103 | ### Representations 104 | 105 | # *attitude*.angles([angles]) 106 | 107 | Sets or reads the *Euler angles* of an *attitude*, as an array [φ, λ, γ] (in degrees). 108 | 109 | # *attitude*.axis([axis]) 110 | 111 | Sets or reads the *rotation axis* of an *attitude*, as [lon, lat] coordinates. 112 | 113 | # *attitude*.angle([angle]) 114 | 115 | Sets or reads the *rotation angle* of an *attitude*, in degrees. 116 | 117 | # *attitude*.versor([versor]) 118 | 119 | Sets or reads the *versor* representation of an *attitude*, as a length-4 array. 120 | 121 | # *attitude*.matrix([matrix]) 122 | 123 | Sets or reads the *matrix* representation of an *attitude*, as a matrix of size 3×3. 124 | 125 | # *attitude*.vector([vector]) 126 | 127 | Sets or reads the *vector* representation of an *attitude*, as a length-3 array. That array can be written f(a)B, where f is a function of the rotation’s angle, and B a unit vector respresenting the axis in cartesian coordinates. 128 | 129 | Defaults to the [stereographic](#attitude_vectorStereographic) vector: f(a) = tan(a/4). 130 | 131 | # *attitude*.vectorStereographic([vector]) 132 | 133 | *Stereographic* vector: f(a) = tan(a/4). Also called the ‘Modified Rodrigues Parameters’. 134 | 135 | # *attitude*.vectorGnomonic([vector]) 136 | 137 | *Gnomonic* vector: f(a) = tan(a/2). Also called ‘Rodrigues Parameters’ or ‘Gibbs vector’. 138 | 139 | # *attitude*.vectorEquidistant([vector]) 140 | 141 | *Equidistant* vector: f(a) = a. Also called the logarithm vector. 142 | 143 | 144 | 145 | --- 146 | 147 | With thanks to [Jacob Rus](https://observablehq.com/@jrus), [Nadieh Bremer](https://www.visualcinnamon.com), [Mike Bostock](https://bost.ocks.org/mike/) and [Darcy Murphy](https://github.com/mrDarcyMurphy). 148 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "attitude", 3 | "version": "0.2.5", 4 | "description": "Spherical Rotations", 5 | "keywords": [ 6 | "rotation" 7 | ], 8 | "license": "MIT", 9 | "type": "module", 10 | "main": "src/index.js", 11 | "module": "src/index.js", 12 | "unpkg": "dist/attitude.min.js", 13 | "jsdelivr": "dist/attitude.min.js", 14 | "homepage": "https://github.com/Fil/attitude", 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/Fil/attitude.git" 18 | }, 19 | "files": [ 20 | "dist/**/*.js", 21 | "src/**/*.js" 22 | ], 23 | "author": { 24 | "name": "Philippe Rivière", 25 | "url": "https://github.com/Fil" 26 | }, 27 | "scripts": { 28 | "test": "mocha 'test/**/*-test.js' && eslint src test", 29 | "prepublish": "rm -rf dist && yarn test && rollup -c", 30 | "postpublish": "git push && git push --tags && zip -j dist/${npm_package_name}.zip -- LICENSE README.md dist/${npm_package_name}.js dist/${npm_package_name}.min.js" 31 | }, 32 | "dependencies": {}, 33 | "sideEffects": false, 34 | "devDependencies": { 35 | "d3-geo": "3", 36 | "eslint": "8", 37 | "eslint-plugin-es5": "1", 38 | "esm": "3", 39 | "mocha": "9", 40 | "package-preamble": "0.1", 41 | "rollup": "2", 42 | "rollup-plugin-terser": "7", 43 | "terser": "^4.8.1", 44 | "versor": "0.1" 45 | }, 46 | "engines": { 47 | "node": ">=12" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import {terser} from "rollup-plugin-terser"; 2 | import * as meta from "./package.json"; 3 | 4 | const config = { 5 | input: "src/index.js", 6 | external: [], 7 | output: { 8 | file: `dist/${meta.name}.js`, 9 | name: `${meta.name}`, 10 | format: "umd", 11 | indent: false, 12 | extend: true, 13 | banner: `// ${meta.homepage} v${meta.version} Copyright ${(new Date).getFullYear()} ${meta.author.name}`, 14 | globals: Object.assign({}, ...Object.keys(meta.dependencies || {})) 15 | }, 16 | plugins: [] 17 | }; 18 | 19 | export default [ 20 | config, 21 | { 22 | ...config, 23 | output: { 24 | ...config.output, 25 | file: `dist/${meta.name}.min.js` 26 | }, 27 | plugins: [ 28 | ...config.plugins, 29 | terser({ 30 | output: { 31 | preamble: config.output.banner 32 | } 33 | }) 34 | ] 35 | } 36 | ]; 37 | -------------------------------------------------------------------------------- /src/attitude.js: -------------------------------------------------------------------------------- 1 | import { 2 | MatrixRotatePoint, 3 | RotationMatrix_fromAxisAngle, 4 | RotationMatrix_toEulerAngles, 5 | transpose 6 | } from "./matrix.js"; 7 | import { 8 | versor_normalize, 9 | versor_multiply, 10 | versor_fromAxisAngle, 11 | versor_toAxisAngle, 12 | versor_fromEulerAngles, 13 | versor_toEulerAngles 14 | } from "./versor.js"; 15 | import { 16 | vectorEquidistant, 17 | vectorGnomonic, 18 | vectorStereographic 19 | } from "./vector.js"; 20 | import { acos, degrees, radians, sqrt } from "./math.js"; 21 | import { 22 | cartesiand, 23 | sphericald, 24 | dot, cross 25 | } from "./sinpi.js"; 26 | 27 | export default function attitude(init = {}) { 28 | let axis, angle, q, matrix; 29 | 30 | function rotate(point) { 31 | return point === undefined ? rotate : MatrixRotatePoint(matrix, point); 32 | } 33 | 34 | function set_axis_angle(x, a) { 35 | axis = x; 36 | angle = a; 37 | q = versor_fromAxisAngle(axis, angle); 38 | matrix = RotationMatrix_fromAxisAngle(axis, angle); 39 | return rotate; 40 | } 41 | 42 | function set_versor(p) { 43 | const a = versor_toAxisAngle((q = p)); 44 | matrix = RotationMatrix_fromAxisAngle((axis = a.axis), (angle = a.angle)); 45 | return rotate; 46 | } 47 | 48 | function get_vector(f) { 49 | const n = f(angle * radians), 50 | v = cartesiand(axis); 51 | return v.map(d => d * n); 52 | } 53 | function set_vector(v, f_1) { 54 | const n = sqrt(dot(v, v)), 55 | axis = n > 0 56 | ? sphericald(v.map(d => d / n)) 57 | : [0, 0]; 58 | set_axis_angle(axis, f_1(n) * degrees); 59 | return rotate; 60 | } 61 | 62 | rotate.axis = _ => (_ === undefined ? axis : set_axis_angle(_, angle)); 63 | rotate.angle = _ => (_ === undefined ? angle : set_axis_angle(axis, +_)); 64 | rotate.versor = _ => (_ === undefined ? q : set_versor(versor_normalize(_))); 65 | 66 | rotate.vectorGnomonic = _ => 67 | _ === undefined 68 | ? get_vector(vectorGnomonic.forward) 69 | : set_vector(_, vectorGnomonic.inverse); 70 | rotate.vectorStereographic = _ => 71 | _ === undefined 72 | ? get_vector(vectorStereographic.forward) 73 | : set_vector(_, vectorStereographic.inverse); 74 | rotate.vectorEquidistant = _ => 75 | _ === undefined 76 | ? get_vector(vectorEquidistant.forward) 77 | : set_vector(_, vectorEquidistant.inverse); 78 | rotate.vector = rotate.vectorStereographic; 79 | 80 | rotate.matrix = _ => 81 | _ === undefined 82 | ? matrix 83 | : set_versor( 84 | versor_normalize( 85 | versor_fromEulerAngles(RotationMatrix_toEulerAngles(_)) 86 | ) 87 | ); 88 | 89 | rotate.angles = _ => 90 | _ === undefined 91 | ? versor_toEulerAngles(q) 92 | : set_versor(versor_fromEulerAngles(_)); 93 | 94 | rotate.invert = point => MatrixRotatePoint(transpose(matrix), point); 95 | 96 | // returns a new attitude with inverse parameters 97 | rotate.inverse = () => attitude({ axis, angle: -angle }); 98 | 99 | // returns a new product attitude 100 | rotate.compose = _ => attitude().versor(versor_multiply(q, _.versor())); 101 | 102 | // returns a new power attitude 103 | rotate.power = _ => attitude({ axis, angle: angle * +_ }); 104 | 105 | // returns a new attitude that rotates along the arc of great circle (A,B) 106 | rotate.arc = (A, B) => attitude(arc(A, B)); 107 | 108 | // returns an interpolator between two attitudes 109 | rotate.interpolateTo = b => interpolateAttitude(rotate, b); 110 | 111 | // accept d3.geoRotation's init with Euler Angles 112 | if (init.length >= 2) { 113 | rotate.angles(init); 114 | } else { 115 | set_axis_angle( 116 | (axis = init.axis || [0, 90]), 117 | (angle = init.angle === undefined ? 360 : +init.angle) 118 | ); 119 | } 120 | 121 | return rotate; 122 | } 123 | 124 | // arc(A, B) returns an axis-angle that rotates A to B along a great circle (shortest path) 125 | function arc(A, B) { 126 | const a = cartesiand(A), 127 | b = cartesiand(B); 128 | const alpha = acos(dot(a, b)), // angle 129 | w = cross(a, b), // axis direction 130 | n = sqrt(dot(w, w)); // axis norm 131 | return !n 132 | ? { angle: dot(a, b) > 0 ? 0 : 180 } 133 | : { 134 | axis: sphericald([w[0] / n, w[1] / n, w[2] / n]), 135 | angle: alpha * degrees 136 | }; 137 | } 138 | 139 | function interpolateAttitude(a, b) { 140 | const c = b.compose(a.inverse()); 141 | return t => (t === 1 ? b : !t ? a : c.power(t).compose(a)); 142 | } 143 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import m from "./attitude.js"; 2 | export default m; 3 | -------------------------------------------------------------------------------- /src/math.js: -------------------------------------------------------------------------------- 1 | export const abs = Math.abs; 2 | export const atan = Math.atan; 3 | export const atan2 = Math.atan2; 4 | export const cos = Math.cos; 5 | export const floor = Math.floor; 6 | export const hypot = Math.hypot; 7 | export const sign = Math.sign; 8 | export const sin = Math.sin; 9 | export const sqrt = Math.sqrt; 10 | export const tan = Math.tan; 11 | 12 | export const pi = Math.PI; 13 | export const halfPi = pi / 2; 14 | export const quarterPi = pi / 4; 15 | export const tau = pi * 2; 16 | 17 | export const degrees = 180 / pi; 18 | export const radians = 1 / degrees; 19 | 20 | export function acos(x) { 21 | return x > 1 ? 0 : x < -1 ? pi : Math.acos(x); 22 | } 23 | export function asin(x) { 24 | return x > 1 ? halfPi : x < -1 ? -halfPi : Math.asin(x); 25 | } 26 | -------------------------------------------------------------------------------- /src/matrix.js: -------------------------------------------------------------------------------- 1 | import { versor_normalize } from "./versor.js"; 2 | import { asin, atan2, degrees, sqrt } from "./math.js"; 3 | import { cospi, sinpi, cartesiand, sphericald } from "./sinpi.js"; 4 | 5 | function transpose([[r11, r12, r13], [r21, r22, r23], [r31, r32, r33]]) { 6 | return [[r11, r21, r31], [r12, r22, r32], [r13, r23, r33]]; 7 | } 8 | 9 | // eq. (145) 10 | function versor_fromRotationMatrix(r) { 11 | const [a1, a2, a3] = [r[0][0], r[1][1], r[2][2]]; 12 | 13 | // R0 14 | if (a2 >= -a3 && a1 >= -a2 && a1 >= -a3) { 15 | const n = N(a1, a2, a3); 16 | return [ 17 | n / 2, 18 | (r[1][2] - r[2][1]) / n / 2, 19 | (r[2][0] - r[0][2]) / n / 2, 20 | (r[0][1] - r[1][0]) / n / 2 21 | ]; 22 | } 23 | // R1 24 | if (a2 <= -a3 && a1 >= a2 && a1 >= a3) { 25 | const n = N(a1, -a2, -a3); 26 | return [ 27 | (r[1][2] - r[2][1]) / n / 2, 28 | n / 2, 29 | (r[0][1] + r[1][0]) / n / 2, 30 | (r[2][0] + r[0][2]) / n / 2 31 | ]; 32 | } 33 | // R2 34 | if (a2 >= a3 && a1 <= a2 && a1 <= -a3) { 35 | const n = N(-a1, a2, -a3); 36 | return [ 37 | (r[2][0] - r[0][2]) / n / 2, 38 | (r[0][1] + r[1][0]) / n / 2, 39 | n / 2, 40 | (r[1][2] + r[2][1]) / n / 2 41 | ]; 42 | } 43 | // R3 44 | /*if (a2 <= a3 && a1 <= -a2 && a1 <= a3)*/ { 45 | const n = N(-a1, -a2, a3); 46 | return [ 47 | (r[0][1] - r[1][0]) / n / 2, 48 | (r[2][0] + r[0][2]) / n / 2, 49 | (r[1][2] + r[2][1]) / n / 2, 50 | n / 2 51 | ]; 52 | } 53 | 54 | function N(a1, a2, a3) { 55 | return sqrt(1 + a1 + a2 + a3); 56 | } 57 | } 58 | 59 | // eq. (125) 60 | function versor_toRotationMatrix([a, b, c, d]) { 61 | const [q0, q1, q2, q3] = versor_normalize([a, d, -c, b]), 62 | q02 = q0 * q0, 63 | q12 = q1 * q1, 64 | q22 = q2 * q2, 65 | q32 = q3 * q3; 66 | return [ 67 | [ 68 | q02 + q12 - q22 - q32, 69 | 2 * q1 * q2 + 2 * q0 * q3, 70 | 2 * q1 * q3 - 2 * q0 * q2 71 | ], 72 | [ 73 | 2 * q1 * q2 - 2 * q0 * q3, 74 | q02 - q12 + q22 - q32, 75 | 2 * q2 * q3 + 2 * q0 * q1 76 | ], 77 | [ 78 | 2 * q1 * q3 + 2 * q0 * q2, 79 | 2 * q2 * q3 - 2 * q0 * q1, 80 | q02 - q12 - q22 + q32 81 | ] 82 | ]; 83 | } 84 | 85 | // eq. (5) (we use z = R^T(z’)) 86 | function MatrixRotatePoint( 87 | [[r11, r12, r13], [r21, r22, r23], [r31, r32, r33]], 88 | point 89 | ) { 90 | function rotator(point) { 91 | const [x, y, z] = cartesiand(point); 92 | const product = [ 93 | r11 * x + r21 * y + r31 * z, 94 | r12 * x + r22 * y + r32 * z, 95 | r13 * x + r23 * y + r33 * z 96 | ]; 97 | return sphericald(product); 98 | } 99 | return point ? rotator(point) : rotator; 100 | } 101 | 102 | // eq (289) 103 | function RotationMatrix_toEulerAngles([ 104 | [r11 /* r12 */ /* r13 */, ,], 105 | [r21 /* r22 */ /* r23 */, ,], 106 | [r31, r32, r33] 107 | ]) { 108 | const [f, t, p] = [atan2(r32, r33), -asin(r31), atan2(r21, r11)], 109 | [lambda, phi, gamma] = [-p * degrees, t * degrees, -f * degrees]; 110 | 111 | return [lambda, phi, gamma]; 112 | } 113 | 114 | // eq (184) 115 | // changes for precision by fil@rezo.net 116 | function RotationMatrix_fromAxisAngle(axis, angle) { 117 | const [n1, n2, n3] = cartesiand(axis), 118 | [n12, n22, n32] = [n1 * n1, n2 * n2, n3 * n3], 119 | c = cospi(angle / 180), 120 | s2 = (1 - c) / 2, // cos(a/2)^2 121 | c2 = (1 + c) / 2, // sin(a/2)^2 122 | sc = sinpi(angle / 180) / 2; // sin(a/2)cos(a/2) 123 | 124 | return [ 125 | [ 126 | (n12 - n32 - n22) * s2 + c2, 127 | 2 * n1 * n2 * s2 + 2 * n3 * sc, 128 | 2 * n1 * n3 * s2 - 2 * n2 * sc 129 | ], 130 | [ 131 | 2 * n1 * n2 * s2 - 2 * n3 * sc, 132 | (n22 - n32 - n12) * s2 + c2, 133 | 2 * n2 * n3 * s2 + 2 * n1 * sc 134 | ], 135 | [ 136 | 2 * n1 * n3 * s2 + 2 * n2 * sc, 137 | 2 * n2 * n3 * s2 - 2 * n1 * sc, 138 | (n32 - n22 - n12) * s2 + c2 139 | ] 140 | ]; 141 | } 142 | 143 | // eq (287) 144 | // * the angles are given in the order of the rotation axis: top, left, front. 145 | // * we use the transpose matrix - eq (5). 146 | function RotationMatrix_fromEulerAngles([lambda, phi, gamma]) { 147 | const [f, t, p] = [-gamma, phi, -lambda]; 148 | const cf = cospi(f / 180), 149 | sf = sinpi(f / 180), 150 | ct = cospi(t / 180), 151 | st = sinpi(t / 180), 152 | cp = cospi(p / 180), 153 | sp = sinpi(p / 180); 154 | return [ 155 | [ct * cp, sf * st * cp - cf * sp, cf * st * cp + sf * sp], 156 | [ct * sp, sf * st * sp + cf * cp, cf * st * sp - sf * cp], 157 | [-st, ct * sf, ct * cf] 158 | ]; 159 | } 160 | 161 | export { 162 | transpose, 163 | RotationMatrix_fromAxisAngle, 164 | RotationMatrix_fromEulerAngles, 165 | RotationMatrix_toEulerAngles, 166 | MatrixRotatePoint, 167 | versor_toRotationMatrix, 168 | versor_fromRotationMatrix 169 | }; 170 | -------------------------------------------------------------------------------- /src/sinpi.js: -------------------------------------------------------------------------------- 1 | // https://observablehq.com/@fil/sinpi-cospi 2 | import {asin, atan2, abs, cos, degrees, floor, pi, sign, sin, tan} from "./math.js"; 3 | 4 | // adapted from https://github.com/math-io/sinpi 5 | export function sinpi(x) { 6 | if (!isFinite(x)) return NaN; 7 | const r = x % 2, 8 | s = sign(r), 9 | a = abs(r); 10 | return a == 0 || a == 1 11 | ? 0 * s 12 | : a < .25 13 | ? sin(pi * r) 14 | : a < .75 15 | ? cos(pi * (.5 - a)) * s 16 | : a < 1.25 17 | ? sin(pi * (s - r)) 18 | : a < 1.75 19 | ? -s * cos(pi * (a - 1.5)) 20 | : sin(pi * (r - 2 * s)); 21 | } 22 | 23 | 24 | // adapted from https://github.com/math-io/cospi 25 | export function cospi(x) { 26 | if (!isFinite(x)) return NaN; 27 | const a = abs(x), 28 | i = floor(a), 29 | r = a - i; 30 | if (r == .5) return 0; 31 | return ( 32 | (i % 2 == 1 ? -1 : 1) * 33 | (r < .25 ? cos(pi * r) : r < .75 ? sin(pi * (.5 - r)) : -cos(pi * (1 - r))) 34 | ); 35 | } 36 | 37 | export function tanpi(x) { 38 | // tan(a/2 + pi/4) = tan(a)+sec(a) 39 | const a = abs(x), 40 | s = sign(x); 41 | let i = a % 1; 42 | return i > .2 43 | ? ((sinpi(2 * (i -= .25)) + 1) / cospi(2 * i)) * s 44 | : tan(pi * i) * s; 45 | } 46 | 47 | export function cartesiand([l, p]) { 48 | const cp = cospi(p / 180); 49 | return [cp * cospi(l / 180), cp * sinpi(l / 180), sinpi(p / 180)]; 50 | } 51 | 52 | export function sphericald([x, y, z]) { 53 | return [atan2(y, x) * degrees, asin(z) * degrees]; 54 | } 55 | 56 | export function dot(a, b) { 57 | return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; 58 | } 59 | 60 | export function cross(a, b) { 61 | return [ 62 | a[1] * b[2] - a[2] * b[1], 63 | a[2] * b[0] - a[0] * b[2], 64 | a[0] * b[1] - a[1] * b[0] 65 | ]; 66 | } 67 | -------------------------------------------------------------------------------- /src/vector.js: -------------------------------------------------------------------------------- 1 | import { atan, tan } from "./math.js"; 2 | 3 | export const vectorEquidistant = { 4 | forward: a => a, 5 | inverse: a => a 6 | }; 7 | 8 | export const vectorStereographic = { 9 | forward: a => tan(a / 4), 10 | inverse: a => 4 * atan(a) 11 | }; 12 | 13 | export const vectorGnomonic = { 14 | forward: a => tan(a / 2), 15 | inverse: a => 2 * atan(a) 16 | }; 17 | -------------------------------------------------------------------------------- /src/versor.js: -------------------------------------------------------------------------------- 1 | import { 2 | abs, 3 | acos, 4 | asin, 5 | atan2, 6 | degrees, 7 | hypot, 8 | pi, 9 | sqrt 10 | } from "./math.js"; 11 | import { cospi, sinpi, cartesiand, sphericald } from "./sinpi.js"; 12 | 13 | const versor_normalize = q => { 14 | const n = hypot(...q); 15 | return q.map(d => d / n); 16 | }; 17 | 18 | // eq. (198) & (199) 19 | // - axis as (lon, lat) in degrees 20 | // - angle in degrees 21 | // much more precision for small angles! 22 | function versor_toAxisAngle(q) { 23 | const s = sqrt( 24 | abs(q[0]) < 0.5 25 | ? 1 - q[0] * q[0] 26 | : q[1] * q[1] + q[2] * q[2] + q[3] * q[3] 27 | ), 28 | a = 29 | abs(q[0]) < 0.5 30 | ? 2 * acos(q[0]) 31 | : q[0] < 0 32 | ? 2 * pi - 2 * asin(s) 33 | : 2 * asin(s); 34 | if (!s) return { axis: [0, 90], angle: 0 }; 35 | const s1 = 1 / s; 36 | return { 37 | axis: sphericald([q[3] * s1, -q[2] * s1, q[1] * s1]), 38 | angle: a * degrees 39 | }; 40 | } 41 | 42 | // eq. (175) 43 | // - axis as (lon, lat) in degrees 44 | // - angle in degrees 45 | function versor_fromAxisAngle(axis, angle) { 46 | const c = cospi(angle / 360), 47 | s = sinpi(angle / 360), 48 | d = cartesiand(axis); 49 | return [c, d[2] * s, -d[1] * s, d[0] * s]; 50 | } 51 | 52 | // Euler 123 eq (297) 53 | function versor_fromEulerAngles([l, p, g]) { 54 | 55 | // fix south pole 56 | if (p + 90 < 1e-9) p = -90 + 1e-9; 57 | 58 | const sl = sinpi(l / 360), 59 | cl = cospi(l / 360), 60 | sp = sinpi(p / 360), 61 | cp = cospi(p / 360), 62 | sg = sinpi((g||0) / 360), 63 | cg = cospi((g||0) / 360); 64 | return [ 65 | cl * cp * cg + sl * sp * sg, 66 | sl * cp * cg - cl * sp * sg, 67 | cl * sp * cg + sl * cp * sg, 68 | cl * cp * sg - sl * sp * cg 69 | ]; 70 | } 71 | 72 | // eq (290) 73 | function versor_toEulerAngles([q0, q1, q2, q3]) { 74 | const a = 2 * q2 * q3 + 2 * q0 * q1, 75 | b = q3 * q3 - q1 * q1 + q0 * q0 - q2 * q2, 76 | c = 2 * q1 * q3 - 2 * q0 * q2, 77 | d = 2 * q1 * q2 + 2 * q0 * q3, 78 | e = -q3 * q3 - q2 * q2 + q1 * q1 + q0 * q0, 79 | l = atan2(a, b), 80 | g = atan2(d, e); 81 | 82 | // fix north pole 83 | const eps = 1e-9; 84 | if ( 85 | c < 0 && 86 | ((abs(a) < eps && abs(b) < eps) || (abs(d) < eps && abs(e) < eps)) 87 | ) { 88 | const app = versor_toEulerAngles([q0, q2, q1, q3]); 89 | return [app[1] / 2, app[0], -app[1] / 2]; 90 | } 91 | 92 | return [l * degrees, -asin(c) * degrees, g * degrees]; 93 | } 94 | 95 | // https://observablehq.com/@d3/world-tour 96 | function versor_multiply([a1, b1, c1, d1], [a2, b2, c2, d2]) { 97 | return [ 98 | a1 * a2 - b1 * b2 - c1 * c2 - d1 * d2, 99 | a1 * b2 + b1 * a2 + c1 * d2 - d1 * c2, 100 | a1 * c2 - b1 * d2 + c1 * a2 + d1 * b2, 101 | a1 * d2 + b1 * c2 - c1 * b2 + d1 * a2 102 | ]; 103 | } 104 | 105 | export { 106 | versor_normalize, 107 | versor_multiply, 108 | versor_fromEulerAngles, 109 | versor_toEulerAngles, 110 | versor_fromAxisAngle, 111 | versor_toAxisAngle 112 | }; 113 | -------------------------------------------------------------------------------- /test/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint:recommended", 3 | "parserOptions": { 4 | "sourceType": "module", 5 | "ecmaVersion": 8 6 | }, 7 | "env": { 8 | "mocha": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/attitude-test.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | 3 | import * as d3 from "d3-geo"; 4 | import { cos, pi, sin } from "../src/math.js"; 5 | import { 6 | versor_fromEulerAngles, 7 | versor_toEulerAngles, 8 | versor_fromAxisAngle, 9 | versor_toAxisAngle 10 | } from "../src/versor.js"; 11 | import { 12 | MatrixRotatePoint, 13 | RotationMatrix_fromAxisAngle, 14 | RotationMatrix_toEulerAngles, 15 | RotationMatrix_fromEulerAngles 16 | } from "../src/matrix.js"; 17 | 18 | import {default as attitude} from "../src/index.js"; 19 | import {default as versor} from "versor/dist/versor.js"; 20 | 21 | import delta from "./inDelta.js"; 22 | const inDelta = function() { return delta(assert, ...arguments); } 23 | 24 | const J2000 = [ 25 | [-0.054876, -0.873437, -0.483835], 26 | [0.494109, -0.44483, 0.746982], 27 | [-0.867666, -0.198076, 0.455984] 28 | ], 29 | j2000_e = [-96.33732813865191, 60.188536093292406, 23.47976178196561], 30 | j2000_ei = [93.59503429185153, 28.93617294218035, -58.59864545109253]; 31 | 32 | it("attitude.angle", () => { 33 | inDelta(attitude().angle(10)([0, 0]), [10, 0]); 34 | }); 35 | 36 | it("J2000 gives j2000_e", () => { 37 | assert.deepEqual( 38 | attitude() 39 | .matrix(J2000) 40 | .angles() 41 | .map(Math.round), 42 | j2000_e.map(Math.round) 43 | ); 44 | assert.deepEqual( 45 | attitude() 46 | .matrix(J2000) 47 | .inverse() 48 | .angles() 49 | .map(Math.round), 50 | j2000_ei.map(Math.round) 51 | ); 52 | }); 53 | 54 | it("attitude.angle preserves the axis", () => { 55 | assert.deepEqual( 56 | attitude() 57 | .angle(90) 58 | .axis(), 59 | [0, 90] 60 | ); 61 | assert.equal( 62 | attitude() 63 | .angle(90) 64 | .angle(), 65 | 90 66 | ); 67 | assert.deepEqual( 68 | attitude() 69 | .axis([10, 12]) 70 | .angle(0) 71 | .angle(10) 72 | .axis(), 73 | [10, 12] 74 | ); 75 | }); 76 | 77 | it("attitude.angles()", () => { 78 | inDelta( 79 | attitude() 80 | .versor(versor_fromEulerAngles([100, 2, 1])) 81 | .angles(), 82 | [100, 2, 1] 83 | ); 84 | const a = attitude().angle(100); 85 | inDelta(a.angles(), [100, 0, 0]); 86 | }); 87 | 88 | it("power(t)", () => { 89 | const i = attitude().angle(360); 90 | inDelta( 91 | [0, 0.2, 0.4, 0.6, 0.8, 1].map(t => [ 92 | i.power(t).angle(), 93 | i.power(t)([0, 0]) 94 | ]), 95 | [ 96 | [0, [0, 0]], 97 | [72, [72, 0]], 98 | [144, [144, 0]], 99 | [216, [-144, 0]], 100 | [288, [-72, 0]], 101 | [360, [0, 0]] 102 | ] 103 | ); 104 | }); 105 | 106 | it("interpolateAttitude(t)", () => { 107 | const i = attitude() 108 | .angle(0) 109 | .interpolateTo(attitude().angle(90)); 110 | inDelta( 111 | [0, 0.2, 0.4, 0.6, 0.8, 1, 2.1, 4].map(t => i(t)([0, 0])), 112 | [[0, 0], [18, 0], [36, 0], [54, 0], [72, 0], [90, 0], [-171, 0], [0, 0]], 113 | 1e-5 114 | ); 115 | }); 116 | 117 | it("various tests", () => { 118 | inDelta( 119 | attitude() 120 | .angle(100) 121 | .angles(), 122 | [100, 0, 0] 123 | ); 124 | 125 | inDelta( 126 | attitude() 127 | .angle(36) 128 | .power(1 / 10) 129 | .angle(), 130 | 3.6 131 | ); 132 | 133 | inDelta( 134 | attitude() 135 | .angle(36) 136 | .power(10) 137 | .power(1 / 10) 138 | .angle(), 139 | 36 140 | ); 141 | 142 | inDelta( 143 | RotationMatrix_toEulerAngles(RotationMatrix_fromEulerAngles([0, 2, 4])), 144 | [0, 2, 4] 145 | ); 146 | 147 | inDelta(versor([0, 90, 0]), [0.7071067811865476, 0, 0.7071067811865475, 0]); 148 | 149 | inDelta(versor([0, 0, 90]), [0.7071067811865476, 0, 0, 0.7071067811865475]); 150 | 151 | inDelta( 152 | attitude() 153 | .angles([90, 0, 0]) 154 | .versor(), 155 | [0.7071067811865476, 0.7071067811865475, 0, 0] 156 | ); 157 | 158 | inDelta( 159 | attitude() 160 | .angle(10) 161 | .axis([10, 45]) 162 | .matrix(), 163 | [ 164 | [0.9921748253560523, 0.12408681759202372, -0.01384115708930948], 165 | [-0.12148879034592194, 0.9850368041622599, 0.12224143432603561], 166 | [0.02880259970856334, -0.11960332832193964, 0.9924038765061041] 167 | ] 168 | ); 169 | 170 | // doesn't change z 171 | inDelta(RotationMatrix_fromEulerAngles([1, 0, 0])[2][2], 1); 172 | 173 | // doesn't change y 174 | inDelta(RotationMatrix_fromEulerAngles([0, 1, 0])[1][1], 1); 175 | 176 | // doesn't change x 177 | inDelta(RotationMatrix_fromEulerAngles([0, 0, 1])[0][0], 1); 178 | 179 | inDelta( 180 | attitude() 181 | .versor(versor([1, 2, 3])) 182 | .matrix(), 183 | [ 184 | [0.9992386149554827, 0.015602268173062631, 0.0357597484569552], 185 | [-0.017441774902830165, 0.9985093154342034, 0.051719739745651486], 186 | [-0.03489949670250098, -0.052304074592470856, 0.9980211966240685] 187 | ] 188 | ); 189 | 190 | inDelta( 191 | attitude() 192 | .versor( 193 | attitude() 194 | .angle(0) 195 | .compose(attitude().angle(1)) 196 | .versor() 197 | ) 198 | .axis(), 199 | [0, 90] 200 | ); 201 | 202 | inDelta(versor_toEulerAngles(versor([0, 0, 1])), [0, 0, 1]); 203 | 204 | }); 205 | 206 | it("versor from Euler angles", () => { 207 | inDelta(versor_fromEulerAngles([2, 0, 0]), [0.9998477, 0.0174524, 0, 0]); 208 | }); 209 | 210 | it("versor_toAxisAngle", () => { 211 | assert.equal( 212 | versor_toAxisAngle(versor_fromEulerAngles([1e-6, 0, 0])).angle, 213 | 0.000001 214 | ); 215 | }); 216 | 217 | it("Euler angles from RM", () => { 218 | assert.deepEqual(RotationMatrix_toEulerAngles(J2000).map(Math.round), [ 219 | -96, 220 | 60, 221 | 23 222 | ]); 223 | assert.deepEqual( 224 | RotationMatrix_toEulerAngles( 225 | RotationMatrix_fromEulerAngles( 226 | RotationMatrix_toEulerAngles( 227 | RotationMatrix_fromEulerAngles(RotationMatrix_toEulerAngles(J2000)) 228 | ) 229 | ) 230 | ).map(Math.round), 231 | [-96, 60, 23] 232 | ); 233 | }); 234 | 235 | it("versor from axis,angle", () => { 236 | inDelta(versor_fromAxisAngle([0, 90], 90), versor([90, 0, 0])); 237 | inDelta(versor_fromAxisAngle([0, 0], 90), versor([0, 0, 90])); 238 | inDelta(versor_fromAxisAngle([-90, 0], 90), versor([0, 90, 0])); 239 | inDelta(versor_fromAxisAngle([0, 90], 10), versor([10, 0, 0])); 240 | inDelta( 241 | attitude() 242 | .axis([0, 90]) 243 | .angle(10)([0, 0]), 244 | [10, 0] 245 | ); 246 | inDelta( 247 | attitude() 248 | .versor(versor_fromAxisAngle([0, 90], 10))([0, 0]), 249 | [10, 0] 250 | ); 251 | }); 252 | 253 | it( 254 | "RotationMatrix_toEulerAngles inverses RotationMatrix_fromEulerAngles", 255 | () => { 256 | assert.deepEqual( 257 | RotationMatrix_toEulerAngles( 258 | RotationMatrix_fromEulerAngles([1, 2, 3]) 259 | ).map(Math.round), 260 | [1, 2, 3] 261 | ); 262 | } 263 | ); 264 | 265 | it("same versors as Mike's versor", () => { 266 | inDelta( 267 | versor([90, 0, 0]), 268 | attitude() 269 | .angles([90, 0, 0]) 270 | .versor() 271 | ); 272 | inDelta( 273 | versor([0, 90, 0]), 274 | attitude() 275 | .angles([0, 90, 0]) 276 | .versor() 277 | ); 278 | inDelta( 279 | versor([0, 0, 90]), 280 | attitude() 281 | .angles([0, 0, 90]) 282 | .versor() 283 | ); 284 | }); 285 | 286 | it( 287 | "RotationMatrix_toEulerAngles inverses RotationMatrix_fromEulerAngles", 288 | () => { 289 | assert.deepEqual( 290 | RotationMatrix_toEulerAngles( 291 | RotationMatrix_fromEulerAngles([1, 2, 3]) 292 | ).map(Math.round), 293 | [1, 2, 3] 294 | ); 295 | } 296 | ); 297 | 298 | it( 299 | "RotationMatrix_toEulerAngles inverses RotationMatrix_fromEulerAngles", 300 | () => { 301 | assert.deepEqual( 302 | RotationMatrix_toEulerAngles( 303 | RotationMatrix_fromEulerAngles([1, 2, 3]) 304 | ).map(Math.round), 305 | [1, 2, 3] 306 | ); 307 | } 308 | ); 309 | 310 | it("versor.angles inverses versor_fromAngles", () => { 311 | assert.deepEqual(versor.rotation(versor([1, 2, 3])).map(Math.round), [1, 2, 3]); 312 | assert.deepEqual( 313 | attitude() 314 | .angles([1, 2, 3]) 315 | .angles() 316 | .map(Math.round), 317 | [1, 2, 3] 318 | ); 319 | assert.deepEqual( 320 | attitude() 321 | .versor( 322 | attitude() 323 | .angles([1, 2, 3]) 324 | .versor() 325 | ) 326 | .angles() 327 | .map(Math.round), 328 | [1, 2, 3] 329 | ); 330 | assert.deepEqual( 331 | versor 332 | .rotation( 333 | attitude() 334 | .matrix(J2000) 335 | .versor() 336 | ) 337 | .map(Math.round), 338 | attitude() 339 | .matrix(J2000) 340 | .angles() 341 | .map(Math.round) 342 | ); 343 | }); 344 | 345 | it("test rotations", () => { 346 | inDelta( 347 | attitude() 348 | .axis([0, 90]) 349 | .angle(10)([2, -8]), 350 | [12, -8] 351 | ); 352 | inDelta(attitude().angles([10, 0, 0])([2, -8]), [12, -8]); 353 | 354 | assert.equal(attitude().angle(), 360); 355 | 356 | inDelta( 357 | attitude() 358 | .angle(1) 359 | .angles(), 360 | [1, 0, 0] 361 | ); 362 | 363 | }); 364 | 365 | it("matrix rotate point", () => { 366 | const a = Math.PI / 2; 367 | 368 | // axis 1 is front — eq. (14) 369 | const m1 = [[1, 0, 0], [0, cos(a), sin(a)], [0, -sin(a), cos(a)]]; 370 | assert.deepEqual(MatrixRotatePoint(m1, [0, 0]), [0, 0]); 371 | assert.deepEqual(MatrixRotatePoint(m1, [0, 90]).map(Math.round), [-90, 0]); 372 | assert.deepEqual(MatrixRotatePoint(m1, [90, 10]).map(Math.round), [-90, 80]); 373 | // axis 2 is left — eq. (15) 374 | const m2 = [[cos(a), 0, -sin(a)], [0, 1, 0], [sin(a), 0, cos(a)]]; 375 | assert.deepEqual(MatrixRotatePoint(m2, [0, 0]), [0, -90]); 376 | assert.deepEqual(MatrixRotatePoint(m2, [0, 90]).map(Math.round), [0, 0]); 377 | assert.deepEqual(MatrixRotatePoint(m2, [90, 10]).map(Math.round)[0], 80); 378 | 379 | // axis 3 is top — eq. (16) 380 | const m3 = [[cos(a), sin(a), 0], [-sin(a), cos(a), 0], [0, 0, 1]]; 381 | assert.deepEqual(MatrixRotatePoint(m3, [0, 0]), [90, 0]); 382 | assert.deepEqual(MatrixRotatePoint(m3, [0, 90]).map(Math.round)[1], 90); 383 | assert.deepEqual(MatrixRotatePoint(m3, [90, 10]).map(Math.round), [180, 10]); 384 | 385 | }); 386 | 387 | it("axis rotations", () => { 388 | inDelta(attitude().angle(45)([0, 1]), [45, 1], 0.1); 389 | inDelta( 390 | attitude() 391 | .axis([0, 0]) 392 | .angle(45)([91, 0]), 393 | [91, 45], 394 | 0.5 395 | ); 396 | inDelta( 397 | attitude() 398 | .axis([-90, 0]) 399 | .angle(45)([1, 0]), 400 | [1, 45], 401 | 0.5 402 | ); 403 | 404 | }); 405 | 406 | it("rotation matrix from axis-angle", () => { 407 | inDelta( 408 | RotationMatrix_fromAxisAngle([0, 90], 90), 409 | RotationMatrix_fromEulerAngles([90, 0, 0]) 410 | ); 411 | inDelta( 412 | RotationMatrix_fromAxisAngle([0, 0], 20), 413 | RotationMatrix_fromEulerAngles([0, 0, 20]) 414 | ); 415 | inDelta( 416 | RotationMatrix_fromAxisAngle([-90, 0], 20), 417 | RotationMatrix_fromEulerAngles([0, 20, 0]) 418 | ); 419 | }); 420 | 421 | it("attitude <~> geoRotation", () => { 422 | inDelta(attitude([1, 2, 3])([0, 0]), d3.geoRotation([1, 2, 3])([0, 0])); 423 | inDelta( 424 | attitude([1, 2, 3]).invert([0, 0]), 425 | d3.geoRotation([1, 2, 3]).invert([0, 0]) 426 | ); 427 | }); 428 | 429 | it("arc", () => { 430 | inDelta(attitude().arc([1, 2], [3, 4])([1, 2]), [3, 4]); 431 | }); 432 | 433 | it("vector", () => { 434 | const A = attitude() 435 | .axis([10, 20]) 436 | .angle(180); 437 | // default is stereographic: 180° gives a norm=1 vector 438 | inDelta(A.vector(), [0.9254165783983233, 0.1631759111665348, 0.34202014332566866]); 439 | 440 | // gnomonic: 90° gives a norm=1 vector 441 | inDelta(attitude().angle(90).vectorGnomonic(), [0, 0, 1]); 442 | 443 | // equidistant: 90° gives a norm = pi/2 vector 444 | inDelta(attitude().angle(90).vectorEquidistant(), [0, 0, pi/2]); 445 | 446 | inDelta( 447 | attitude() 448 | .vector(A.vector()) 449 | .axis(), 450 | [10, 20] 451 | ); 452 | inDelta( 453 | attitude() 454 | .vectorEquidistant(A.vectorEquidistant()) 455 | .angle(), 456 | 180 457 | ); 458 | inDelta( 459 | attitude() 460 | .vectorGnomonic(A.vectorGnomonic()) 461 | .axis(), 462 | [10, 20] 463 | ); 464 | inDelta( 465 | attitude() 466 | .vectorStereographic(A.vectorStereographic()) 467 | .axis(), 468 | [10, 20] 469 | ); 470 | }); 471 | 472 | it("vector zero", () => { 473 | const A = attitude().vector([0,0,0]); 474 | inDelta(A.vector(), [0,0,0]); 475 | inDelta(A.angles(), [0,0,0]); 476 | }); 477 | 478 | it("exact sin cos", () => { 479 | assert.deepEqual(attitude({ angle: 90 }).matrix(), [ 480 | [0, 1, 0], 481 | [-1, 0, 0], 482 | [0, 0, 1] 483 | ]); 484 | }); 485 | 486 | 487 | it("precision of versor to Euler angles", () => { 488 | for (let i = 1; i <= 10; i++){ 489 | const a = 28 + i / 10000, b = attitude([a, 90, -a]).angles(); 490 | inDelta(b, [a, 90, -a]); 491 | } 492 | for (let i = 1; i <= 10; i++){ 493 | const a = 28 + i / 10000, b = attitude([-a, -90, a]).angles(); 494 | inDelta(b, [-a, -90, a], 1e-3); 495 | } 496 | }); 497 | 498 | it("precision of Euler angles to versor", () => { 499 | for (let i = 1; i <= 10; i++){ 500 | const a = 28 + i / 10000, b = attitude([a, 90, -a]).angles(); 501 | inDelta(b, [a, 90, -a]) 502 | } 503 | for (let i = 1; i <= 10; i++){ 504 | const a = 28 + i / 10000, b = attitude([-a, -90, a]).angles(); 505 | inDelta(b, [-a, -90, a], 1e-3) 506 | } 507 | }); 508 | -------------------------------------------------------------------------------- /test/inDelta.js: -------------------------------------------------------------------------------- 1 | export default function(assert, actual, expected, delta) { 2 | delta = delta || 1e-6; 3 | assert(inDelta(actual, expected, delta), { 4 | message: "should be in delta " + delta, 5 | operator: "inDelta", 6 | actual, 7 | expected 8 | }); 9 | } 10 | 11 | function inDelta(actual, expected, delta) { 12 | return (Array.isArray(expected) ? inDeltaArray : inDeltaNumber)(actual, expected, delta); 13 | } 14 | 15 | function inDeltaArray(actual, expected, delta) { 16 | var n = expected.length, i = -1; 17 | if (actual.length !== n) return false; 18 | while (++i < n) if (!inDelta(actual[i], expected[i], delta)) return false; 19 | return true; 20 | } 21 | 22 | function inDeltaNumber(actual, expected, delta) { 23 | return actual >= expected - delta && actual <= expected + delta; 24 | } 25 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@aashutoshrathi/word-wrap@^1.2.3": 6 | version "1.2.6" 7 | resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" 8 | integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== 9 | 10 | "@babel/code-frame@^7.10.4": 11 | version "7.22.5" 12 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.5.tgz#234d98e1551960604f1246e6475891a570ad5658" 13 | integrity sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ== 14 | dependencies: 15 | "@babel/highlight" "^7.22.5" 16 | 17 | "@babel/helper-validator-identifier@^7.22.5": 18 | version "7.22.5" 19 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" 20 | integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== 21 | 22 | "@babel/highlight@^7.22.5": 23 | version "7.22.5" 24 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031" 25 | integrity sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw== 26 | dependencies: 27 | "@babel/helper-validator-identifier" "^7.22.5" 28 | chalk "^2.0.0" 29 | js-tokens "^4.0.0" 30 | 31 | "@eslint-community/eslint-utils@^4.2.0": 32 | version "4.4.0" 33 | resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" 34 | integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== 35 | dependencies: 36 | eslint-visitor-keys "^3.3.0" 37 | 38 | "@eslint-community/regexpp@^4.4.0": 39 | version "4.5.1" 40 | resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.1.tgz#cdd35dce4fa1a89a4fd42b1599eb35b3af408884" 41 | integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== 42 | 43 | "@eslint/eslintrc@^2.1.0": 44 | version "2.1.0" 45 | resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.0.tgz#82256f164cc9e0b59669efc19d57f8092706841d" 46 | integrity sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A== 47 | dependencies: 48 | ajv "^6.12.4" 49 | debug "^4.3.2" 50 | espree "^9.6.0" 51 | globals "^13.19.0" 52 | ignore "^5.2.0" 53 | import-fresh "^3.2.1" 54 | js-yaml "^4.1.0" 55 | minimatch "^3.1.2" 56 | strip-json-comments "^3.1.1" 57 | 58 | "@eslint/js@8.44.0": 59 | version "8.44.0" 60 | resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.44.0.tgz#961a5903c74139390478bdc808bcde3fc45ab7af" 61 | integrity sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw== 62 | 63 | "@humanwhocodes/config-array@^0.11.10": 64 | version "0.11.10" 65 | resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" 66 | integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== 67 | dependencies: 68 | "@humanwhocodes/object-schema" "^1.2.1" 69 | debug "^4.1.1" 70 | minimatch "^3.0.5" 71 | 72 | "@humanwhocodes/module-importer@^1.0.1": 73 | version "1.0.1" 74 | resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" 75 | integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== 76 | 77 | "@humanwhocodes/object-schema@^1.2.1": 78 | version "1.2.1" 79 | resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" 80 | integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== 81 | 82 | "@jridgewell/gen-mapping@^0.3.0": 83 | version "0.3.3" 84 | resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" 85 | integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== 86 | dependencies: 87 | "@jridgewell/set-array" "^1.0.1" 88 | "@jridgewell/sourcemap-codec" "^1.4.10" 89 | "@jridgewell/trace-mapping" "^0.3.9" 90 | 91 | "@jridgewell/resolve-uri@3.1.0": 92 | version "3.1.0" 93 | resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" 94 | integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== 95 | 96 | "@jridgewell/set-array@^1.0.1": 97 | version "1.1.2" 98 | resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" 99 | integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== 100 | 101 | "@jridgewell/source-map@^0.3.3": 102 | version "0.3.5" 103 | resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91" 104 | integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ== 105 | dependencies: 106 | "@jridgewell/gen-mapping" "^0.3.0" 107 | "@jridgewell/trace-mapping" "^0.3.9" 108 | 109 | "@jridgewell/sourcemap-codec@1.4.14": 110 | version "1.4.14" 111 | resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" 112 | integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== 113 | 114 | "@jridgewell/sourcemap-codec@^1.4.10": 115 | version "1.4.15" 116 | resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" 117 | integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== 118 | 119 | "@jridgewell/trace-mapping@^0.3.9": 120 | version "0.3.18" 121 | resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" 122 | integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== 123 | dependencies: 124 | "@jridgewell/resolve-uri" "3.1.0" 125 | "@jridgewell/sourcemap-codec" "1.4.14" 126 | 127 | "@nodelib/fs.scandir@2.1.5": 128 | version "2.1.5" 129 | resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" 130 | integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== 131 | dependencies: 132 | "@nodelib/fs.stat" "2.0.5" 133 | run-parallel "^1.1.9" 134 | 135 | "@nodelib/fs.stat@2.0.5": 136 | version "2.0.5" 137 | resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" 138 | integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== 139 | 140 | "@nodelib/fs.walk@^1.2.8": 141 | version "1.2.8" 142 | resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" 143 | integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== 144 | dependencies: 145 | "@nodelib/fs.scandir" "2.1.5" 146 | fastq "^1.6.0" 147 | 148 | "@types/node@*": 149 | version "20.4.2" 150 | resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.2.tgz#129cc9ae69f93824f92fac653eebfb4812ab4af9" 151 | integrity sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw== 152 | 153 | "@ungap/promise-all-settled@1.1.2": 154 | version "1.1.2" 155 | resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" 156 | integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== 157 | 158 | acorn-jsx@^5.3.2: 159 | version "5.3.2" 160 | resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" 161 | integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== 162 | 163 | acorn@^8.8.2, acorn@^8.9.0: 164 | version "8.10.0" 165 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" 166 | integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== 167 | 168 | ajv@^6.10.0, ajv@^6.12.4: 169 | version "6.12.6" 170 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" 171 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== 172 | dependencies: 173 | fast-deep-equal "^3.1.1" 174 | fast-json-stable-stringify "^2.0.0" 175 | json-schema-traverse "^0.4.1" 176 | uri-js "^4.2.2" 177 | 178 | ansi-colors@4.1.1: 179 | version "4.1.1" 180 | resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" 181 | integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== 182 | 183 | ansi-regex@^5.0.1: 184 | version "5.0.1" 185 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 186 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 187 | 188 | ansi-styles@^3.2.1: 189 | version "3.2.1" 190 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 191 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 192 | dependencies: 193 | color-convert "^1.9.0" 194 | 195 | ansi-styles@^4.0.0, ansi-styles@^4.1.0: 196 | version "4.3.0" 197 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 198 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 199 | dependencies: 200 | color-convert "^2.0.1" 201 | 202 | anymatch@~3.1.2: 203 | version "3.1.3" 204 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" 205 | integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== 206 | dependencies: 207 | normalize-path "^3.0.0" 208 | picomatch "^2.0.4" 209 | 210 | argparse@^2.0.1: 211 | version "2.0.1" 212 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" 213 | integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== 214 | 215 | balanced-match@^1.0.0: 216 | version "1.0.2" 217 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 218 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 219 | 220 | binary-extensions@^2.0.0: 221 | version "2.2.0" 222 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" 223 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 224 | 225 | brace-expansion@^1.1.7: 226 | version "1.1.11" 227 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 228 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 229 | dependencies: 230 | balanced-match "^1.0.0" 231 | concat-map "0.0.1" 232 | 233 | braces@~3.0.2: 234 | version "3.0.2" 235 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 236 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 237 | dependencies: 238 | fill-range "^7.0.1" 239 | 240 | browser-stdout@1.3.1: 241 | version "1.3.1" 242 | resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" 243 | integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== 244 | 245 | buffer-from@^1.0.0: 246 | version "1.1.2" 247 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" 248 | integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== 249 | 250 | callsites@^3.0.0: 251 | version "3.1.0" 252 | resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" 253 | integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== 254 | 255 | camelcase@^6.0.0: 256 | version "6.3.0" 257 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" 258 | integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== 259 | 260 | chalk@^2.0.0: 261 | version "2.4.2" 262 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 263 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 264 | dependencies: 265 | ansi-styles "^3.2.1" 266 | escape-string-regexp "^1.0.5" 267 | supports-color "^5.3.0" 268 | 269 | chalk@^4.0.0, chalk@^4.1.0: 270 | version "4.1.2" 271 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" 272 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 273 | dependencies: 274 | ansi-styles "^4.1.0" 275 | supports-color "^7.1.0" 276 | 277 | chokidar@3.5.3: 278 | version "3.5.3" 279 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" 280 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== 281 | dependencies: 282 | anymatch "~3.1.2" 283 | braces "~3.0.2" 284 | glob-parent "~5.1.2" 285 | is-binary-path "~2.1.0" 286 | is-glob "~4.0.1" 287 | normalize-path "~3.0.0" 288 | readdirp "~3.6.0" 289 | optionalDependencies: 290 | fsevents "~2.3.2" 291 | 292 | cliui@^7.0.2: 293 | version "7.0.4" 294 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" 295 | integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== 296 | dependencies: 297 | string-width "^4.2.0" 298 | strip-ansi "^6.0.0" 299 | wrap-ansi "^7.0.0" 300 | 301 | color-convert@^1.9.0: 302 | version "1.9.3" 303 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 304 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 305 | dependencies: 306 | color-name "1.1.3" 307 | 308 | color-convert@^2.0.1: 309 | version "2.0.1" 310 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 311 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 312 | dependencies: 313 | color-name "~1.1.4" 314 | 315 | color-name@1.1.3: 316 | version "1.1.3" 317 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 318 | integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== 319 | 320 | color-name@~1.1.4: 321 | version "1.1.4" 322 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 323 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 324 | 325 | commander@^2.20.0: 326 | version "2.20.3" 327 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" 328 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== 329 | 330 | concat-map@0.0.1: 331 | version "0.0.1" 332 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 333 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== 334 | 335 | cross-spawn@^7.0.2: 336 | version "7.0.3" 337 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" 338 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 339 | dependencies: 340 | path-key "^3.1.0" 341 | shebang-command "^2.0.0" 342 | which "^2.0.1" 343 | 344 | "d3-array@2.5.0 - 3": 345 | version "3.2.4" 346 | resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.4.tgz#15fec33b237f97ac5d7c986dc77da273a8ed0bb5" 347 | integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== 348 | dependencies: 349 | internmap "1 - 2" 350 | 351 | d3-geo@3: 352 | version "3.1.0" 353 | resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-3.1.0.tgz#74fd54e1f4cebd5185ac2039217a98d39b0a4c0e" 354 | integrity sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA== 355 | dependencies: 356 | d3-array "2.5.0 - 3" 357 | 358 | debug@4.3.3: 359 | version "4.3.3" 360 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" 361 | integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== 362 | dependencies: 363 | ms "2.1.2" 364 | 365 | debug@^4.1.1, debug@^4.3.2: 366 | version "4.3.4" 367 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" 368 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== 369 | dependencies: 370 | ms "2.1.2" 371 | 372 | decamelize@^4.0.0: 373 | version "4.0.0" 374 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" 375 | integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== 376 | 377 | deep-is@^0.1.3: 378 | version "0.1.4" 379 | resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" 380 | integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== 381 | 382 | diff@5.0.0: 383 | version "5.0.0" 384 | resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" 385 | integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== 386 | 387 | doctrine@^3.0.0: 388 | version "3.0.0" 389 | resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" 390 | integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== 391 | dependencies: 392 | esutils "^2.0.2" 393 | 394 | emoji-regex@^8.0.0: 395 | version "8.0.0" 396 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 397 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 398 | 399 | escalade@^3.1.1: 400 | version "3.1.1" 401 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" 402 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== 403 | 404 | escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: 405 | version "4.0.0" 406 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" 407 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 408 | 409 | escape-string-regexp@^1.0.5: 410 | version "1.0.5" 411 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 412 | integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== 413 | 414 | eslint-plugin-es5@1: 415 | version "1.5.0" 416 | resolved "https://registry.yarnpkg.com/eslint-plugin-es5/-/eslint-plugin-es5-1.5.0.tgz#aab19af3d4798f7924bba309bc4f87087280fbba" 417 | integrity sha512-Qxmfo7v2B7SGAEURJo0dpBweFf+JU15kSyALfiB2rXWcBuJ96r6X9kFHXFnhdopPHCaHjoQs1xQPUJVbGMb1AA== 418 | 419 | eslint-scope@^7.2.0: 420 | version "7.2.1" 421 | resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.1.tgz#936821d3462675f25a18ac5fd88a67cc15b393bd" 422 | integrity sha512-CvefSOsDdaYYvxChovdrPo/ZGt8d5lrJWleAc1diXRKhHGiTYEI26cvo8Kle/wGnsizoCJjK73FMg1/IkIwiNA== 423 | dependencies: 424 | esrecurse "^4.3.0" 425 | estraverse "^5.2.0" 426 | 427 | eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: 428 | version "3.4.1" 429 | resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz#c22c48f48942d08ca824cc526211ae400478a994" 430 | integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== 431 | 432 | eslint@8: 433 | version "8.45.0" 434 | resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.45.0.tgz#bab660f90d18e1364352c0a6b7c6db8edb458b78" 435 | integrity sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw== 436 | dependencies: 437 | "@eslint-community/eslint-utils" "^4.2.0" 438 | "@eslint-community/regexpp" "^4.4.0" 439 | "@eslint/eslintrc" "^2.1.0" 440 | "@eslint/js" "8.44.0" 441 | "@humanwhocodes/config-array" "^0.11.10" 442 | "@humanwhocodes/module-importer" "^1.0.1" 443 | "@nodelib/fs.walk" "^1.2.8" 444 | ajv "^6.10.0" 445 | chalk "^4.0.0" 446 | cross-spawn "^7.0.2" 447 | debug "^4.3.2" 448 | doctrine "^3.0.0" 449 | escape-string-regexp "^4.0.0" 450 | eslint-scope "^7.2.0" 451 | eslint-visitor-keys "^3.4.1" 452 | espree "^9.6.0" 453 | esquery "^1.4.2" 454 | esutils "^2.0.2" 455 | fast-deep-equal "^3.1.3" 456 | file-entry-cache "^6.0.1" 457 | find-up "^5.0.0" 458 | glob-parent "^6.0.2" 459 | globals "^13.19.0" 460 | graphemer "^1.4.0" 461 | ignore "^5.2.0" 462 | imurmurhash "^0.1.4" 463 | is-glob "^4.0.0" 464 | is-path-inside "^3.0.3" 465 | js-yaml "^4.1.0" 466 | json-stable-stringify-without-jsonify "^1.0.1" 467 | levn "^0.4.1" 468 | lodash.merge "^4.6.2" 469 | minimatch "^3.1.2" 470 | natural-compare "^1.4.0" 471 | optionator "^0.9.3" 472 | strip-ansi "^6.0.1" 473 | text-table "^0.2.0" 474 | 475 | esm@3: 476 | version "3.2.25" 477 | resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" 478 | integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== 479 | 480 | espree@^9.6.0: 481 | version "9.6.1" 482 | resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" 483 | integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== 484 | dependencies: 485 | acorn "^8.9.0" 486 | acorn-jsx "^5.3.2" 487 | eslint-visitor-keys "^3.4.1" 488 | 489 | esquery@^1.4.2: 490 | version "1.5.0" 491 | resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" 492 | integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== 493 | dependencies: 494 | estraverse "^5.1.0" 495 | 496 | esrecurse@^4.3.0: 497 | version "4.3.0" 498 | resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" 499 | integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== 500 | dependencies: 501 | estraverse "^5.2.0" 502 | 503 | estraverse@^5.1.0, estraverse@^5.2.0: 504 | version "5.3.0" 505 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" 506 | integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== 507 | 508 | esutils@^2.0.2: 509 | version "2.0.3" 510 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" 511 | integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== 512 | 513 | fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: 514 | version "3.1.3" 515 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" 516 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 517 | 518 | fast-json-stable-stringify@^2.0.0: 519 | version "2.1.0" 520 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" 521 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== 522 | 523 | fast-levenshtein@^2.0.6: 524 | version "2.0.6" 525 | resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" 526 | integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== 527 | 528 | fastq@^1.6.0: 529 | version "1.15.0" 530 | resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" 531 | integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== 532 | dependencies: 533 | reusify "^1.0.4" 534 | 535 | file-entry-cache@^6.0.1: 536 | version "6.0.1" 537 | resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" 538 | integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== 539 | dependencies: 540 | flat-cache "^3.0.4" 541 | 542 | fill-range@^7.0.1: 543 | version "7.0.1" 544 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 545 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 546 | dependencies: 547 | to-regex-range "^5.0.1" 548 | 549 | find-up@5.0.0, find-up@^5.0.0: 550 | version "5.0.0" 551 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" 552 | integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== 553 | dependencies: 554 | locate-path "^6.0.0" 555 | path-exists "^4.0.0" 556 | 557 | flat-cache@^3.0.4: 558 | version "3.0.4" 559 | resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" 560 | integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== 561 | dependencies: 562 | flatted "^3.1.0" 563 | rimraf "^3.0.2" 564 | 565 | flat@^5.0.2: 566 | version "5.0.2" 567 | resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" 568 | integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== 569 | 570 | flatted@^3.1.0: 571 | version "3.2.7" 572 | resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" 573 | integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== 574 | 575 | fs.realpath@^1.0.0: 576 | version "1.0.0" 577 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 578 | integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== 579 | 580 | fsevents@~2.3.2: 581 | version "2.3.2" 582 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" 583 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== 584 | 585 | get-caller-file@^2.0.5: 586 | version "2.0.5" 587 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 588 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 589 | 590 | glob-parent@^6.0.2: 591 | version "6.0.2" 592 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" 593 | integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== 594 | dependencies: 595 | is-glob "^4.0.3" 596 | 597 | glob-parent@~5.1.2: 598 | version "5.1.2" 599 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 600 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 601 | dependencies: 602 | is-glob "^4.0.1" 603 | 604 | glob@7.2.0: 605 | version "7.2.0" 606 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" 607 | integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== 608 | dependencies: 609 | fs.realpath "^1.0.0" 610 | inflight "^1.0.4" 611 | inherits "2" 612 | minimatch "^3.0.4" 613 | once "^1.3.0" 614 | path-is-absolute "^1.0.0" 615 | 616 | glob@^7.1.3: 617 | version "7.2.3" 618 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" 619 | integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== 620 | dependencies: 621 | fs.realpath "^1.0.0" 622 | inflight "^1.0.4" 623 | inherits "2" 624 | minimatch "^3.1.1" 625 | once "^1.3.0" 626 | path-is-absolute "^1.0.0" 627 | 628 | globals@^13.19.0: 629 | version "13.20.0" 630 | resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" 631 | integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== 632 | dependencies: 633 | type-fest "^0.20.2" 634 | 635 | graphemer@^1.4.0: 636 | version "1.4.0" 637 | resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" 638 | integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== 639 | 640 | growl@1.10.5: 641 | version "1.10.5" 642 | resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" 643 | integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== 644 | 645 | has-flag@^3.0.0: 646 | version "3.0.0" 647 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 648 | integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== 649 | 650 | has-flag@^4.0.0: 651 | version "4.0.0" 652 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 653 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 654 | 655 | he@1.2.0: 656 | version "1.2.0" 657 | resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" 658 | integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== 659 | 660 | ignore@^5.2.0: 661 | version "5.2.4" 662 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" 663 | integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== 664 | 665 | import-fresh@^3.2.1: 666 | version "3.3.0" 667 | resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" 668 | integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== 669 | dependencies: 670 | parent-module "^1.0.0" 671 | resolve-from "^4.0.0" 672 | 673 | imurmurhash@^0.1.4: 674 | version "0.1.4" 675 | resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" 676 | integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== 677 | 678 | inflight@^1.0.4: 679 | version "1.0.6" 680 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 681 | integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== 682 | dependencies: 683 | once "^1.3.0" 684 | wrappy "1" 685 | 686 | inherits@2: 687 | version "2.0.4" 688 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 689 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 690 | 691 | "internmap@1 - 2": 692 | version "2.0.3" 693 | resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009" 694 | integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== 695 | 696 | is-binary-path@~2.1.0: 697 | version "2.1.0" 698 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 699 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 700 | dependencies: 701 | binary-extensions "^2.0.0" 702 | 703 | is-extglob@^2.1.1: 704 | version "2.1.1" 705 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 706 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== 707 | 708 | is-fullwidth-code-point@^3.0.0: 709 | version "3.0.0" 710 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 711 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 712 | 713 | is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: 714 | version "4.0.3" 715 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 716 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 717 | dependencies: 718 | is-extglob "^2.1.1" 719 | 720 | is-number@^7.0.0: 721 | version "7.0.0" 722 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 723 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 724 | 725 | is-path-inside@^3.0.3: 726 | version "3.0.3" 727 | resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" 728 | integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== 729 | 730 | is-plain-obj@^2.1.0: 731 | version "2.1.0" 732 | resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" 733 | integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== 734 | 735 | is-unicode-supported@^0.1.0: 736 | version "0.1.0" 737 | resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" 738 | integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== 739 | 740 | isexe@^2.0.0: 741 | version "2.0.0" 742 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 743 | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== 744 | 745 | jest-worker@^26.2.1: 746 | version "26.6.2" 747 | resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" 748 | integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== 749 | dependencies: 750 | "@types/node" "*" 751 | merge-stream "^2.0.0" 752 | supports-color "^7.0.0" 753 | 754 | js-tokens@^4.0.0: 755 | version "4.0.0" 756 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 757 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 758 | 759 | js-yaml@4.1.0, js-yaml@^4.1.0: 760 | version "4.1.0" 761 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" 762 | integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== 763 | dependencies: 764 | argparse "^2.0.1" 765 | 766 | json-schema-traverse@^0.4.1: 767 | version "0.4.1" 768 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" 769 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== 770 | 771 | json-stable-stringify-without-jsonify@^1.0.1: 772 | version "1.0.1" 773 | resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" 774 | integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== 775 | 776 | levn@^0.4.1: 777 | version "0.4.1" 778 | resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" 779 | integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== 780 | dependencies: 781 | prelude-ls "^1.2.1" 782 | type-check "~0.4.0" 783 | 784 | locate-path@^6.0.0: 785 | version "6.0.0" 786 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" 787 | integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== 788 | dependencies: 789 | p-locate "^5.0.0" 790 | 791 | lodash.merge@^4.6.2: 792 | version "4.6.2" 793 | resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" 794 | integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== 795 | 796 | log-symbols@4.1.0: 797 | version "4.1.0" 798 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" 799 | integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== 800 | dependencies: 801 | chalk "^4.1.0" 802 | is-unicode-supported "^0.1.0" 803 | 804 | merge-stream@^2.0.0: 805 | version "2.0.0" 806 | resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" 807 | integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== 808 | 809 | minimatch@4.2.1: 810 | version "4.2.1" 811 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.1.tgz#40d9d511a46bdc4e563c22c3080cde9c0d8299b4" 812 | integrity sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g== 813 | dependencies: 814 | brace-expansion "^1.1.7" 815 | 816 | minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: 817 | version "3.1.2" 818 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 819 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 820 | dependencies: 821 | brace-expansion "^1.1.7" 822 | 823 | mocha@9: 824 | version "9.2.2" 825 | resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.2.tgz#d70db46bdb93ca57402c809333e5a84977a88fb9" 826 | integrity sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g== 827 | dependencies: 828 | "@ungap/promise-all-settled" "1.1.2" 829 | ansi-colors "4.1.1" 830 | browser-stdout "1.3.1" 831 | chokidar "3.5.3" 832 | debug "4.3.3" 833 | diff "5.0.0" 834 | escape-string-regexp "4.0.0" 835 | find-up "5.0.0" 836 | glob "7.2.0" 837 | growl "1.10.5" 838 | he "1.2.0" 839 | js-yaml "4.1.0" 840 | log-symbols "4.1.0" 841 | minimatch "4.2.1" 842 | ms "2.1.3" 843 | nanoid "3.3.1" 844 | serialize-javascript "6.0.0" 845 | strip-json-comments "3.1.1" 846 | supports-color "8.1.1" 847 | which "2.0.2" 848 | workerpool "6.2.0" 849 | yargs "16.2.0" 850 | yargs-parser "20.2.4" 851 | yargs-unparser "2.0.0" 852 | 853 | ms@2.1.2: 854 | version "2.1.2" 855 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 856 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 857 | 858 | ms@2.1.3: 859 | version "2.1.3" 860 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" 861 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 862 | 863 | nanoid@3.3.1: 864 | version "3.3.1" 865 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" 866 | integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== 867 | 868 | natural-compare@^1.4.0: 869 | version "1.4.0" 870 | resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" 871 | integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== 872 | 873 | normalize-path@^3.0.0, normalize-path@~3.0.0: 874 | version "3.0.0" 875 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 876 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 877 | 878 | once@^1.3.0: 879 | version "1.4.0" 880 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 881 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== 882 | dependencies: 883 | wrappy "1" 884 | 885 | optionator@^0.9.3: 886 | version "0.9.3" 887 | resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" 888 | integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== 889 | dependencies: 890 | "@aashutoshrathi/word-wrap" "^1.2.3" 891 | deep-is "^0.1.3" 892 | fast-levenshtein "^2.0.6" 893 | levn "^0.4.1" 894 | prelude-ls "^1.2.1" 895 | type-check "^0.4.0" 896 | 897 | p-limit@^3.0.2: 898 | version "3.1.0" 899 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" 900 | integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== 901 | dependencies: 902 | yocto-queue "^0.1.0" 903 | 904 | p-locate@^5.0.0: 905 | version "5.0.0" 906 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" 907 | integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== 908 | dependencies: 909 | p-limit "^3.0.2" 910 | 911 | package-preamble@0.1: 912 | version "0.1.0" 913 | resolved "https://registry.yarnpkg.com/package-preamble/-/package-preamble-0.1.0.tgz#c4397381b70353448e4255ea9a49a5e5b418ca68" 914 | integrity sha512-K9cr2xQAkPlq9fmKv1fzD1MXRTp2n5BLD/6Zj+QgIWiBYNl0wvasOavABoMXBtNmWBPVB4aKb8MqLL2FU18Nmg== 915 | 916 | parent-module@^1.0.0: 917 | version "1.0.1" 918 | resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" 919 | integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== 920 | dependencies: 921 | callsites "^3.0.0" 922 | 923 | path-exists@^4.0.0: 924 | version "4.0.0" 925 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" 926 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== 927 | 928 | path-is-absolute@^1.0.0: 929 | version "1.0.1" 930 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 931 | integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== 932 | 933 | path-key@^3.1.0: 934 | version "3.1.1" 935 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 936 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 937 | 938 | picomatch@^2.0.4, picomatch@^2.2.1: 939 | version "2.3.1" 940 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" 941 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 942 | 943 | prelude-ls@^1.2.1: 944 | version "1.2.1" 945 | resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" 946 | integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== 947 | 948 | punycode@^2.1.0: 949 | version "2.3.0" 950 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" 951 | integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== 952 | 953 | queue-microtask@^1.2.2: 954 | version "1.2.3" 955 | resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" 956 | integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== 957 | 958 | randombytes@^2.1.0: 959 | version "2.1.0" 960 | resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" 961 | integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== 962 | dependencies: 963 | safe-buffer "^5.1.0" 964 | 965 | readdirp@~3.6.0: 966 | version "3.6.0" 967 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" 968 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 969 | dependencies: 970 | picomatch "^2.2.1" 971 | 972 | require-directory@^2.1.1: 973 | version "2.1.1" 974 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 975 | integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== 976 | 977 | resolve-from@^4.0.0: 978 | version "4.0.0" 979 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" 980 | integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== 981 | 982 | reusify@^1.0.4: 983 | version "1.0.4" 984 | resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" 985 | integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== 986 | 987 | rimraf@^3.0.2: 988 | version "3.0.2" 989 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" 990 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== 991 | dependencies: 992 | glob "^7.1.3" 993 | 994 | rollup-plugin-terser@7: 995 | version "7.0.2" 996 | resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d" 997 | integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ== 998 | dependencies: 999 | "@babel/code-frame" "^7.10.4" 1000 | jest-worker "^26.2.1" 1001 | serialize-javascript "^4.0.0" 1002 | terser "^5.0.0" 1003 | 1004 | rollup@2: 1005 | version "2.79.1" 1006 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7" 1007 | integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw== 1008 | optionalDependencies: 1009 | fsevents "~2.3.2" 1010 | 1011 | run-parallel@^1.1.9: 1012 | version "1.2.0" 1013 | resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" 1014 | integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== 1015 | dependencies: 1016 | queue-microtask "^1.2.2" 1017 | 1018 | safe-buffer@^5.1.0: 1019 | version "5.2.1" 1020 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 1021 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 1022 | 1023 | serialize-javascript@6.0.0: 1024 | version "6.0.0" 1025 | resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" 1026 | integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== 1027 | dependencies: 1028 | randombytes "^2.1.0" 1029 | 1030 | serialize-javascript@^4.0.0: 1031 | version "4.0.0" 1032 | resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" 1033 | integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== 1034 | dependencies: 1035 | randombytes "^2.1.0" 1036 | 1037 | shebang-command@^2.0.0: 1038 | version "2.0.0" 1039 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 1040 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 1041 | dependencies: 1042 | shebang-regex "^3.0.0" 1043 | 1044 | shebang-regex@^3.0.0: 1045 | version "3.0.0" 1046 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 1047 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 1048 | 1049 | source-map-support@~0.5.12, source-map-support@~0.5.20: 1050 | version "0.5.21" 1051 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" 1052 | integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== 1053 | dependencies: 1054 | buffer-from "^1.0.0" 1055 | source-map "^0.6.0" 1056 | 1057 | source-map@^0.6.0, source-map@~0.6.1: 1058 | version "0.6.1" 1059 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 1060 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 1061 | 1062 | string-width@^4.1.0, string-width@^4.2.0: 1063 | version "4.2.3" 1064 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 1065 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 1066 | dependencies: 1067 | emoji-regex "^8.0.0" 1068 | is-fullwidth-code-point "^3.0.0" 1069 | strip-ansi "^6.0.1" 1070 | 1071 | strip-ansi@^6.0.0, strip-ansi@^6.0.1: 1072 | version "6.0.1" 1073 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 1074 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1075 | dependencies: 1076 | ansi-regex "^5.0.1" 1077 | 1078 | strip-json-comments@3.1.1, strip-json-comments@^3.1.1: 1079 | version "3.1.1" 1080 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" 1081 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== 1082 | 1083 | supports-color@8.1.1: 1084 | version "8.1.1" 1085 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" 1086 | integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== 1087 | dependencies: 1088 | has-flag "^4.0.0" 1089 | 1090 | supports-color@^5.3.0: 1091 | version "5.5.0" 1092 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 1093 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 1094 | dependencies: 1095 | has-flag "^3.0.0" 1096 | 1097 | supports-color@^7.0.0, supports-color@^7.1.0: 1098 | version "7.2.0" 1099 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 1100 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 1101 | dependencies: 1102 | has-flag "^4.0.0" 1103 | 1104 | terser@^4.8.1: 1105 | version "4.8.1" 1106 | resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.1.tgz#a00e5634562de2239fd404c649051bf6fc21144f" 1107 | integrity sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw== 1108 | dependencies: 1109 | commander "^2.20.0" 1110 | source-map "~0.6.1" 1111 | source-map-support "~0.5.12" 1112 | 1113 | terser@^5.0.0: 1114 | version "5.19.1" 1115 | resolved "https://registry.yarnpkg.com/terser/-/terser-5.19.1.tgz#dbd7231f224a9e2401d0f0959542ed74d76d340b" 1116 | integrity sha512-27hxBUVdV6GoNg1pKQ7Z5cbR6V9txPVyBA+FQw3BaZ1Wuzvztce5p156DaP0NVZNrMZZ+6iG9Syf7WgMNKDg2Q== 1117 | dependencies: 1118 | "@jridgewell/source-map" "^0.3.3" 1119 | acorn "^8.8.2" 1120 | commander "^2.20.0" 1121 | source-map-support "~0.5.20" 1122 | 1123 | text-table@^0.2.0: 1124 | version "0.2.0" 1125 | resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" 1126 | integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== 1127 | 1128 | to-regex-range@^5.0.1: 1129 | version "5.0.1" 1130 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 1131 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 1132 | dependencies: 1133 | is-number "^7.0.0" 1134 | 1135 | type-check@^0.4.0, type-check@~0.4.0: 1136 | version "0.4.0" 1137 | resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" 1138 | integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== 1139 | dependencies: 1140 | prelude-ls "^1.2.1" 1141 | 1142 | type-fest@^0.20.2: 1143 | version "0.20.2" 1144 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" 1145 | integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== 1146 | 1147 | uri-js@^4.2.2: 1148 | version "4.4.1" 1149 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" 1150 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== 1151 | dependencies: 1152 | punycode "^2.1.0" 1153 | 1154 | versor@0.1: 1155 | version "0.1.2" 1156 | resolved "https://registry.yarnpkg.com/versor/-/versor-0.1.2.tgz#0b145a22cd6376f222dace214ab1fd3b6369a8d9" 1157 | integrity sha512-/XNJOGXeis3j7OOOkdTp3LXzWDTxo/33wvYNtXLLbNOZ5lkTgESzTMPeThU6albr14UupCottC6KTXjcGDO0Lg== 1158 | 1159 | which@2.0.2, which@^2.0.1: 1160 | version "2.0.2" 1161 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 1162 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 1163 | dependencies: 1164 | isexe "^2.0.0" 1165 | 1166 | workerpool@6.2.0: 1167 | version "6.2.0" 1168 | resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" 1169 | integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== 1170 | 1171 | wrap-ansi@^7.0.0: 1172 | version "7.0.0" 1173 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 1174 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 1175 | dependencies: 1176 | ansi-styles "^4.0.0" 1177 | string-width "^4.1.0" 1178 | strip-ansi "^6.0.0" 1179 | 1180 | wrappy@1: 1181 | version "1.0.2" 1182 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1183 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== 1184 | 1185 | y18n@^5.0.5: 1186 | version "5.0.8" 1187 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" 1188 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== 1189 | 1190 | yargs-parser@20.2.4: 1191 | version "20.2.4" 1192 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" 1193 | integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== 1194 | 1195 | yargs-parser@^20.2.2: 1196 | version "20.2.9" 1197 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" 1198 | integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== 1199 | 1200 | yargs-unparser@2.0.0: 1201 | version "2.0.0" 1202 | resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" 1203 | integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== 1204 | dependencies: 1205 | camelcase "^6.0.0" 1206 | decamelize "^4.0.0" 1207 | flat "^5.0.2" 1208 | is-plain-obj "^2.1.0" 1209 | 1210 | yargs@16.2.0: 1211 | version "16.2.0" 1212 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" 1213 | integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== 1214 | dependencies: 1215 | cliui "^7.0.2" 1216 | escalade "^3.1.1" 1217 | get-caller-file "^2.0.5" 1218 | require-directory "^2.1.1" 1219 | string-width "^4.2.0" 1220 | y18n "^5.0.5" 1221 | yargs-parser "^20.2.2" 1222 | 1223 | yocto-queue@^0.1.0: 1224 | version "0.1.0" 1225 | resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" 1226 | integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== 1227 | --------------------------------------------------------------------------------