├── .eslintrc.yml ├── .gitignore ├── LICENSE ├── README.md ├── examples ├── bounce.js ├── clock.js ├── randstripe.js ├── sierpinski.js └── spiral.js ├── package-lock.json ├── package.json ├── turtle.css ├── turtle.html └── turtle.js /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | env: 2 | browser: true 3 | es6: true # retro-compatibility 4 | 5 | extends: eslint:recommended 6 | 7 | # eslint refuses to work if this is uncommented 8 | # it seems the formatting is wrong 9 | #overrides: 10 | #- files: 11 | # - /examples/ 12 | # rules: 13 | # no-undef: off 14 | 15 | rules: # `warn`` instead of `error`, for easier transition 16 | indent: 17 | - warn 18 | - 3 # average between 2 and 4 19 | - SwitchCase: 1 20 | linebreak-style: 21 | - warn 22 | - unix # reason: less bytes 23 | quotes: 24 | - warn 25 | - single # reason: it seems these are used more frequently in *.js files 26 | semi: 27 | - warn 28 | - always 29 | no-self-compare: error 30 | no-constant-binary-expression: error 31 | no-unreachable-loop: error 32 | no-unused-vars: 33 | - warn 34 | - vars: local 35 | no-unused-private-class-members: warn 36 | no-shadow: 37 | - warn 38 | - builtinGlobals: true 39 | no-constructor-return: warn -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2020 Bernard Pope 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Thanks to HTML5's [`Canvas`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) element, we were able to create an implementation of [Turtle Graphics](https://en.wikipedia.org/wiki/Turtle_graphics) programming in pure JavaScript. 2 | Now with improved UI including the ability to move forward and backward in the interactive command box, Turtle programming in JavaScript is easy enough for beginners and modifiable by advanced users thanks to its open-source nature. 3 | You can access this live by [clicking here](http://htmlpreview.github.io/?https://github.com/bjpop/js-turtle/blob/master/turtle.html) 4 | -------------------------------------------------------------------------------- /examples/bounce.js: -------------------------------------------------------------------------------- 1 | // rectangles which bounce off the side of the canvas 2 | 3 | const init_drops = length => Array.from({ length }, () => ({ 4 | x: random(-150, 150), 5 | y: random(-150, 150), 6 | 7 | velocityX: random(-6, 6), 8 | velocityY: random(-6, 6), 9 | 10 | size: random(20, 300), 11 | width: random(1, 40), 12 | 13 | r: random(0, 255), 14 | g: random(0, 255), 15 | b: random(0, 255), 16 | a: Math.random() 17 | })); 18 | 19 | function rain(drops) { 20 | clear(); 21 | for (const d of drops) { 22 | colour(d.r,d.g,d.b,d.a); 23 | width(d.width); 24 | goto(d.x,d.y); 25 | if (d.y < -150 || d.y + d.size > 150 && d.velocityY > 0) 26 | d.velocityY *= -1; 27 | if (d.x - d.width/2 < -150 || d.x + d.width/2 > 150) 28 | d.velocityX *= -1; 29 | forward(d.size); 30 | d.y += d.velocityY; 31 | d.x += d.velocityX; 32 | } 33 | } 34 | 35 | function demo(n) { 36 | wrap(false); 37 | hideTurtle(); 38 | animate(() => rain(init_drops(n)), 100); 39 | } 40 | -------------------------------------------------------------------------------- /examples/clock.js: -------------------------------------------------------------------------------- 1 | // draw the tick marks around the edge of the clock 2 | function ticks(radius) { 3 | const tickLen = 7; 4 | const gap = radius - tickLen; 5 | colour(0,0,255,0.5); 6 | width(1); 7 | for (let theta = 0; theta < 360; theta += 6) { 8 | // skip the mark where the numbers are drawn 9 | if (theta % 30 == 0) continue; 10 | penup(); 11 | goto(0,0); 12 | angle(theta); 13 | forward(gap); 14 | pendown(); 15 | forward(tickLen); 16 | } 17 | } 18 | 19 | function circle(x, y, w, radius, sides) { 20 | const theta = 360/sides; 21 | const sideLen = 2 * radius * Math.sin(degToRad(theta/2)); 22 | penup(); 23 | goto(x,y); 24 | forward(radius); 25 | left(90); 26 | forward(sideLen/2); 27 | right(180); 28 | pendown(); 29 | colour(0, 255, 0, 0.5); 30 | width(w); 31 | while (sides-- > 0) { 32 | forward(sideLen); 33 | right(theta); 34 | } 35 | } 36 | 37 | // draw the hour numbers on the clock face 38 | function numbers(x, y, radius) { 39 | penup(); 40 | setFont('20px sans-serif'); 41 | for (const hour of range(1, 13)) { 42 | goto(x,y); 43 | angle(hour * 30); 44 | forward(radius); 45 | write(hour); 46 | } 47 | pendown(); 48 | } 49 | 50 | // draw one of the clock hands 51 | function hand (theta, w, length, col) { 52 | const stepSize = 5; 53 | const widthDelta = w / (length / stepSize); 54 | goto(0, 0); 55 | angle(theta); 56 | colour(col.r, col.g, col.b, col.a); 57 | for (let step = 0; step < length; step += stepSize) { 58 | width(w); 59 | forward(stepSize); 60 | w -= widthDelta; 61 | } 62 | } 63 | 64 | // draw all of the hands 65 | function hands(hours, minutes, seconds) { 66 | // draw seconds hand 67 | hand(seconds * 6, 6, 100, {r: 255, g: 0, b: 0, a: 0.5 }); 68 | // draw minutes hand 69 | const 70 | minutesInSeconds = minutes * 60, 71 | minutesAndSeconds = minutesInSeconds + seconds; 72 | hand(minutesAndSeconds * 0.1, 10, 100, {r: 0, g: 255, b: 0, a: 0.5 }); 73 | // draw hours hand 74 | const 75 | hoursInSeconds = hours % 12 * 3600, 76 | hoursAndMinutesAndSeconds = hoursInSeconds + minutesAndSeconds; 77 | hand(hoursAndMinutesAndSeconds * 360 / 43200, 10, 60, {r: 0, g: 0, b: 255, a: 0.5 }); 78 | } 79 | 80 | // refresh the entire clock 81 | function clock() { 82 | clear(); 83 | numbers(0, 0, 115); 84 | circle(0, 0, 2, 130, 50); 85 | ticks(130); 86 | const d = new Date(); 87 | hands(d.getHours(), d.getMinutes(), d.getSeconds()); 88 | } 89 | 90 | function demo() { 91 | hideTurtle(); 92 | // refresh the clock every second 93 | animate(clock,1000); 94 | } 95 | -------------------------------------------------------------------------------- /examples/randstripe.js: -------------------------------------------------------------------------------- 1 | // draw some randomly placed coloured stripes 2 | 3 | function fun(count) { 4 | while (count-- > 0) { 5 | goto(random(-150, 150), random(-150, 150)); 6 | colour( 7 | random(0,255), 8 | random(0,255), 9 | random(0,255), 10 | Math.random() 11 | ); 12 | angle(random(0,180)); 13 | width(random(1,10)); 14 | forward(random(10, 30)); 15 | } 16 | } 17 | 18 | function demo(count) { 19 | hideTurtle(); 20 | redrawOnMove(false); 21 | fun(count); 22 | redrawOnMove(true); 23 | draw(); 24 | } 25 | -------------------------------------------------------------------------------- /examples/sierpinski.js: -------------------------------------------------------------------------------- 1 | // https://en.wikipedia.org/wiki/Sierpi%C5%84ski_curve 2 | 3 | function part(size, level) { 4 | level--; 5 | halfSierpinski(size, level); 6 | left(45); 7 | forward(size * Math.SQRT2); 8 | left(45); 9 | halfSierpinski(size, level); 10 | } 11 | 12 | /** helper for `sierpinski` */ 13 | function halfSierpinski(size, level) { 14 | if (level <= 0) { 15 | forward(size); 16 | return; 17 | } 18 | part(size, level); 19 | right(90); 20 | forward(size); 21 | right(90); 22 | part(size, level); 23 | } 24 | 25 | /** draw a Sierpinski Curve of arbitrary recursive depth */ 26 | function sierpinski(size, level) { 27 | for (const _ of range(0, 2)) { 28 | halfSierpinski(size, level); 29 | right(90); 30 | forward(size); 31 | right(90); 32 | } 33 | } 34 | 35 | function demo() { 36 | hideTurtle(); 37 | redrawOnMove(false); 38 | goto(0,-120); 39 | sierpinski(2,5); 40 | redrawOnMove(true); 41 | draw(); 42 | } 43 | -------------------------------------------------------------------------------- /examples/spiral.js: -------------------------------------------------------------------------------- 1 | // randomly spaced spirals 2 | 3 | function spiral(steps, angle) { 4 | const widthInc = 5 / steps; 5 | let w = 0.1; 6 | while (steps-- > 0) { 7 | width(w); 8 | forward(random(1,10)); 9 | right(angle--); 10 | w += widthInc; 11 | } 12 | } 13 | 14 | function fun(count) { 15 | while (count-- > 0) { 16 | colour( 17 | random(0,255), 18 | random(0,255), 19 | random(0,255), 20 | Math.random() 21 | ); 22 | goto(random(-150, 150), random(-150, 150)); 23 | angle(random(0,360)); 24 | spiral(random(100, 1000), random(5, 90)); 25 | } 26 | } 27 | 28 | function demo(count) { 29 | hideTurtle(); 30 | redrawOnMove(false); 31 | fun(count); 32 | redrawOnMove(true); 33 | draw(); 34 | } 35 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "js-turtle", 3 | "version": "0.1.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "js-turtle", 9 | "version": "0.1.0", 10 | "license": "BSD-3-Clause", 11 | "devDependencies": { 12 | "eslint": "^8.27.0" 13 | } 14 | }, 15 | "node_modules/@eslint/eslintrc": { 16 | "version": "1.3.3", 17 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", 18 | "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", 19 | "dev": true, 20 | "dependencies": { 21 | "ajv": "^6.12.4", 22 | "debug": "^4.3.2", 23 | "espree": "^9.4.0", 24 | "globals": "^13.15.0", 25 | "ignore": "^5.2.0", 26 | "import-fresh": "^3.2.1", 27 | "js-yaml": "^4.1.0", 28 | "minimatch": "^3.1.2", 29 | "strip-json-comments": "^3.1.1" 30 | }, 31 | "engines": { 32 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 33 | }, 34 | "funding": { 35 | "url": "https://opencollective.com/eslint" 36 | } 37 | }, 38 | "node_modules/@humanwhocodes/config-array": { 39 | "version": "0.11.7", 40 | "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", 41 | "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", 42 | "dev": true, 43 | "dependencies": { 44 | "@humanwhocodes/object-schema": "^1.2.1", 45 | "debug": "^4.1.1", 46 | "minimatch": "^3.0.5" 47 | }, 48 | "engines": { 49 | "node": ">=10.10.0" 50 | } 51 | }, 52 | "node_modules/@humanwhocodes/module-importer": { 53 | "version": "1.0.1", 54 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", 55 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", 56 | "dev": true, 57 | "engines": { 58 | "node": ">=12.22" 59 | }, 60 | "funding": { 61 | "type": "github", 62 | "url": "https://github.com/sponsors/nzakas" 63 | } 64 | }, 65 | "node_modules/@humanwhocodes/object-schema": { 66 | "version": "1.2.1", 67 | "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", 68 | "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", 69 | "dev": true 70 | }, 71 | "node_modules/@nodelib/fs.scandir": { 72 | "version": "2.1.5", 73 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 74 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 75 | "dev": true, 76 | "dependencies": { 77 | "@nodelib/fs.stat": "2.0.5", 78 | "run-parallel": "^1.1.9" 79 | }, 80 | "engines": { 81 | "node": ">= 8" 82 | } 83 | }, 84 | "node_modules/@nodelib/fs.stat": { 85 | "version": "2.0.5", 86 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 87 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 88 | "dev": true, 89 | "engines": { 90 | "node": ">= 8" 91 | } 92 | }, 93 | "node_modules/@nodelib/fs.walk": { 94 | "version": "1.2.8", 95 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 96 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 97 | "dev": true, 98 | "dependencies": { 99 | "@nodelib/fs.scandir": "2.1.5", 100 | "fastq": "^1.6.0" 101 | }, 102 | "engines": { 103 | "node": ">= 8" 104 | } 105 | }, 106 | "node_modules/acorn": { 107 | "version": "8.8.1", 108 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", 109 | "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", 110 | "dev": true, 111 | "bin": { 112 | "acorn": "bin/acorn" 113 | }, 114 | "engines": { 115 | "node": ">=0.4.0" 116 | } 117 | }, 118 | "node_modules/acorn-jsx": { 119 | "version": "5.3.2", 120 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 121 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 122 | "dev": true, 123 | "peerDependencies": { 124 | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" 125 | } 126 | }, 127 | "node_modules/ajv": { 128 | "version": "6.12.6", 129 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 130 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 131 | "dev": true, 132 | "dependencies": { 133 | "fast-deep-equal": "^3.1.1", 134 | "fast-json-stable-stringify": "^2.0.0", 135 | "json-schema-traverse": "^0.4.1", 136 | "uri-js": "^4.2.2" 137 | }, 138 | "funding": { 139 | "type": "github", 140 | "url": "https://github.com/sponsors/epoberezkin" 141 | } 142 | }, 143 | "node_modules/ansi-regex": { 144 | "version": "5.0.1", 145 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 146 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 147 | "dev": true, 148 | "engines": { 149 | "node": ">=8" 150 | } 151 | }, 152 | "node_modules/ansi-styles": { 153 | "version": "4.3.0", 154 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 155 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 156 | "dev": true, 157 | "dependencies": { 158 | "color-convert": "^2.0.1" 159 | }, 160 | "engines": { 161 | "node": ">=8" 162 | }, 163 | "funding": { 164 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 165 | } 166 | }, 167 | "node_modules/argparse": { 168 | "version": "2.0.1", 169 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 170 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 171 | "dev": true 172 | }, 173 | "node_modules/balanced-match": { 174 | "version": "1.0.2", 175 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 176 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 177 | "dev": true 178 | }, 179 | "node_modules/brace-expansion": { 180 | "version": "1.1.11", 181 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 182 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 183 | "dev": true, 184 | "dependencies": { 185 | "balanced-match": "^1.0.0", 186 | "concat-map": "0.0.1" 187 | } 188 | }, 189 | "node_modules/callsites": { 190 | "version": "3.1.0", 191 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 192 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 193 | "dev": true, 194 | "engines": { 195 | "node": ">=6" 196 | } 197 | }, 198 | "node_modules/chalk": { 199 | "version": "4.1.2", 200 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 201 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 202 | "dev": true, 203 | "dependencies": { 204 | "ansi-styles": "^4.1.0", 205 | "supports-color": "^7.1.0" 206 | }, 207 | "engines": { 208 | "node": ">=10" 209 | }, 210 | "funding": { 211 | "url": "https://github.com/chalk/chalk?sponsor=1" 212 | } 213 | }, 214 | "node_modules/color-convert": { 215 | "version": "2.0.1", 216 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 217 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 218 | "dev": true, 219 | "dependencies": { 220 | "color-name": "~1.1.4" 221 | }, 222 | "engines": { 223 | "node": ">=7.0.0" 224 | } 225 | }, 226 | "node_modules/color-name": { 227 | "version": "1.1.4", 228 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 229 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 230 | "dev": true 231 | }, 232 | "node_modules/concat-map": { 233 | "version": "0.0.1", 234 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 235 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 236 | "dev": true 237 | }, 238 | "node_modules/cross-spawn": { 239 | "version": "7.0.3", 240 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 241 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 242 | "dev": true, 243 | "dependencies": { 244 | "path-key": "^3.1.0", 245 | "shebang-command": "^2.0.0", 246 | "which": "^2.0.1" 247 | }, 248 | "engines": { 249 | "node": ">= 8" 250 | } 251 | }, 252 | "node_modules/debug": { 253 | "version": "4.3.4", 254 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 255 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 256 | "dev": true, 257 | "dependencies": { 258 | "ms": "2.1.2" 259 | }, 260 | "engines": { 261 | "node": ">=6.0" 262 | }, 263 | "peerDependenciesMeta": { 264 | "supports-color": { 265 | "optional": true 266 | } 267 | } 268 | }, 269 | "node_modules/deep-is": { 270 | "version": "0.1.4", 271 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 272 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 273 | "dev": true 274 | }, 275 | "node_modules/doctrine": { 276 | "version": "3.0.0", 277 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 278 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 279 | "dev": true, 280 | "dependencies": { 281 | "esutils": "^2.0.2" 282 | }, 283 | "engines": { 284 | "node": ">=6.0.0" 285 | } 286 | }, 287 | "node_modules/escape-string-regexp": { 288 | "version": "4.0.0", 289 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 290 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 291 | "dev": true, 292 | "engines": { 293 | "node": ">=10" 294 | }, 295 | "funding": { 296 | "url": "https://github.com/sponsors/sindresorhus" 297 | } 298 | }, 299 | "node_modules/eslint": { 300 | "version": "8.27.0", 301 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.27.0.tgz", 302 | "integrity": "sha512-0y1bfG2ho7mty+SiILVf9PfuRA49ek4Nc60Wmmu62QlobNR+CeXa4xXIJgcuwSQgZiWaPH+5BDsctpIW0PR/wQ==", 303 | "dev": true, 304 | "dependencies": { 305 | "@eslint/eslintrc": "^1.3.3", 306 | "@humanwhocodes/config-array": "^0.11.6", 307 | "@humanwhocodes/module-importer": "^1.0.1", 308 | "@nodelib/fs.walk": "^1.2.8", 309 | "ajv": "^6.10.0", 310 | "chalk": "^4.0.0", 311 | "cross-spawn": "^7.0.2", 312 | "debug": "^4.3.2", 313 | "doctrine": "^3.0.0", 314 | "escape-string-regexp": "^4.0.0", 315 | "eslint-scope": "^7.1.1", 316 | "eslint-utils": "^3.0.0", 317 | "eslint-visitor-keys": "^3.3.0", 318 | "espree": "^9.4.0", 319 | "esquery": "^1.4.0", 320 | "esutils": "^2.0.2", 321 | "fast-deep-equal": "^3.1.3", 322 | "file-entry-cache": "^6.0.1", 323 | "find-up": "^5.0.0", 324 | "glob-parent": "^6.0.2", 325 | "globals": "^13.15.0", 326 | "grapheme-splitter": "^1.0.4", 327 | "ignore": "^5.2.0", 328 | "import-fresh": "^3.0.0", 329 | "imurmurhash": "^0.1.4", 330 | "is-glob": "^4.0.0", 331 | "is-path-inside": "^3.0.3", 332 | "js-sdsl": "^4.1.4", 333 | "js-yaml": "^4.1.0", 334 | "json-stable-stringify-without-jsonify": "^1.0.1", 335 | "levn": "^0.4.1", 336 | "lodash.merge": "^4.6.2", 337 | "minimatch": "^3.1.2", 338 | "natural-compare": "^1.4.0", 339 | "optionator": "^0.9.1", 340 | "regexpp": "^3.2.0", 341 | "strip-ansi": "^6.0.1", 342 | "strip-json-comments": "^3.1.0", 343 | "text-table": "^0.2.0" 344 | }, 345 | "bin": { 346 | "eslint": "bin/eslint.js" 347 | }, 348 | "engines": { 349 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 350 | }, 351 | "funding": { 352 | "url": "https://opencollective.com/eslint" 353 | } 354 | }, 355 | "node_modules/eslint-scope": { 356 | "version": "7.1.1", 357 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", 358 | "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", 359 | "dev": true, 360 | "dependencies": { 361 | "esrecurse": "^4.3.0", 362 | "estraverse": "^5.2.0" 363 | }, 364 | "engines": { 365 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 366 | } 367 | }, 368 | "node_modules/eslint-utils": { 369 | "version": "3.0.0", 370 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", 371 | "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", 372 | "dev": true, 373 | "dependencies": { 374 | "eslint-visitor-keys": "^2.0.0" 375 | }, 376 | "engines": { 377 | "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" 378 | }, 379 | "funding": { 380 | "url": "https://github.com/sponsors/mysticatea" 381 | }, 382 | "peerDependencies": { 383 | "eslint": ">=5" 384 | } 385 | }, 386 | "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { 387 | "version": "2.1.0", 388 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", 389 | "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", 390 | "dev": true, 391 | "engines": { 392 | "node": ">=10" 393 | } 394 | }, 395 | "node_modules/eslint-visitor-keys": { 396 | "version": "3.3.0", 397 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", 398 | "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", 399 | "dev": true, 400 | "engines": { 401 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 402 | } 403 | }, 404 | "node_modules/espree": { 405 | "version": "9.4.1", 406 | "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", 407 | "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", 408 | "dev": true, 409 | "dependencies": { 410 | "acorn": "^8.8.0", 411 | "acorn-jsx": "^5.3.2", 412 | "eslint-visitor-keys": "^3.3.0" 413 | }, 414 | "engines": { 415 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 416 | }, 417 | "funding": { 418 | "url": "https://opencollective.com/eslint" 419 | } 420 | }, 421 | "node_modules/esquery": { 422 | "version": "1.4.0", 423 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", 424 | "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", 425 | "dev": true, 426 | "dependencies": { 427 | "estraverse": "^5.1.0" 428 | }, 429 | "engines": { 430 | "node": ">=0.10" 431 | } 432 | }, 433 | "node_modules/esrecurse": { 434 | "version": "4.3.0", 435 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 436 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 437 | "dev": true, 438 | "dependencies": { 439 | "estraverse": "^5.2.0" 440 | }, 441 | "engines": { 442 | "node": ">=4.0" 443 | } 444 | }, 445 | "node_modules/estraverse": { 446 | "version": "5.3.0", 447 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 448 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 449 | "dev": true, 450 | "engines": { 451 | "node": ">=4.0" 452 | } 453 | }, 454 | "node_modules/esutils": { 455 | "version": "2.0.3", 456 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 457 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 458 | "dev": true, 459 | "engines": { 460 | "node": ">=0.10.0" 461 | } 462 | }, 463 | "node_modules/fast-deep-equal": { 464 | "version": "3.1.3", 465 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 466 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 467 | "dev": true 468 | }, 469 | "node_modules/fast-json-stable-stringify": { 470 | "version": "2.1.0", 471 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 472 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 473 | "dev": true 474 | }, 475 | "node_modules/fast-levenshtein": { 476 | "version": "2.0.6", 477 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 478 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", 479 | "dev": true 480 | }, 481 | "node_modules/fastq": { 482 | "version": "1.13.0", 483 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", 484 | "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", 485 | "dev": true, 486 | "dependencies": { 487 | "reusify": "^1.0.4" 488 | } 489 | }, 490 | "node_modules/file-entry-cache": { 491 | "version": "6.0.1", 492 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", 493 | "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", 494 | "dev": true, 495 | "dependencies": { 496 | "flat-cache": "^3.0.4" 497 | }, 498 | "engines": { 499 | "node": "^10.12.0 || >=12.0.0" 500 | } 501 | }, 502 | "node_modules/find-up": { 503 | "version": "5.0.0", 504 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 505 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 506 | "dev": true, 507 | "dependencies": { 508 | "locate-path": "^6.0.0", 509 | "path-exists": "^4.0.0" 510 | }, 511 | "engines": { 512 | "node": ">=10" 513 | }, 514 | "funding": { 515 | "url": "https://github.com/sponsors/sindresorhus" 516 | } 517 | }, 518 | "node_modules/flat-cache": { 519 | "version": "3.0.4", 520 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", 521 | "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", 522 | "dev": true, 523 | "dependencies": { 524 | "flatted": "^3.1.0", 525 | "rimraf": "^3.0.2" 526 | }, 527 | "engines": { 528 | "node": "^10.12.0 || >=12.0.0" 529 | } 530 | }, 531 | "node_modules/flatted": { 532 | "version": "3.2.7", 533 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", 534 | "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", 535 | "dev": true 536 | }, 537 | "node_modules/fs.realpath": { 538 | "version": "1.0.0", 539 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 540 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 541 | "dev": true 542 | }, 543 | "node_modules/glob": { 544 | "version": "7.2.3", 545 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 546 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 547 | "dev": true, 548 | "dependencies": { 549 | "fs.realpath": "^1.0.0", 550 | "inflight": "^1.0.4", 551 | "inherits": "2", 552 | "minimatch": "^3.1.1", 553 | "once": "^1.3.0", 554 | "path-is-absolute": "^1.0.0" 555 | }, 556 | "engines": { 557 | "node": "*" 558 | }, 559 | "funding": { 560 | "url": "https://github.com/sponsors/isaacs" 561 | } 562 | }, 563 | "node_modules/glob-parent": { 564 | "version": "6.0.2", 565 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 566 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 567 | "dev": true, 568 | "dependencies": { 569 | "is-glob": "^4.0.3" 570 | }, 571 | "engines": { 572 | "node": ">=10.13.0" 573 | } 574 | }, 575 | "node_modules/globals": { 576 | "version": "13.17.0", 577 | "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", 578 | "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", 579 | "dev": true, 580 | "dependencies": { 581 | "type-fest": "^0.20.2" 582 | }, 583 | "engines": { 584 | "node": ">=8" 585 | }, 586 | "funding": { 587 | "url": "https://github.com/sponsors/sindresorhus" 588 | } 589 | }, 590 | "node_modules/grapheme-splitter": { 591 | "version": "1.0.4", 592 | "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", 593 | "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", 594 | "dev": true 595 | }, 596 | "node_modules/has-flag": { 597 | "version": "4.0.0", 598 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 599 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 600 | "dev": true, 601 | "engines": { 602 | "node": ">=8" 603 | } 604 | }, 605 | "node_modules/ignore": { 606 | "version": "5.2.0", 607 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", 608 | "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", 609 | "dev": true, 610 | "engines": { 611 | "node": ">= 4" 612 | } 613 | }, 614 | "node_modules/import-fresh": { 615 | "version": "3.3.0", 616 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", 617 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", 618 | "dev": true, 619 | "dependencies": { 620 | "parent-module": "^1.0.0", 621 | "resolve-from": "^4.0.0" 622 | }, 623 | "engines": { 624 | "node": ">=6" 625 | }, 626 | "funding": { 627 | "url": "https://github.com/sponsors/sindresorhus" 628 | } 629 | }, 630 | "node_modules/imurmurhash": { 631 | "version": "0.1.4", 632 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 633 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", 634 | "dev": true, 635 | "engines": { 636 | "node": ">=0.8.19" 637 | } 638 | }, 639 | "node_modules/inflight": { 640 | "version": "1.0.6", 641 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 642 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 643 | "dev": true, 644 | "dependencies": { 645 | "once": "^1.3.0", 646 | "wrappy": "1" 647 | } 648 | }, 649 | "node_modules/inherits": { 650 | "version": "2.0.4", 651 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 652 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 653 | "dev": true 654 | }, 655 | "node_modules/is-extglob": { 656 | "version": "2.1.1", 657 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 658 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 659 | "dev": true, 660 | "engines": { 661 | "node": ">=0.10.0" 662 | } 663 | }, 664 | "node_modules/is-glob": { 665 | "version": "4.0.3", 666 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 667 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 668 | "dev": true, 669 | "dependencies": { 670 | "is-extglob": "^2.1.1" 671 | }, 672 | "engines": { 673 | "node": ">=0.10.0" 674 | } 675 | }, 676 | "node_modules/is-path-inside": { 677 | "version": "3.0.3", 678 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", 679 | "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", 680 | "dev": true, 681 | "engines": { 682 | "node": ">=8" 683 | } 684 | }, 685 | "node_modules/isexe": { 686 | "version": "2.0.0", 687 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 688 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 689 | "dev": true 690 | }, 691 | "node_modules/js-sdsl": { 692 | "version": "4.1.5", 693 | "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", 694 | "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", 695 | "dev": true 696 | }, 697 | "node_modules/js-yaml": { 698 | "version": "4.1.0", 699 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 700 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 701 | "dev": true, 702 | "dependencies": { 703 | "argparse": "^2.0.1" 704 | }, 705 | "bin": { 706 | "js-yaml": "bin/js-yaml.js" 707 | } 708 | }, 709 | "node_modules/json-schema-traverse": { 710 | "version": "0.4.1", 711 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 712 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 713 | "dev": true 714 | }, 715 | "node_modules/json-stable-stringify-without-jsonify": { 716 | "version": "1.0.1", 717 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 718 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", 719 | "dev": true 720 | }, 721 | "node_modules/levn": { 722 | "version": "0.4.1", 723 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 724 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 725 | "dev": true, 726 | "dependencies": { 727 | "prelude-ls": "^1.2.1", 728 | "type-check": "~0.4.0" 729 | }, 730 | "engines": { 731 | "node": ">= 0.8.0" 732 | } 733 | }, 734 | "node_modules/locate-path": { 735 | "version": "6.0.0", 736 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 737 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 738 | "dev": true, 739 | "dependencies": { 740 | "p-locate": "^5.0.0" 741 | }, 742 | "engines": { 743 | "node": ">=10" 744 | }, 745 | "funding": { 746 | "url": "https://github.com/sponsors/sindresorhus" 747 | } 748 | }, 749 | "node_modules/lodash.merge": { 750 | "version": "4.6.2", 751 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 752 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 753 | "dev": true 754 | }, 755 | "node_modules/minimatch": { 756 | "version": "3.1.2", 757 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 758 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 759 | "dev": true, 760 | "dependencies": { 761 | "brace-expansion": "^1.1.7" 762 | }, 763 | "engines": { 764 | "node": "*" 765 | } 766 | }, 767 | "node_modules/ms": { 768 | "version": "2.1.2", 769 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 770 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 771 | "dev": true 772 | }, 773 | "node_modules/natural-compare": { 774 | "version": "1.4.0", 775 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 776 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", 777 | "dev": true 778 | }, 779 | "node_modules/once": { 780 | "version": "1.4.0", 781 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 782 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 783 | "dev": true, 784 | "dependencies": { 785 | "wrappy": "1" 786 | } 787 | }, 788 | "node_modules/optionator": { 789 | "version": "0.9.1", 790 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", 791 | "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", 792 | "dev": true, 793 | "dependencies": { 794 | "deep-is": "^0.1.3", 795 | "fast-levenshtein": "^2.0.6", 796 | "levn": "^0.4.1", 797 | "prelude-ls": "^1.2.1", 798 | "type-check": "^0.4.0", 799 | "word-wrap": "^1.2.3" 800 | }, 801 | "engines": { 802 | "node": ">= 0.8.0" 803 | } 804 | }, 805 | "node_modules/p-limit": { 806 | "version": "3.1.0", 807 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 808 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 809 | "dev": true, 810 | "dependencies": { 811 | "yocto-queue": "^0.1.0" 812 | }, 813 | "engines": { 814 | "node": ">=10" 815 | }, 816 | "funding": { 817 | "url": "https://github.com/sponsors/sindresorhus" 818 | } 819 | }, 820 | "node_modules/p-locate": { 821 | "version": "5.0.0", 822 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 823 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 824 | "dev": true, 825 | "dependencies": { 826 | "p-limit": "^3.0.2" 827 | }, 828 | "engines": { 829 | "node": ">=10" 830 | }, 831 | "funding": { 832 | "url": "https://github.com/sponsors/sindresorhus" 833 | } 834 | }, 835 | "node_modules/parent-module": { 836 | "version": "1.0.1", 837 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 838 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 839 | "dev": true, 840 | "dependencies": { 841 | "callsites": "^3.0.0" 842 | }, 843 | "engines": { 844 | "node": ">=6" 845 | } 846 | }, 847 | "node_modules/path-exists": { 848 | "version": "4.0.0", 849 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 850 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 851 | "dev": true, 852 | "engines": { 853 | "node": ">=8" 854 | } 855 | }, 856 | "node_modules/path-is-absolute": { 857 | "version": "1.0.1", 858 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 859 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 860 | "dev": true, 861 | "engines": { 862 | "node": ">=0.10.0" 863 | } 864 | }, 865 | "node_modules/path-key": { 866 | "version": "3.1.1", 867 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 868 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 869 | "dev": true, 870 | "engines": { 871 | "node": ">=8" 872 | } 873 | }, 874 | "node_modules/prelude-ls": { 875 | "version": "1.2.1", 876 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 877 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 878 | "dev": true, 879 | "engines": { 880 | "node": ">= 0.8.0" 881 | } 882 | }, 883 | "node_modules/punycode": { 884 | "version": "2.1.1", 885 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 886 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 887 | "dev": true, 888 | "engines": { 889 | "node": ">=6" 890 | } 891 | }, 892 | "node_modules/queue-microtask": { 893 | "version": "1.2.3", 894 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 895 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 896 | "dev": true, 897 | "funding": [ 898 | { 899 | "type": "github", 900 | "url": "https://github.com/sponsors/feross" 901 | }, 902 | { 903 | "type": "patreon", 904 | "url": "https://www.patreon.com/feross" 905 | }, 906 | { 907 | "type": "consulting", 908 | "url": "https://feross.org/support" 909 | } 910 | ] 911 | }, 912 | "node_modules/regexpp": { 913 | "version": "3.2.0", 914 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", 915 | "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", 916 | "dev": true, 917 | "engines": { 918 | "node": ">=8" 919 | }, 920 | "funding": { 921 | "url": "https://github.com/sponsors/mysticatea" 922 | } 923 | }, 924 | "node_modules/resolve-from": { 925 | "version": "4.0.0", 926 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 927 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 928 | "dev": true, 929 | "engines": { 930 | "node": ">=4" 931 | } 932 | }, 933 | "node_modules/reusify": { 934 | "version": "1.0.4", 935 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 936 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 937 | "dev": true, 938 | "engines": { 939 | "iojs": ">=1.0.0", 940 | "node": ">=0.10.0" 941 | } 942 | }, 943 | "node_modules/rimraf": { 944 | "version": "3.0.2", 945 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 946 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 947 | "dev": true, 948 | "dependencies": { 949 | "glob": "^7.1.3" 950 | }, 951 | "bin": { 952 | "rimraf": "bin.js" 953 | }, 954 | "funding": { 955 | "url": "https://github.com/sponsors/isaacs" 956 | } 957 | }, 958 | "node_modules/run-parallel": { 959 | "version": "1.2.0", 960 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 961 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 962 | "dev": true, 963 | "funding": [ 964 | { 965 | "type": "github", 966 | "url": "https://github.com/sponsors/feross" 967 | }, 968 | { 969 | "type": "patreon", 970 | "url": "https://www.patreon.com/feross" 971 | }, 972 | { 973 | "type": "consulting", 974 | "url": "https://feross.org/support" 975 | } 976 | ], 977 | "dependencies": { 978 | "queue-microtask": "^1.2.2" 979 | } 980 | }, 981 | "node_modules/shebang-command": { 982 | "version": "2.0.0", 983 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 984 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 985 | "dev": true, 986 | "dependencies": { 987 | "shebang-regex": "^3.0.0" 988 | }, 989 | "engines": { 990 | "node": ">=8" 991 | } 992 | }, 993 | "node_modules/shebang-regex": { 994 | "version": "3.0.0", 995 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 996 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 997 | "dev": true, 998 | "engines": { 999 | "node": ">=8" 1000 | } 1001 | }, 1002 | "node_modules/strip-ansi": { 1003 | "version": "6.0.1", 1004 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1005 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1006 | "dev": true, 1007 | "dependencies": { 1008 | "ansi-regex": "^5.0.1" 1009 | }, 1010 | "engines": { 1011 | "node": ">=8" 1012 | } 1013 | }, 1014 | "node_modules/strip-json-comments": { 1015 | "version": "3.1.1", 1016 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1017 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1018 | "dev": true, 1019 | "engines": { 1020 | "node": ">=8" 1021 | }, 1022 | "funding": { 1023 | "url": "https://github.com/sponsors/sindresorhus" 1024 | } 1025 | }, 1026 | "node_modules/supports-color": { 1027 | "version": "7.2.0", 1028 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1029 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1030 | "dev": true, 1031 | "dependencies": { 1032 | "has-flag": "^4.0.0" 1033 | }, 1034 | "engines": { 1035 | "node": ">=8" 1036 | } 1037 | }, 1038 | "node_modules/text-table": { 1039 | "version": "0.2.0", 1040 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 1041 | "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", 1042 | "dev": true 1043 | }, 1044 | "node_modules/type-check": { 1045 | "version": "0.4.0", 1046 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 1047 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 1048 | "dev": true, 1049 | "dependencies": { 1050 | "prelude-ls": "^1.2.1" 1051 | }, 1052 | "engines": { 1053 | "node": ">= 0.8.0" 1054 | } 1055 | }, 1056 | "node_modules/type-fest": { 1057 | "version": "0.20.2", 1058 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", 1059 | "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", 1060 | "dev": true, 1061 | "engines": { 1062 | "node": ">=10" 1063 | }, 1064 | "funding": { 1065 | "url": "https://github.com/sponsors/sindresorhus" 1066 | } 1067 | }, 1068 | "node_modules/uri-js": { 1069 | "version": "4.4.1", 1070 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 1071 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 1072 | "dev": true, 1073 | "dependencies": { 1074 | "punycode": "^2.1.0" 1075 | } 1076 | }, 1077 | "node_modules/which": { 1078 | "version": "2.0.2", 1079 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 1080 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 1081 | "dev": true, 1082 | "dependencies": { 1083 | "isexe": "^2.0.0" 1084 | }, 1085 | "bin": { 1086 | "node-which": "bin/node-which" 1087 | }, 1088 | "engines": { 1089 | "node": ">= 8" 1090 | } 1091 | }, 1092 | "node_modules/word-wrap": { 1093 | "version": "1.2.3", 1094 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 1095 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 1096 | "dev": true, 1097 | "engines": { 1098 | "node": ">=0.10.0" 1099 | } 1100 | }, 1101 | "node_modules/wrappy": { 1102 | "version": "1.0.2", 1103 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1104 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 1105 | "dev": true 1106 | }, 1107 | "node_modules/yocto-queue": { 1108 | "version": "0.1.0", 1109 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 1110 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 1111 | "dev": true, 1112 | "engines": { 1113 | "node": ">=10" 1114 | }, 1115 | "funding": { 1116 | "url": "https://github.com/sponsors/sindresorhus" 1117 | } 1118 | } 1119 | }, 1120 | "dependencies": { 1121 | "@eslint/eslintrc": { 1122 | "version": "1.3.3", 1123 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", 1124 | "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", 1125 | "dev": true, 1126 | "requires": { 1127 | "ajv": "^6.12.4", 1128 | "debug": "^4.3.2", 1129 | "espree": "^9.4.0", 1130 | "globals": "^13.15.0", 1131 | "ignore": "^5.2.0", 1132 | "import-fresh": "^3.2.1", 1133 | "js-yaml": "^4.1.0", 1134 | "minimatch": "^3.1.2", 1135 | "strip-json-comments": "^3.1.1" 1136 | } 1137 | }, 1138 | "@humanwhocodes/config-array": { 1139 | "version": "0.11.7", 1140 | "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", 1141 | "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", 1142 | "dev": true, 1143 | "requires": { 1144 | "@humanwhocodes/object-schema": "^1.2.1", 1145 | "debug": "^4.1.1", 1146 | "minimatch": "^3.0.5" 1147 | } 1148 | }, 1149 | "@humanwhocodes/module-importer": { 1150 | "version": "1.0.1", 1151 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", 1152 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", 1153 | "dev": true 1154 | }, 1155 | "@humanwhocodes/object-schema": { 1156 | "version": "1.2.1", 1157 | "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", 1158 | "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", 1159 | "dev": true 1160 | }, 1161 | "@nodelib/fs.scandir": { 1162 | "version": "2.1.5", 1163 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 1164 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 1165 | "dev": true, 1166 | "requires": { 1167 | "@nodelib/fs.stat": "2.0.5", 1168 | "run-parallel": "^1.1.9" 1169 | } 1170 | }, 1171 | "@nodelib/fs.stat": { 1172 | "version": "2.0.5", 1173 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 1174 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 1175 | "dev": true 1176 | }, 1177 | "@nodelib/fs.walk": { 1178 | "version": "1.2.8", 1179 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 1180 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 1181 | "dev": true, 1182 | "requires": { 1183 | "@nodelib/fs.scandir": "2.1.5", 1184 | "fastq": "^1.6.0" 1185 | } 1186 | }, 1187 | "acorn": { 1188 | "version": "8.8.1", 1189 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", 1190 | "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", 1191 | "dev": true 1192 | }, 1193 | "acorn-jsx": { 1194 | "version": "5.3.2", 1195 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 1196 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 1197 | "dev": true, 1198 | "requires": {} 1199 | }, 1200 | "ajv": { 1201 | "version": "6.12.6", 1202 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 1203 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 1204 | "dev": true, 1205 | "requires": { 1206 | "fast-deep-equal": "^3.1.1", 1207 | "fast-json-stable-stringify": "^2.0.0", 1208 | "json-schema-traverse": "^0.4.1", 1209 | "uri-js": "^4.2.2" 1210 | } 1211 | }, 1212 | "ansi-regex": { 1213 | "version": "5.0.1", 1214 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 1215 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 1216 | "dev": true 1217 | }, 1218 | "ansi-styles": { 1219 | "version": "4.3.0", 1220 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 1221 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 1222 | "dev": true, 1223 | "requires": { 1224 | "color-convert": "^2.0.1" 1225 | } 1226 | }, 1227 | "argparse": { 1228 | "version": "2.0.1", 1229 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 1230 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 1231 | "dev": true 1232 | }, 1233 | "balanced-match": { 1234 | "version": "1.0.2", 1235 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 1236 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 1237 | "dev": true 1238 | }, 1239 | "brace-expansion": { 1240 | "version": "1.1.11", 1241 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 1242 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 1243 | "dev": true, 1244 | "requires": { 1245 | "balanced-match": "^1.0.0", 1246 | "concat-map": "0.0.1" 1247 | } 1248 | }, 1249 | "callsites": { 1250 | "version": "3.1.0", 1251 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 1252 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 1253 | "dev": true 1254 | }, 1255 | "chalk": { 1256 | "version": "4.1.2", 1257 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 1258 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 1259 | "dev": true, 1260 | "requires": { 1261 | "ansi-styles": "^4.1.0", 1262 | "supports-color": "^7.1.0" 1263 | } 1264 | }, 1265 | "color-convert": { 1266 | "version": "2.0.1", 1267 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 1268 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 1269 | "dev": true, 1270 | "requires": { 1271 | "color-name": "~1.1.4" 1272 | } 1273 | }, 1274 | "color-name": { 1275 | "version": "1.1.4", 1276 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 1277 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 1278 | "dev": true 1279 | }, 1280 | "concat-map": { 1281 | "version": "0.0.1", 1282 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 1283 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 1284 | "dev": true 1285 | }, 1286 | "cross-spawn": { 1287 | "version": "7.0.3", 1288 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 1289 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 1290 | "dev": true, 1291 | "requires": { 1292 | "path-key": "^3.1.0", 1293 | "shebang-command": "^2.0.0", 1294 | "which": "^2.0.1" 1295 | } 1296 | }, 1297 | "debug": { 1298 | "version": "4.3.4", 1299 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 1300 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 1301 | "dev": true, 1302 | "requires": { 1303 | "ms": "2.1.2" 1304 | } 1305 | }, 1306 | "deep-is": { 1307 | "version": "0.1.4", 1308 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 1309 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 1310 | "dev": true 1311 | }, 1312 | "doctrine": { 1313 | "version": "3.0.0", 1314 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 1315 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 1316 | "dev": true, 1317 | "requires": { 1318 | "esutils": "^2.0.2" 1319 | } 1320 | }, 1321 | "escape-string-regexp": { 1322 | "version": "4.0.0", 1323 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 1324 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 1325 | "dev": true 1326 | }, 1327 | "eslint": { 1328 | "version": "8.27.0", 1329 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.27.0.tgz", 1330 | "integrity": "sha512-0y1bfG2ho7mty+SiILVf9PfuRA49ek4Nc60Wmmu62QlobNR+CeXa4xXIJgcuwSQgZiWaPH+5BDsctpIW0PR/wQ==", 1331 | "dev": true, 1332 | "requires": { 1333 | "@eslint/eslintrc": "^1.3.3", 1334 | "@humanwhocodes/config-array": "^0.11.6", 1335 | "@humanwhocodes/module-importer": "^1.0.1", 1336 | "@nodelib/fs.walk": "^1.2.8", 1337 | "ajv": "^6.10.0", 1338 | "chalk": "^4.0.0", 1339 | "cross-spawn": "^7.0.2", 1340 | "debug": "^4.3.2", 1341 | "doctrine": "^3.0.0", 1342 | "escape-string-regexp": "^4.0.0", 1343 | "eslint-scope": "^7.1.1", 1344 | "eslint-utils": "^3.0.0", 1345 | "eslint-visitor-keys": "^3.3.0", 1346 | "espree": "^9.4.0", 1347 | "esquery": "^1.4.0", 1348 | "esutils": "^2.0.2", 1349 | "fast-deep-equal": "^3.1.3", 1350 | "file-entry-cache": "^6.0.1", 1351 | "find-up": "^5.0.0", 1352 | "glob-parent": "^6.0.2", 1353 | "globals": "^13.15.0", 1354 | "grapheme-splitter": "^1.0.4", 1355 | "ignore": "^5.2.0", 1356 | "import-fresh": "^3.0.0", 1357 | "imurmurhash": "^0.1.4", 1358 | "is-glob": "^4.0.0", 1359 | "is-path-inside": "^3.0.3", 1360 | "js-sdsl": "^4.1.4", 1361 | "js-yaml": "^4.1.0", 1362 | "json-stable-stringify-without-jsonify": "^1.0.1", 1363 | "levn": "^0.4.1", 1364 | "lodash.merge": "^4.6.2", 1365 | "minimatch": "^3.1.2", 1366 | "natural-compare": "^1.4.0", 1367 | "optionator": "^0.9.1", 1368 | "regexpp": "^3.2.0", 1369 | "strip-ansi": "^6.0.1", 1370 | "strip-json-comments": "^3.1.0", 1371 | "text-table": "^0.2.0" 1372 | } 1373 | }, 1374 | "eslint-scope": { 1375 | "version": "7.1.1", 1376 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", 1377 | "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", 1378 | "dev": true, 1379 | "requires": { 1380 | "esrecurse": "^4.3.0", 1381 | "estraverse": "^5.2.0" 1382 | } 1383 | }, 1384 | "eslint-utils": { 1385 | "version": "3.0.0", 1386 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", 1387 | "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", 1388 | "dev": true, 1389 | "requires": { 1390 | "eslint-visitor-keys": "^2.0.0" 1391 | }, 1392 | "dependencies": { 1393 | "eslint-visitor-keys": { 1394 | "version": "2.1.0", 1395 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", 1396 | "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", 1397 | "dev": true 1398 | } 1399 | } 1400 | }, 1401 | "eslint-visitor-keys": { 1402 | "version": "3.3.0", 1403 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", 1404 | "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", 1405 | "dev": true 1406 | }, 1407 | "espree": { 1408 | "version": "9.4.1", 1409 | "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", 1410 | "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", 1411 | "dev": true, 1412 | "requires": { 1413 | "acorn": "^8.8.0", 1414 | "acorn-jsx": "^5.3.2", 1415 | "eslint-visitor-keys": "^3.3.0" 1416 | } 1417 | }, 1418 | "esquery": { 1419 | "version": "1.4.0", 1420 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", 1421 | "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", 1422 | "dev": true, 1423 | "requires": { 1424 | "estraverse": "^5.1.0" 1425 | } 1426 | }, 1427 | "esrecurse": { 1428 | "version": "4.3.0", 1429 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 1430 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 1431 | "dev": true, 1432 | "requires": { 1433 | "estraverse": "^5.2.0" 1434 | } 1435 | }, 1436 | "estraverse": { 1437 | "version": "5.3.0", 1438 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 1439 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 1440 | "dev": true 1441 | }, 1442 | "esutils": { 1443 | "version": "2.0.3", 1444 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 1445 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 1446 | "dev": true 1447 | }, 1448 | "fast-deep-equal": { 1449 | "version": "3.1.3", 1450 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 1451 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 1452 | "dev": true 1453 | }, 1454 | "fast-json-stable-stringify": { 1455 | "version": "2.1.0", 1456 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 1457 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 1458 | "dev": true 1459 | }, 1460 | "fast-levenshtein": { 1461 | "version": "2.0.6", 1462 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 1463 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", 1464 | "dev": true 1465 | }, 1466 | "fastq": { 1467 | "version": "1.13.0", 1468 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", 1469 | "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", 1470 | "dev": true, 1471 | "requires": { 1472 | "reusify": "^1.0.4" 1473 | } 1474 | }, 1475 | "file-entry-cache": { 1476 | "version": "6.0.1", 1477 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", 1478 | "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", 1479 | "dev": true, 1480 | "requires": { 1481 | "flat-cache": "^3.0.4" 1482 | } 1483 | }, 1484 | "find-up": { 1485 | "version": "5.0.0", 1486 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 1487 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 1488 | "dev": true, 1489 | "requires": { 1490 | "locate-path": "^6.0.0", 1491 | "path-exists": "^4.0.0" 1492 | } 1493 | }, 1494 | "flat-cache": { 1495 | "version": "3.0.4", 1496 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", 1497 | "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", 1498 | "dev": true, 1499 | "requires": { 1500 | "flatted": "^3.1.0", 1501 | "rimraf": "^3.0.2" 1502 | } 1503 | }, 1504 | "flatted": { 1505 | "version": "3.2.7", 1506 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", 1507 | "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", 1508 | "dev": true 1509 | }, 1510 | "fs.realpath": { 1511 | "version": "1.0.0", 1512 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1513 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 1514 | "dev": true 1515 | }, 1516 | "glob": { 1517 | "version": "7.2.3", 1518 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 1519 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 1520 | "dev": true, 1521 | "requires": { 1522 | "fs.realpath": "^1.0.0", 1523 | "inflight": "^1.0.4", 1524 | "inherits": "2", 1525 | "minimatch": "^3.1.1", 1526 | "once": "^1.3.0", 1527 | "path-is-absolute": "^1.0.0" 1528 | } 1529 | }, 1530 | "glob-parent": { 1531 | "version": "6.0.2", 1532 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 1533 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 1534 | "dev": true, 1535 | "requires": { 1536 | "is-glob": "^4.0.3" 1537 | } 1538 | }, 1539 | "globals": { 1540 | "version": "13.17.0", 1541 | "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", 1542 | "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", 1543 | "dev": true, 1544 | "requires": { 1545 | "type-fest": "^0.20.2" 1546 | } 1547 | }, 1548 | "grapheme-splitter": { 1549 | "version": "1.0.4", 1550 | "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", 1551 | "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", 1552 | "dev": true 1553 | }, 1554 | "has-flag": { 1555 | "version": "4.0.0", 1556 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1557 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1558 | "dev": true 1559 | }, 1560 | "ignore": { 1561 | "version": "5.2.0", 1562 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", 1563 | "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", 1564 | "dev": true 1565 | }, 1566 | "import-fresh": { 1567 | "version": "3.3.0", 1568 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", 1569 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", 1570 | "dev": true, 1571 | "requires": { 1572 | "parent-module": "^1.0.0", 1573 | "resolve-from": "^4.0.0" 1574 | } 1575 | }, 1576 | "imurmurhash": { 1577 | "version": "0.1.4", 1578 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 1579 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", 1580 | "dev": true 1581 | }, 1582 | "inflight": { 1583 | "version": "1.0.6", 1584 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1585 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 1586 | "dev": true, 1587 | "requires": { 1588 | "once": "^1.3.0", 1589 | "wrappy": "1" 1590 | } 1591 | }, 1592 | "inherits": { 1593 | "version": "2.0.4", 1594 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1595 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 1596 | "dev": true 1597 | }, 1598 | "is-extglob": { 1599 | "version": "2.1.1", 1600 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1601 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 1602 | "dev": true 1603 | }, 1604 | "is-glob": { 1605 | "version": "4.0.3", 1606 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 1607 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 1608 | "dev": true, 1609 | "requires": { 1610 | "is-extglob": "^2.1.1" 1611 | } 1612 | }, 1613 | "is-path-inside": { 1614 | "version": "3.0.3", 1615 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", 1616 | "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", 1617 | "dev": true 1618 | }, 1619 | "isexe": { 1620 | "version": "2.0.0", 1621 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1622 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 1623 | "dev": true 1624 | }, 1625 | "js-sdsl": { 1626 | "version": "4.1.5", 1627 | "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", 1628 | "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", 1629 | "dev": true 1630 | }, 1631 | "js-yaml": { 1632 | "version": "4.1.0", 1633 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 1634 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 1635 | "dev": true, 1636 | "requires": { 1637 | "argparse": "^2.0.1" 1638 | } 1639 | }, 1640 | "json-schema-traverse": { 1641 | "version": "0.4.1", 1642 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 1643 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 1644 | "dev": true 1645 | }, 1646 | "json-stable-stringify-without-jsonify": { 1647 | "version": "1.0.1", 1648 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 1649 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", 1650 | "dev": true 1651 | }, 1652 | "levn": { 1653 | "version": "0.4.1", 1654 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 1655 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 1656 | "dev": true, 1657 | "requires": { 1658 | "prelude-ls": "^1.2.1", 1659 | "type-check": "~0.4.0" 1660 | } 1661 | }, 1662 | "locate-path": { 1663 | "version": "6.0.0", 1664 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 1665 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 1666 | "dev": true, 1667 | "requires": { 1668 | "p-locate": "^5.0.0" 1669 | } 1670 | }, 1671 | "lodash.merge": { 1672 | "version": "4.6.2", 1673 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 1674 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 1675 | "dev": true 1676 | }, 1677 | "minimatch": { 1678 | "version": "3.1.2", 1679 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1680 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1681 | "dev": true, 1682 | "requires": { 1683 | "brace-expansion": "^1.1.7" 1684 | } 1685 | }, 1686 | "ms": { 1687 | "version": "2.1.2", 1688 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1689 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1690 | "dev": true 1691 | }, 1692 | "natural-compare": { 1693 | "version": "1.4.0", 1694 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 1695 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", 1696 | "dev": true 1697 | }, 1698 | "once": { 1699 | "version": "1.4.0", 1700 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1701 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 1702 | "dev": true, 1703 | "requires": { 1704 | "wrappy": "1" 1705 | } 1706 | }, 1707 | "optionator": { 1708 | "version": "0.9.1", 1709 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", 1710 | "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", 1711 | "dev": true, 1712 | "requires": { 1713 | "deep-is": "^0.1.3", 1714 | "fast-levenshtein": "^2.0.6", 1715 | "levn": "^0.4.1", 1716 | "prelude-ls": "^1.2.1", 1717 | "type-check": "^0.4.0", 1718 | "word-wrap": "^1.2.3" 1719 | } 1720 | }, 1721 | "p-limit": { 1722 | "version": "3.1.0", 1723 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 1724 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 1725 | "dev": true, 1726 | "requires": { 1727 | "yocto-queue": "^0.1.0" 1728 | } 1729 | }, 1730 | "p-locate": { 1731 | "version": "5.0.0", 1732 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 1733 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 1734 | "dev": true, 1735 | "requires": { 1736 | "p-limit": "^3.0.2" 1737 | } 1738 | }, 1739 | "parent-module": { 1740 | "version": "1.0.1", 1741 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 1742 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 1743 | "dev": true, 1744 | "requires": { 1745 | "callsites": "^3.0.0" 1746 | } 1747 | }, 1748 | "path-exists": { 1749 | "version": "4.0.0", 1750 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 1751 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 1752 | "dev": true 1753 | }, 1754 | "path-is-absolute": { 1755 | "version": "1.0.1", 1756 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1757 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 1758 | "dev": true 1759 | }, 1760 | "path-key": { 1761 | "version": "3.1.1", 1762 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 1763 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 1764 | "dev": true 1765 | }, 1766 | "prelude-ls": { 1767 | "version": "1.2.1", 1768 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 1769 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 1770 | "dev": true 1771 | }, 1772 | "punycode": { 1773 | "version": "2.1.1", 1774 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 1775 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 1776 | "dev": true 1777 | }, 1778 | "queue-microtask": { 1779 | "version": "1.2.3", 1780 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 1781 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 1782 | "dev": true 1783 | }, 1784 | "regexpp": { 1785 | "version": "3.2.0", 1786 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", 1787 | "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", 1788 | "dev": true 1789 | }, 1790 | "resolve-from": { 1791 | "version": "4.0.0", 1792 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 1793 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 1794 | "dev": true 1795 | }, 1796 | "reusify": { 1797 | "version": "1.0.4", 1798 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 1799 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 1800 | "dev": true 1801 | }, 1802 | "rimraf": { 1803 | "version": "3.0.2", 1804 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 1805 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 1806 | "dev": true, 1807 | "requires": { 1808 | "glob": "^7.1.3" 1809 | } 1810 | }, 1811 | "run-parallel": { 1812 | "version": "1.2.0", 1813 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 1814 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 1815 | "dev": true, 1816 | "requires": { 1817 | "queue-microtask": "^1.2.2" 1818 | } 1819 | }, 1820 | "shebang-command": { 1821 | "version": "2.0.0", 1822 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 1823 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 1824 | "dev": true, 1825 | "requires": { 1826 | "shebang-regex": "^3.0.0" 1827 | } 1828 | }, 1829 | "shebang-regex": { 1830 | "version": "3.0.0", 1831 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 1832 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 1833 | "dev": true 1834 | }, 1835 | "strip-ansi": { 1836 | "version": "6.0.1", 1837 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1838 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1839 | "dev": true, 1840 | "requires": { 1841 | "ansi-regex": "^5.0.1" 1842 | } 1843 | }, 1844 | "strip-json-comments": { 1845 | "version": "3.1.1", 1846 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1847 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1848 | "dev": true 1849 | }, 1850 | "supports-color": { 1851 | "version": "7.2.0", 1852 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1853 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1854 | "dev": true, 1855 | "requires": { 1856 | "has-flag": "^4.0.0" 1857 | } 1858 | }, 1859 | "text-table": { 1860 | "version": "0.2.0", 1861 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 1862 | "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", 1863 | "dev": true 1864 | }, 1865 | "type-check": { 1866 | "version": "0.4.0", 1867 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 1868 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 1869 | "dev": true, 1870 | "requires": { 1871 | "prelude-ls": "^1.2.1" 1872 | } 1873 | }, 1874 | "type-fest": { 1875 | "version": "0.20.2", 1876 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", 1877 | "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", 1878 | "dev": true 1879 | }, 1880 | "uri-js": { 1881 | "version": "4.4.1", 1882 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 1883 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 1884 | "dev": true, 1885 | "requires": { 1886 | "punycode": "^2.1.0" 1887 | } 1888 | }, 1889 | "which": { 1890 | "version": "2.0.2", 1891 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 1892 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 1893 | "dev": true, 1894 | "requires": { 1895 | "isexe": "^2.0.0" 1896 | } 1897 | }, 1898 | "word-wrap": { 1899 | "version": "1.2.3", 1900 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 1901 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 1902 | "dev": true 1903 | }, 1904 | "wrappy": { 1905 | "version": "1.0.2", 1906 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1907 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 1908 | "dev": true 1909 | }, 1910 | "yocto-queue": { 1911 | "version": "0.1.0", 1912 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 1913 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 1914 | "dev": true 1915 | } 1916 | } 1917 | } 1918 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "js-turtle", 3 | "version": "0.1.0", 4 | "description": "Turtle graphics in Javascript using HTML5 canvas", 5 | "main": "turtle.js", 6 | "directories": { 7 | "example": "examples" 8 | }, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/bjpop/js-turtle.git" 15 | }, 16 | "author": "bjpop", 17 | "license": "BSD-3-Clause", 18 | "bugs": { 19 | "url": "https://github.com/bjpop/js-turtle/issues" 20 | }, 21 | "homepage": "https://github.com/bjpop/js-turtle#readme", 22 | "devDependencies": { 23 | "eslint": "^8.27.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /turtle.css: -------------------------------------------------------------------------------- 1 | body, 2 | html { 3 | margin:0; 4 | padding:0; 5 | font-family: sans-serif; 6 | } 7 | 8 | body h1 { 9 | text-align:center; 10 | } 11 | 12 | #wrap { 13 | width:1000px; 14 | margin:0 auto; 15 | } 16 | 17 | #leftcolumn { 18 | float:left; 19 | width:30%; 20 | } 21 | 22 | #midcolumn { 23 | float:left; 24 | width:35%; 25 | } 26 | 27 | #rightcolumn { 28 | float:right; 29 | width:35%; 30 | } 31 | 32 | #turtlecanvas { 33 | background:#fff; 34 | border: 1px solid red; 35 | } 36 | 37 | #definitions { 38 | width:300px; 39 | } 40 | 41 | #command { 42 | width:300px; 43 | } 44 | -------------------------------------------------------------------------------- /turtle.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Javascript Turtle 5 | 6 | 7 | 8 | 9 |
10 |

Javascript Turtle Graphics

11 |
12 |

Language API Reference

13 | 14 | forward(distance)
15 | right(angle)
16 | left(angle)
17 | goto(x,y)
18 | clear()
19 | penup()
20 | pendown()
21 | reset()
22 | angle(angle)
23 | degToRad(angle)
24 | radToDeg(angle)
25 | width(width)
26 | shape(shape)
27 | colour(r,g,b,a)
28 | color(r,g,b,a)
29 | write(msg)
30 | n = random(low,high)
31 | hideTurtle()
32 | showTurtle()
33 | redrawOnMove(bool)
34 | draw()
35 | repeat(n, action)
36 | wrap(bool)
37 | animate(action,ms)
38 | range(start, end, step=1)
39 |
40 |
41 |
42 |

Canvas

43 | 44 | 45 |

Command

46 | 47 |
48 | 49 | 50 | 51 |
52 |
53 |

Definitions

54 | 74 |
75 |
76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /turtle.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * @typedef {number} Uint32 4 | * Name influenced by {@link Uint32Array} 5 | */ 6 | 7 | /** 8 | * Yield a sequence of numbers in the interval `[start, end(`. 9 | * Doesn't handle unsafe (overflowing) numbers, so it'll get stuck at {@link Number.MAX_SAFE_INTEGER}. 10 | * @param {number} start 11 | * @param {number} end 12 | */ 13 | const range = function*(start, end, step=1) { 14 | for (let i = +start; i < +end; i += +step){ 15 | yield i; 16 | } 17 | }; 18 | 19 | /* 20 | vars that should be private/local but are public/global, are prefixed with `_`. 21 | 22 | fns that sanitize their inputs (despite JSDoc type annotations) are "very public" API. 23 | */ 24 | 25 | // get a handle for each canvas in the document 26 | const _imageCanvas = /**@type {HTMLCanvasElement}*/(document.getElementById('imagecanvas')); 27 | const _imageCtx = /**@type {CanvasRenderingContext2D}*/(_imageCanvas.getContext('2d')); 28 | 29 | _imageCtx.textAlign = 'center'; 30 | _imageCtx.textBaseline = 'middle'; 31 | 32 | const _turtleCtx = (() => { 33 | const turtleCanv = /**@type {HTMLCanvasElement}*/(document.getElementById('turtlecanvas')); 34 | return /**@type {CanvasRenderingContext2D}*/(turtleCanv.getContext('2d')); 35 | })(); 36 | 37 | // the turtle takes precedence when compositing 38 | _turtleCtx.globalCompositeOperation = 'destination-over'; 39 | 40 | /** 41 | * specification of relative coordinates for drawing turtle shapes, 42 | * as lists of [x,y] pairs. 43 | * (The shapes are borrowed from cpython turtle.py) 44 | */ 45 | const _shapes = Object.freeze(/**@type {const}*/({ 46 | triangle: [[-5, 0], [5, 0], [0, 15]], 47 | turtle: [ 48 | [0, 16], [-2, 14], [-1, 10], [-4, 7], [-7, 9], 49 | [-9, 8], [-6, 5], [-7, 1], [-5, -3], [-8, -6], 50 | [-6, -8], [-4, -5], [0, -7], [4, -5], [6, -8], 51 | [8, -6], [5, -3], [7, 1], [6, 5], [9, 8], 52 | [7, 9], [4, 7], [1, 10], [2, 14] 53 | ], 54 | square: [[10, -10], [10, 10], [-10, 10], [-10, -10]], 55 | circle: [ 56 | [10, 0], [9.51, 3.09], [8.09, 5.88], 57 | [5.88, 8.09], [3.09, 9.51], [0, 10], 58 | [-3.09, 9.51], [-5.88, 8.09], [-8.09, 5.88], 59 | [-9.51, 3.09], [-10, 0], [-9.51, -3.09], 60 | [-8.09, -5.88], [-5.88, -8.09], [-3.09, -9.51], 61 | [-0.00, -10.00], [3.09, -9.51], [5.88, -8.09], 62 | [8.09, -5.88], [9.51, -3.09] 63 | ] 64 | })); 65 | 66 | const _DEFAULT_SHAPE = 'triangle'; 67 | 68 | /** turtle-object constructor, for static type-checking */ 69 | const _defaultTurtle = () => ({ 70 | pos: { 71 | x: 0, 72 | y: 0 73 | }, 74 | angle: 0, 75 | penDown: true, 76 | width: 1, 77 | visible: true, 78 | redraw: true, // does this belong here? 79 | wrap: true, 80 | shape: _DEFAULT_SHAPE, 81 | colour: { 82 | r: 0, 83 | g: 0, 84 | b: 0, 85 | a: 1 86 | } 87 | }); 88 | 89 | // initialise the state of the turtle 90 | let _turtle = _defaultTurtle(); 91 | 92 | /** 93 | * draw the turtle and the current image if `redraw` is `true`. 94 | * for complicated drawings it is much faster to turn `redraw` off. 95 | */ 96 | const drawIf = () => { _turtle.redraw && draw(); }; 97 | 98 | /** 99 | * use canvas centered coordinates facing upwards 100 | * @param {CanvasRenderingContext2D} ctx 101 | */ 102 | const _centerCoords = ctx => { 103 | const {width: w, height: h} = ctx.canvas; 104 | ctx.translate(w / 2, h / 2); 105 | ctx.transform(1, 0, 0, -1, 0, 0); 106 | }; 107 | 108 | /** draw the turtle and the current image */ 109 | const draw = () => { 110 | _clearCtx(_turtleCtx); 111 | if (_turtle.visible) { 112 | const {x, y} = _turtle.pos; 113 | 114 | _turtleCtx.save(); 115 | _centerCoords(_turtleCtx); 116 | // move the origin to the turtle center 117 | _turtleCtx.translate(x, y); 118 | // rotate about the center of the turtle 119 | _turtleCtx.rotate(-_turtle.angle); 120 | // move the turtle back to its position 121 | _turtleCtx.translate(-x, -y); 122 | 123 | /** 124 | * the type isn't guaranteed, because {@link _shapes} is fully mutable, 125 | * so the user may mutate it 126 | * @type {number[][]} 127 | */ 128 | const shape = _shapes[ 129 | // eslint-disable-next-line no-prototype-builtins 130 | _shapes.hasOwnProperty(_turtle.shape) ? _turtle.shape : _DEFAULT_SHAPE 131 | ]; 132 | 133 | // draw the turtle icon 134 | _turtleCtx.beginPath(); 135 | if (shape.length > 0) 136 | _turtleCtx.moveTo(x + shape[0][0], y + shape[0][1]); 137 | for (const [cx, cy] of shape.slice(1)) { 138 | _turtleCtx.lineTo(x + cx, y + cy); 139 | } 140 | _turtleCtx.closePath(); 141 | 142 | _turtleCtx.fillStyle = 'green'; 143 | _turtleCtx.fill(); 144 | _turtleCtx.restore(); 145 | } 146 | _turtleCtx.drawImage(_imageCanvas, 0, 0, 300, 300, 0, 0, 300, 300); 147 | }; 148 | 149 | const _clearCtx = (/**@type {CanvasRenderingContext2D}*/ ctx) => { 150 | const {width: w, height: h} = ctx.canvas; 151 | ctx.save(); 152 | ctx.setTransform( 1,0,0,1,0,0 ); 153 | ctx.clearRect( 0,0,w,h ); 154 | ctx.restore(); 155 | }; 156 | 157 | /** clear the display, don't move the turtle */ 158 | const clear = () => { 159 | _clearCtx(_imageCtx); 160 | drawIf(); 161 | }; 162 | 163 | /** 164 | * reset the whole system, clear the display and move turtle back to 165 | * origin, facing the Y axis. 166 | */ 167 | const reset = () => { 168 | // initialise 169 | _turtle = _defaultTurtle(); 170 | _imageCtx.lineWidth = _turtle.width; 171 | _imageCtx.strokeStyle = 'black'; 172 | _imageCtx.globalAlpha = 1; 173 | 174 | clear(); 175 | draw(); 176 | }; 177 | 178 | /** 179 | * Trace the forward motion of the turtle, allowing for possible 180 | * wrap-around at the boundaries of the canvas. 181 | * @param {number} distance 182 | */ 183 | const forward = distance => { 184 | distance = +distance; 185 | 186 | _imageCtx.save(); 187 | _centerCoords(_imageCtx); 188 | _imageCtx.beginPath(); 189 | 190 | // get the boundaries of the canvas 191 | const 192 | {abs, sin, cos} = Math, 193 | {width: w, height: h} = _imageCanvas, 194 | maxX = w / 2, minX = -maxX, 195 | maxY = h / 2, minY = -maxY; 196 | 197 | /** 198 | * Returns the sine and cosine of a number, as a 2-tuple. 199 | * @param {number} x 200 | * @return {[number, number]} 201 | */ 202 | const sin_cos = x => [sin(x), cos(x)]; 203 | 204 | let {x, y} = _turtle.pos; 205 | 206 | // trace out the forward steps 207 | while (distance > 0) { 208 | // move to the current location of the turtle 209 | _imageCtx.moveTo(x, y); 210 | 211 | // calculate the new location of the turtle after doing the forward movement 212 | const 213 | [sinAngle, cosAngle] = sin_cos(_turtle.angle), 214 | newX = x + sinAngle * distance, 215 | newY = y + cosAngle * distance; 216 | 217 | /** 218 | * wrap on the X boundary 219 | * @param {number} cutBound 220 | * @param {number} otherBound 221 | */ 222 | const xWrap = (cutBound, otherBound) => { 223 | const distanceToEdge = abs((cutBound - x) / sinAngle); 224 | const edgeY = cosAngle * distanceToEdge + y; 225 | _imageCtx.lineTo(cutBound, edgeY); 226 | distance -= distanceToEdge; 227 | x = otherBound; 228 | y = edgeY; 229 | }; 230 | /** 231 | * wrap on the Y boundary 232 | * @param {number} cutBound 233 | * @param {number} otherBound 234 | */ 235 | const yWrap = (cutBound, otherBound) => { 236 | const distanceToEdge = abs((cutBound - y) / cosAngle); 237 | const edgeX = sinAngle * distanceToEdge + x; 238 | _imageCtx.lineTo(edgeX, cutBound); 239 | distance -= distanceToEdge; 240 | x = edgeX; 241 | y = otherBound; 242 | }; 243 | /** don't wrap the turtle on any boundary */ 244 | const noWrap = () => { 245 | _imageCtx.lineTo(newX, newY); 246 | _turtle.pos.x = newX; 247 | _turtle.pos.y = newY; 248 | distance = 0; 249 | }; 250 | // if wrap is on, trace a part segment of the path and wrap on boundary if necessary 251 | if (_turtle.wrap) 252 | if (newX > maxX) 253 | xWrap(maxX, minX); 254 | else if (newX < minX) 255 | xWrap(minX, maxX); 256 | else if (newY > maxY) 257 | yWrap(maxY, minY); 258 | else if (newY < minY) 259 | yWrap(minY, maxY); 260 | else 261 | noWrap(); 262 | // wrap is not on. 263 | else 264 | noWrap(); 265 | } 266 | // only draw if the pen is currently down. 267 | _turtle.penDown && _imageCtx.stroke(); 268 | _imageCtx.restore(); 269 | drawIf(); 270 | }; 271 | 272 | /** 273 | * turn edge wrapping on/off 274 | * @param {boolean} b 275 | */ 276 | const wrap = b => { _turtle.wrap = b; }; 277 | 278 | const hideTurtle = () => { 279 | _turtle.visible = false; 280 | drawIf(); 281 | }; 282 | 283 | const showTurtle = () => { 284 | _turtle.visible = true; 285 | drawIf(); 286 | }; 287 | 288 | /** 289 | * turn on/off redrawing 290 | * @param {boolean} b 291 | */ 292 | const redrawOnMove = b => { _turtle.redraw = b; }; 293 | 294 | /** lift up the pen (don't draw) */ 295 | const penup = () => { _turtle.penDown = false; }; 296 | /** put the pen down (do draw) */ 297 | const pendown = () => { _turtle.penDown = true; }; 298 | 299 | /** 300 | * turn right by an angle in degrees 301 | * @param {number} angle 302 | */ 303 | const right = angle => { 304 | _turtle.angle += degToRad(angle); 305 | drawIf(); 306 | }; 307 | 308 | /** 309 | * turn left by an angle in degrees 310 | * @param {number} angle 311 | */ 312 | const left = angle => { 313 | _turtle.angle -= degToRad(angle); 314 | drawIf(); 315 | }; 316 | 317 | /** 318 | * move the turtle to a particular coordinate (don't draw on the way there) 319 | * @param {number} x 320 | * @param {number} y 321 | */ 322 | const goto = (x, y) => { 323 | _turtle.pos.x = +x; 324 | _turtle.pos.y = +y; 325 | drawIf(); 326 | }; 327 | 328 | /** 329 | * set the angle of the turtle in degrees 330 | * @param {number} a 331 | */ 332 | const angle = a => { _turtle.angle = degToRad(a); }; 333 | 334 | /** 335 | * convert degrees to radians 336 | * @param {number} deg 337 | */ 338 | const degToRad = deg => deg / 180 * Math.PI; 339 | 340 | /** 341 | * convert radians to degrees 342 | * @param {number} rad 343 | */ 344 | const radToDeg = rad => rad * 180 / Math.PI; 345 | 346 | /** 347 | * set the width of the line 348 | * @param {number} w 349 | */ 350 | const width = w => { 351 | w = +w; 352 | _turtle.width = w; 353 | _imageCtx.lineWidth = w; 354 | }; 355 | 356 | /** 357 | * write some text at the turtle position, with custom or default font. 358 | * 359 | * ideally we'd like this to rotate the text based on 360 | * the turtle orientation, but this will require some clever 361 | * canvas transformations which aren't implemented yet. 362 | * @param {string} msg 363 | */ 364 | const write = msg => { 365 | const {x, y} = _turtle.pos; 366 | 367 | _imageCtx.save(); 368 | _centerCoords(_imageCtx); 369 | 370 | //_imageCtx.rotate(turtle.angle); 371 | _imageCtx.translate(x, y); 372 | _imageCtx.transform(1, 0, 0, -1, 0, 0); 373 | _imageCtx.translate(-x, -y); 374 | 375 | _imageCtx.fillText(msg, x, y); 376 | 377 | _imageCtx.restore(); 378 | 379 | drawIf(); 380 | }; 381 | 382 | /** 383 | * set the font of the image Context 384 | * @param {string} font 385 | */ 386 | const setFont = font => { _imageCtx.font = font; }; 387 | 388 | /** 389 | * set the turtle draw shape 390 | * 391 | * currently supports triangle (default), circle, square, and turtle 392 | * @param {string} s 393 | */ 394 | const shape = s => { 395 | _turtle.shape = s; 396 | draw(); 397 | }; 398 | 399 | /** 400 | * set line color using RGB values in the range 0 - 255. 401 | * @param {number} r 402 | * @param {number} g 403 | * @param {number} b 404 | * @param {number} a alpha 405 | */ 406 | const colour = (r, g, b, a) => { 407 | r = +r; 408 | g = +g; 409 | b = +b; 410 | a = +a; 411 | 412 | _imageCtx.strokeStyle = `rgba(${r}, ${g}, ${b}, ${a})`; 413 | const c = _turtle.colour; 414 | c.r = r; 415 | c.g = g; 416 | c.b = b; 417 | c.a = a; 418 | }; 419 | const color = colour; 420 | 421 | /** 422 | * Returns a pseudo-random integer in a range 423 | * @param {number} min inclusive lower bound 424 | * @param {number} max inclusive upper bound 425 | */ 426 | const random = (min, max) => { 427 | min = +min; 428 | max = +max; 429 | 430 | return Math.floor(Math.random() * (max - min + 1) + min); 431 | }; 432 | 433 | /** 434 | * repeatedly run an "action" callback `n` times 435 | * @param {number} n integer 436 | * @param {() => never} action callback 437 | */ 438 | const repeat = (n, action) => { while (n-- > 0) action(); }; 439 | 440 | /** 441 | * `setInterval` alias, but 2-adic (no rest args) 442 | * @param {TimerHandler} f 443 | * @param {number | undefined} ms 444 | */ 445 | const animate = (f, ms) => setInterval(f, ms); 446 | 447 | /** 448 | * main program/script, mostly UI code. 449 | * 450 | * this fn is used to encapsulate private stuff that the user shouldn't access 451 | */ 452 | const _main = () => { 453 | const doc = document; 454 | 455 | /** 456 | * check if `x` is `-0`, using only operators. 457 | * to ensure correctness in ALL circumstances, it doesn't use `Object.is`, because it's mutable. 458 | * this means this fn is 100% [pure](https://en.wikipedia.org/wiki/Pure_function). 459 | * @param {*} x 460 | */ 461 | const isNegZero = x => x === 0 && 1 / x == -Infinity; 462 | 463 | /** 464 | * check if `x` matches the description of the `Uint32` namepath. 465 | * this fn is pure, by using only operators (and a fn call). 466 | * @param {*} x 467 | */ 468 | const isUint32 = x => typeof x == 'number' && x == x >>> 0 && !isNegZero(x); 469 | 470 | /** 471 | * String Queue (FIFO) to manage a history or log. 472 | * @param {Uint32} [maxSize=2**16] maximum chars to keep in memory. 473 | */ 474 | const Hist = class { 475 | // a 16bit address-space seems like a sensible default 476 | constructor(maxSize = 1 << 0x10) { 477 | // runtime type safety 478 | if ( !isUint32(maxSize) ) 479 | throw new RangeError('expected `maxSize` to be `Uint32`, but got ' + maxSize); 480 | // just-in-case 481 | if (maxSize < 2) 482 | console.warn('Max History size set to 0 or 1. This seems like an accident'); 483 | 484 | /** 485 | * max CUs to store, until at least 1 string is cleared from the queue. 486 | * @type {Uint32} 487 | */ 488 | this._maxSize = maxSize; 489 | 490 | /** 491 | * total size in memory. 492 | * measured in **code-units** (16b or 2B), not bytes (8b or 1B). 493 | * @type {Uint32} 494 | */ 495 | this._size = 0; 496 | 497 | /** 498 | * pointer to currently selected entry. 499 | * @type {Uint32} 500 | */ 501 | this._index = 0; 502 | 503 | /**@type {string[]}*/ 504 | this._entries = []; 505 | } 506 | 507 | /** returns entry at current `index`, defaults to empty `string` */ 508 | get() { return this._entries[this._index] || ''; } 509 | 510 | // both are unused, but may be handy in the future 511 | /** get latest entry, defaults to empty `string` */ 512 | newest() { return this._entries[this._entries.length - 1] || ''; } 513 | /** get earliest entry, defaults to empty `string` */ 514 | oldest() { return this._entries[0] || ''; } 515 | 516 | /** 517 | * append/push, with auto-flush 518 | * @param {string} s 519 | */ 520 | set(s) { 521 | // enqueue, then set index to newest entry 522 | this._index = this._entries.push(s); 523 | // ensure it's up-to-date, to avoid memory leaks 524 | this._size += s.length; 525 | 526 | // flush old entries 527 | while (this._size > this._maxSize) { 528 | // dequeue, then update size 529 | this._size -= /**@type {string}*/(this._entries.shift()).length; 530 | this._index--; // index correction 531 | } 532 | } 533 | 534 | /** 535 | * increment `index` by 1, clamped to `entries.length`, then return its value. 536 | * @return {Uint32} 537 | */ 538 | incIdx() { 539 | return this._index = Math.min(this._index + 1, this._entries.length); 540 | } 541 | 542 | /** 543 | * decrement `index` by 1, clamped to 0 (keeps it unsigned), then return its value. 544 | * @return {Uint32} 545 | */ 546 | decIdx() { 547 | return this._index = Math.max(this._index - 1, 0); 548 | } 549 | 550 | // also unused, but good to have available 551 | /** 552 | * set `maxSize` to a new value 553 | * @param {Uint32} n 554 | */ 555 | setMaxSize(n) { 556 | if ( !isUint32(n) ) 557 | throw new RangeError('expected `n` to be `Uint32`, but got ' + n); 558 | this._maxSize = n; 559 | } 560 | // maybe we should add a button to clear the history? 561 | }; 562 | 563 | const cmds = new Hist(1 << 20); // is this size "balanced"? 564 | 565 | const cmdBox = /**@type {HTMLInputElement}*/(doc.getElementById('command')); 566 | 567 | cmdBox.addEventListener('keydown', ({ key }) => { 568 | switch (key) { 569 | // Moves up and down in command history 570 | case 'ArrowDown': cmds.incIdx(); break; 571 | case 'ArrowUp': cmds.decIdx(); break; 572 | // call `runCmd` when user presses any "Enter" or "Return" keys 573 | case 'Enter': return runCmd(); 574 | default: return; 575 | } 576 | // external fall-through, only executed if `return` isn't touched 577 | cmdBox.value = cmds.get(); 578 | }, false); 579 | 580 | const def = /**@type {HTMLTextAreaElement}*/(doc.getElementById('definitions')); 581 | 582 | /** Executes program in the command box */ 583 | const runCmd = () => { 584 | const cmdText = cmdBox.value; 585 | cmds.set(cmdText); 586 | 587 | const definitionsText = def.value; 588 | // https://stackoverflow.com/questions/19357978/indirect-eval-call-in-strict-mode 589 | // "JS never ceases to surprise me" @Rudxain 590 | try { 591 | // execute any code in the definitions box 592 | (0, eval)(definitionsText); 593 | // execute the code in the command box 594 | (0, eval)(cmdText); 595 | } catch (e) { 596 | alert('Exception thrown:\n' + e); 597 | throw e; 598 | } finally { 599 | // clear the command box 600 | cmdBox.value = ''; 601 | } 602 | }; 603 | 604 | /** 605 | * Similar to JQuery 606 | * @param {string} id HTML element ID 607 | * @param {(this: HTMLElement, ev: MouseEvent) => unknown} cb callback 608 | */ 609 | const listenClickById = (id, cb) => doc.getElementById(id).addEventListener('click', cb); 610 | // call `runCmd` when user presses "Run" 611 | listenClickById('runButton', runCmd); 612 | listenClickById('resetButton', reset); 613 | reset(); 614 | }; 615 | 616 | _main(); 617 | --------------------------------------------------------------------------------