From 9891494d1612a9442e7305156e297c7a1c745288 Mon Sep 17 00:00:00 2001 From: Roxsy Date: Mon, 6 Feb 2023 11:25:00 -0500 Subject: [PATCH 01/12] funcion de validacion de archivos absoluta o relativa --- app.js | 94 + cli.js | 20 + index.js | 25 +- package-lock.json | 6086 +++++++++++++++++++++++++++++++++++++++++ package.json | 25 +- readme/README.md | 666 +++++ test/md-links.spec.js | 20 +- 7 files changed, 6928 insertions(+), 8 deletions(-) create mode 100644 app.js create mode 100644 cli.js create mode 100644 package-lock.json create mode 100644 readme/README.md diff --git a/app.js b/app.js new file mode 100644 index 0000000..29644ee --- /dev/null +++ b/app.js @@ -0,0 +1,94 @@ +const fs = require('fs'); +const path = require('path'); + +// regex para ver si es ruta absoluta +const regEx = /^(\/|[A-Za-z]:\\)/; +function isAbsolute(path) { + return regEx.test(path); +} +// validando si es absoluta o relativa tmb esta convirtiendo la ruta relativa a absoluta +const changeToAbsolute = (ruta) => { + if (isAbsolute(ruta)) { + return ruta; + } else { + return path.resolve(ruta); + } +} + + + +const idDirFil = (path) => { + +fs.lstat(path, (err, stats) => { + console.log("que es eto", stats); + + if (err) { + console.error(err); + } else if (stats.isDirectory()) { + + console.log('Es una carpeta',stats.isDirectory()); + } else if (stats.isFile()) { + path. + console.log('Es un archivo', stats.isFile()); + } else { + console.log('No es ni una carpeta ni un archivo'); + } + }); +} + + + + + +// esto es prueba + +/* + +const absoOurRelative = (path) => { + return new Promise((resolve, reject) => { + if (isAbsolute(path)) { + resolve(path); + } else { + resolve(path.resolve(path)); + } + }); +}; + + +const mdLinks = (path) => { + + console.log("absoluta booleano", isAbsolute(path)); + // path == relativa + return new Promise((resolve, reject) => { + // resolve => relativa al directorio desde donde se invoca node + + + // istat para saber si es una carpeta + fs.lstat(path, (err, stats) => { + if (err) { + console.error(err); + } else if (stats.isDirectory()) { + console.log('Es una carpeta'); + } else if (stats.isFile()) { + console.log('Es un archivo'); + } else { + console.log('No es ni una carpeta ni un archivo'); + } + }); + + + // funcion - chequear o convertir una ruta absoluta + // probar si esa ruta absoluta es una archivo o directorio + // Si es un directorio filtrar los archivos md. arry filtrado + + + + }) +} */ + + + +module.exports = { + changeToAbsolute, idDirFil, checkPath + +}; \ No newline at end of file diff --git a/cli.js b/cli.js new file mode 100644 index 0000000..44c8a90 --- /dev/null +++ b/cli.js @@ -0,0 +1,20 @@ +const { mdLinks } = require('./index.js'); + +mdLinks('./node_modules') + +.then(() => { + mdLinks => console.log(mdLinks) +}) +.catch((error) => { + console.log(error) +}) + +/*absoOurRelative('./README.md') +.then(() => { + absoOurRelative => console.log(absoOurRelative) + +}) +.catch((error) => { + error => console.error(error) +})*/ + diff --git a/index.js b/index.js index a4e4a45..7c9be38 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,22 @@ -module.exports = () => { - // ... -}; +const { pathAbsolute, changeToAbsolute, idDirFil,checkPath } = require('./app') +const fs = require("fs"); +const path = require("path"); + +const mdLinks = (path, options) => { + return new Promise((resolve, reject) => { + + + if(fs.existsSync(path)){ + console.log(" dino q es",changeToAbsolute(path)) + console.log(" que s",idDirFil(path)); + console.log("klear 2", checkPath(path)); + + + } else { + reject("la ruta no existe") + } + }) +} +module.exports = { + mdLinks +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..1a976ae --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6086 @@ +{ + "name": "rvq_md-links", + "version": "0.1.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "rvq_md-links", + "version": "0.1.0", + "license": "ISC", + "devDependencies": { + "jest": "^29.4.1" + }, + "engines": { + "node": ">=16.x" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.20.14", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.14.tgz", + "integrity": "sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", + "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.12", + "@babel/types": "^7.20.7", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/@babel/generator": { + "version": "7.20.14", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz", + "integrity": "sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "dev": true, + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", + "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.10", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.13.tgz", + "integrity": "sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.13", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.20.15", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.15.tgz", + "integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz", + "integrity": "sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.13", + "@babel/types": "^7.20.7", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.4.1.tgz", + "integrity": "sha512-m+XpwKSi3PPM9znm5NGS8bBReeAJJpSkL1OuFCqaMaJL2YX9YXLkkI+MBchMPwu+ZuM2rynL51sgfkQteQ1CKQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.4.1", + "jest-util": "^29.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.4.1.tgz", + "integrity": "sha512-RXFTohpBqpaTebNdg5l3I5yadnKo9zLBajMT0I38D0tDhreVBYv3fA8kywthI00sWxPztWLD3yjiUkewwu/wKA==", + "dev": true, + "dependencies": { + "@jest/console": "^29.4.1", + "@jest/reporters": "^29.4.1", + "@jest/test-result": "^29.4.1", + "@jest/transform": "^29.4.1", + "@jest/types": "^29.4.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.4.0", + "jest-config": "^29.4.1", + "jest-haste-map": "^29.4.1", + "jest-message-util": "^29.4.1", + "jest-regex-util": "^29.2.0", + "jest-resolve": "^29.4.1", + "jest-resolve-dependencies": "^29.4.1", + "jest-runner": "^29.4.1", + "jest-runtime": "^29.4.1", + "jest-snapshot": "^29.4.1", + "jest-util": "^29.4.1", + "jest-validate": "^29.4.1", + "jest-watcher": "^29.4.1", + "micromatch": "^4.0.4", + "pretty-format": "^29.4.1", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.4.1.tgz", + "integrity": "sha512-pJ14dHGSQke7Q3mkL/UZR9ZtTOxqskZaC91NzamEH4dlKRt42W+maRBXiw/LWkdJe+P0f/zDR37+SPMplMRlPg==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^29.4.1", + "@jest/types": "^29.4.1", + "@types/node": "*", + "jest-mock": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.4.1.tgz", + "integrity": "sha512-ZxKJP5DTUNF2XkpJeZIzvnzF1KkfrhEF6Rz0HGG69fHl6Bgx5/GoU3XyaeFYEjuuKSOOsbqD/k72wFvFxc3iTw==", + "dev": true, + "dependencies": { + "expect": "^29.4.1", + "jest-snapshot": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.4.1.tgz", + "integrity": "sha512-w6YJMn5DlzmxjO00i9wu2YSozUYRBhIoJ6nQwpMYcBMtiqMGJm1QBzOf6DDgRao8dbtpDoaqLg6iiQTvv0UHhQ==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.2.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.4.1.tgz", + "integrity": "sha512-/1joI6rfHFmmm39JxNfmNAO3Nwm6Y0VoL5fJDy7H1AtWrD1CgRtqJbN9Ld6rhAkGO76qqp4cwhhxJ9o9kYjQMw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.1", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.4.1", + "jest-mock": "^29.4.1", + "jest-util": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.4.1.tgz", + "integrity": "sha512-znoK2EuFytbHH0ZSf2mQK2K1xtIgmaw4Da21R2C/NE/+NnItm5mPEFQmn8gmF3f0rfOlmZ3Y3bIf7bFj7DHxAA==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.4.1", + "@jest/expect": "^29.4.1", + "@jest/types": "^29.4.1", + "jest-mock": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.4.1.tgz", + "integrity": "sha512-AISY5xpt2Xpxj9R6y0RF1+O6GRy9JsGa8+vK23Lmzdy1AYcpQn5ItX79wJSsTmfzPKSAcsY1LNt/8Y5Xe5LOSg==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.4.1", + "@jest/test-result": "^29.4.1", + "@jest/transform": "^29.4.1", + "@jest/types": "^29.4.1", + "@jridgewell/trace-mapping": "^0.3.15", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.4.1", + "jest-util": "^29.4.1", + "jest-worker": "^29.4.1", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.0.tgz", + "integrity": "sha512-0E01f/gOZeNTG76i5eWWSupvSHaIINrTie7vCyjiYFKgzNdyEGd12BUv4oNBFHOqlHDbtoJi3HrQ38KCC90NsQ==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.25.16" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.2.0.tgz", + "integrity": "sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.15", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.4.1.tgz", + "integrity": "sha512-WRt29Lwt+hEgfN8QDrXqXGgCTidq1rLyFqmZ4lmJOpVArC8daXrZWkWjiaijQvgd3aOUj2fM8INclKHsQW9YyQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.4.1", + "@jest/types": "^29.4.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.4.1.tgz", + "integrity": "sha512-v5qLBNSsM0eHzWLXsQ5fiB65xi49A3ILPSFQKPXzGL4Vyux0DPZAIN7NAFJa9b4BiTDP9MBF/Zqc/QA1vuiJ0w==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.4.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.4.1.tgz", + "integrity": "sha512-5w6YJrVAtiAgr0phzKjYd83UPbCXsBRTeYI4BXokv9Er9CcrH9hfXL/crCvP2d2nGOcovPUnlYiLPFLZrkG5Hg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.4.1", + "@jridgewell/trace-mapping": "^0.3.15", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.4.1", + "jest-regex-util": "^29.2.0", + "jest-util": "^29.4.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^5.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.1.tgz", + "integrity": "sha512-zbrAXDUOnpJ+FMST2rV7QZOgec8rskg2zv8g2ajeqitp4tvZiyqTCYXANrKsM+ryj5o+LI+ZN2EgU9drrkiwSA==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.4.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.25.21", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", + "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "dev": true + }, + "node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", + "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.3.0" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/node": { + "version": "18.11.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", + "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", + "dev": true + }, + "node_modules/@types/prettier": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", + "dev": true + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.22", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.22.tgz", + "integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/babel-jest": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.4.1.tgz", + "integrity": "sha512-xBZa/pLSsF/1sNpkgsiT3CmY7zV1kAsZ9OxxtrFqYucnOuRftXAfcJqcDVyOPeN4lttWTwhLdu0T9f8uvoPEUg==", + "dev": true, + "dependencies": { + "@jest/transform": "^29.4.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.4.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.4.0.tgz", + "integrity": "sha512-a/sZRLQJEmsmejQ2rPEUe35nO1+C9dc9O1gplH1SXmJxveQSRUYdBk8yGZG/VOUuZs1u2aHZJusEGoRMbhhwCg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.4.0.tgz", + "integrity": "sha512-fUB9vZflUSM3dO/6M2TCAepTzvA4VkOvl67PjErcrQMGt9Eve7uazaeyCZ2th3UtI7ljpiBJES0F7A1vBRsLZA==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.4.0", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001450", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001450.tgz", + "integrity": "sha512-qMBmvmQmFXaSxexkjjfMvD5rnDL0+m+dUMZKoDYsGG8iZN29RuYh9eRoMvKsT6uMAWlyUUGDEQGJJYjzCIO9ew==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.1.tgz", + "integrity": "sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "dev": true + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.0.tgz", + "integrity": "sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff-sequences": { + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz", + "integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.285", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.285.tgz", + "integrity": "sha512-47o4PPgxfU1KMNejz+Dgaodf7YTcg48uOfV1oM6cs3adrl2+7R+dHkt3Jpxqo0LRCbGJEzTKMUt0RdvByb/leg==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.4.1.tgz", + "integrity": "sha512-OKrGESHOaMxK3b6zxIq9SOW8kEXztKff/Dvg88j4xIJxur1hspEbedVkR3GpHe5LO+WB2Qw7OWN0RMTdp6as5A==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.4.1", + "jest-get-type": "^29.2.0", + "jest-matcher-utils": "^29.4.1", + "jest-message-util": "^29.4.1", + "jest-util": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.4.1.tgz", + "integrity": "sha512-cknimw7gAXPDOmj0QqztlxVtBVCw2lYY9CeIE5N6kD+kET1H4H79HSNISJmijb1HF+qk+G+ploJgiDi5k/fRlg==", + "dev": true, + "dependencies": { + "@jest/core": "^29.4.1", + "@jest/types": "^29.4.1", + "import-local": "^3.0.2", + "jest-cli": "^29.4.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.4.0.tgz", + "integrity": "sha512-rnI1oPxgFghoz32Y8eZsGJMjW54UlqT17ycQeCEktcxxwqqKdlj9afl8LNeO0Pbu+h2JQHThQP0BzS67eTRx4w==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.4.1.tgz", + "integrity": "sha512-v02NuL5crMNY4CGPHBEflLzl4v91NFb85a+dH9a1pUNx6Xjggrd8l9pPy4LZ1VYNRXlb+f65+7O/MSIbLir6pA==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.4.1", + "@jest/expect": "^29.4.1", + "@jest/test-result": "^29.4.1", + "@jest/types": "^29.4.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.4.1", + "jest-matcher-utils": "^29.4.1", + "jest-message-util": "^29.4.1", + "jest-runtime": "^29.4.1", + "jest-snapshot": "^29.4.1", + "jest-util": "^29.4.1", + "p-limit": "^3.1.0", + "pretty-format": "^29.4.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.4.1.tgz", + "integrity": "sha512-jz7GDIhtxQ37M+9dlbv5K+/FVcIo1O/b1sX3cJgzlQUf/3VG25nvuWzlDC4F1FLLzUThJeWLu8I7JF9eWpuURQ==", + "dev": true, + "dependencies": { + "@jest/core": "^29.4.1", + "@jest/test-result": "^29.4.1", + "@jest/types": "^29.4.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^29.4.1", + "jest-util": "^29.4.1", + "jest-validate": "^29.4.1", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.4.1.tgz", + "integrity": "sha512-g7p3q4NuXiM4hrS4XFATTkd+2z0Ml2RhFmFPM8c3WyKwVDNszbl4E7cV7WIx1YZeqqCtqbtTtZhGZWJlJqngzg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.4.1", + "@jest/types": "^29.4.1", + "babel-jest": "^29.4.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.4.1", + "jest-environment-node": "^29.4.1", + "jest-get-type": "^29.2.0", + "jest-regex-util": "^29.2.0", + "jest-resolve": "^29.4.1", + "jest-runner": "^29.4.1", + "jest-util": "^29.4.1", + "jest-validate": "^29.4.1", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.4.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.1.tgz", + "integrity": "sha512-uazdl2g331iY56CEyfbNA0Ut7Mn2ulAG5vUaEHXycf1L6IPyuImIxSz4F0VYBKi7LYIuxOwTZzK3wh5jHzASMw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.3.1", + "jest-get-type": "^29.2.0", + "pretty-format": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.2.0.tgz", + "integrity": "sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.4.1.tgz", + "integrity": "sha512-QlYFiX3llJMWUV0BtWht/esGEz9w+0i7BHwODKCze7YzZzizgExB9MOfiivF/vVT0GSQ8wXLhvHXh3x2fVD4QQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.1", + "chalk": "^4.0.0", + "jest-get-type": "^29.2.0", + "jest-util": "^29.4.1", + "pretty-format": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.4.1.tgz", + "integrity": "sha512-x/H2kdVgxSkxWAIlIh9MfMuBa0hZySmfsC5lCsWmWr6tZySP44ediRKDUiNggX/eHLH7Cd5ZN10Rw+XF5tXsqg==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.4.1", + "@jest/fake-timers": "^29.4.1", + "@jest/types": "^29.4.1", + "@types/node": "*", + "jest-mock": "^29.4.1", + "jest-util": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz", + "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.4.1.tgz", + "integrity": "sha512-imTjcgfVVTvg02khXL11NNLTx9ZaofbAWhilrMg/G8dIkp+HYCswhxf0xxJwBkfhWb3e8dwbjuWburvxmcr58w==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.1", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.2.0", + "jest-util": "^29.4.1", + "jest-worker": "^29.4.1", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.4.1.tgz", + "integrity": "sha512-akpZv7TPyGMnH2RimOCgy+hPmWZf55EyFUvymQ4LMsQP8xSPlZumCPtXGoDhFNhUE2039RApZkTQDKU79p/FiQ==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.2.0", + "pretty-format": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.1.tgz", + "integrity": "sha512-k5h0u8V4nAEy6lSACepxL/rw78FLDkBnXhZVgFneVpnJONhb2DhZj/Gv4eNe+1XqQ5IhgUcqj745UwH0HJmMnA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.4.1", + "jest-get-type": "^29.2.0", + "pretty-format": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.1.tgz", + "integrity": "sha512-H4/I0cXUaLeCw6FM+i4AwCnOwHRgitdaUFOdm49022YD5nfyr8C/DrbXOBEyJaj+w/y0gGJ57klssOaUiLLQGQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.4.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.4.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.4.1.tgz", + "integrity": "sha512-MwA4hQ7zBOcgVCVnsM8TzaFLVUD/pFWTfbkY953Y81L5ret3GFRZtmPmRFAjKQSdCKoJvvqOu6Bvfpqlwwb0dQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.1", + "@types/node": "*", + "jest-util": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.2.0.tgz", + "integrity": "sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.4.1.tgz", + "integrity": "sha512-j/ZFNV2lm9IJ2wmlq1uYK0Y/1PiyDq9g4HEGsNTNr3viRbJdV+8Lf1SXIiLZXFvyiisu0qUyIXGBnw+OKWkJwQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.4.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.4.1", + "jest-validate": "^29.4.1", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.4.1.tgz", + "integrity": "sha512-Y3QG3M1ncAMxfjbYgtqNXC5B595zmB6e//p/qpA/58JkQXu/IpLDoLeOa8YoYfsSglBKQQzNUqtfGJJT/qLmJg==", + "dev": true, + "dependencies": { + "jest-regex-util": "^29.2.0", + "jest-snapshot": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.4.1.tgz", + "integrity": "sha512-8d6XXXi7GtHmsHrnaqBKWxjKb166Eyj/ksSaUYdcBK09VbjPwIgWov1VwSmtupCIz8q1Xv4Qkzt/BTo3ZqiCeg==", + "dev": true, + "dependencies": { + "@jest/console": "^29.4.1", + "@jest/environment": "^29.4.1", + "@jest/test-result": "^29.4.1", + "@jest/transform": "^29.4.1", + "@jest/types": "^29.4.1", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.2.0", + "jest-environment-node": "^29.4.1", + "jest-haste-map": "^29.4.1", + "jest-leak-detector": "^29.4.1", + "jest-message-util": "^29.4.1", + "jest-resolve": "^29.4.1", + "jest-runtime": "^29.4.1", + "jest-util": "^29.4.1", + "jest-watcher": "^29.4.1", + "jest-worker": "^29.4.1", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.4.1.tgz", + "integrity": "sha512-UXTMU9uKu2GjYwTtoAw5rn4STxWw/nadOfW7v1sx6LaJYa3V/iymdCLQM6xy3+7C6mY8GfX22vKpgxY171UIoA==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.4.1", + "@jest/fake-timers": "^29.4.1", + "@jest/globals": "^29.4.1", + "@jest/source-map": "^29.2.0", + "@jest/test-result": "^29.4.1", + "@jest/transform": "^29.4.1", + "@jest/types": "^29.4.1", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.4.1", + "jest-message-util": "^29.4.1", + "jest-mock": "^29.4.1", + "jest-regex-util": "^29.2.0", + "jest-resolve": "^29.4.1", + "jest-snapshot": "^29.4.1", + "jest-util": "^29.4.1", + "semver": "^7.3.5", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-runtime/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-runtime/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/jest-snapshot": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.4.1.tgz", + "integrity": "sha512-l4iV8EjGgQWVz3ee/LR9sULDk2pCkqb71bjvlqn+qp90lFwpnulHj4ZBT8nm1hA1C5wowXLc7MGnw321u0tsYA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.4.1", + "@jest/transform": "^29.4.1", + "@jest/types": "^29.4.1", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.4.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.4.1", + "jest-get-type": "^29.2.0", + "jest-haste-map": "^29.4.1", + "jest-matcher-utils": "^29.4.1", + "jest-message-util": "^29.4.1", + "jest-util": "^29.4.1", + "natural-compare": "^1.4.0", + "pretty-format": "^29.4.1", + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/jest-util": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.1.tgz", + "integrity": "sha512-bQy9FPGxVutgpN4VRc0hk6w7Hx/m6L53QxpDreTZgJd9gfx/AV2MjyPde9tGyZRINAUrSv57p2inGBu2dRLmkQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.4.1.tgz", + "integrity": "sha512-qNZXcZQdIQx4SfUB/atWnI4/I2HUvhz8ajOSYUu40CSmf9U5emil8EDHgE7M+3j9/pavtk3knlZBDsgFvv/SWw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.1", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.2.0", + "leven": "^3.1.0", + "pretty-format": "^29.4.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.4.1.tgz", + "integrity": "sha512-vFOzflGFs27nU6h8dpnVRER3O2rFtL+VMEwnG0H3KLHcllLsU8y9DchSh0AL/Rg5nN1/wSiQ+P4ByMGpuybaVw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.4.1", + "@jest/types": "^29.4.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.4.1", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.4.1.tgz", + "integrity": "sha512-O9doU/S1EBe+yp/mstQ0VpPwpv0Clgn68TkNwGxL6/usX/KUW9Arnn4ag8C3jc6qHcXznhsT5Na1liYzAsuAbQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.4.1", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.9.tgz", + "integrity": "sha512-2xfmOrRkGogbTK9R6Leda0DGiXeY3p2NJpy4+gNCffdUvV6mdEJnaDEic1i3Ec2djAo8jWYoJMR5PB0MSMpxUA==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pretty-format": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.1.tgz", + "integrity": "sha512-dt/Z761JUVsrIKaY215o1xQJBGlSmTx/h4cSqXqjHLnU1+Kt+mavVE7UgqJJO5ukx5HjSswHfmXz4LjS2oIJfg==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.4.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.0.tgz", + "integrity": "sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", + "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.0.tgz", + "integrity": "sha512-R7NYMnHSlV42K54lwY9lvW6MnSm1HSJqZL3xiSgi9E7//FYaI74r2G0rd+/X6VAMkHEdzxQaU5HUOXWUz5kA/w==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dev": true, + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "@babel/compat-data": { + "version": "7.20.14", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.14.tgz", + "integrity": "sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==", + "dev": true + }, + "@babel/core": { + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", + "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.12", + "@babel/types": "^7.20.7", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" + }, + "dependencies": { + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.20.14", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz", + "integrity": "sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==", + "dev": true, + "requires": { + "@babel/types": "^7.20.7", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } + } + }, + "@babel/helper-compilation-targets": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "dev": true + }, + "@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "dev": true, + "requires": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-transforms": { + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", + "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.10", + "@babel/types": "^7.20.7" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "dev": true + }, + "@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "dev": true, + "requires": { + "@babel/types": "^7.20.2" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.13.tgz", + "integrity": "sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==", + "dev": true, + "requires": { + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.13", + "@babel/types": "^7.20.7" + } + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.20.15", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.15.tgz", + "integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==", + "dev": true + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.19.0" + } + }, + "@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + } + }, + "@babel/traverse": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz", + "integrity": "sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.13", + "@babel/types": "^7.20.7", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@jest/console": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.4.1.tgz", + "integrity": "sha512-m+XpwKSi3PPM9znm5NGS8bBReeAJJpSkL1OuFCqaMaJL2YX9YXLkkI+MBchMPwu+ZuM2rynL51sgfkQteQ1CKQ==", + "dev": true, + "requires": { + "@jest/types": "^29.4.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.4.1", + "jest-util": "^29.4.1", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.4.1.tgz", + "integrity": "sha512-RXFTohpBqpaTebNdg5l3I5yadnKo9zLBajMT0I38D0tDhreVBYv3fA8kywthI00sWxPztWLD3yjiUkewwu/wKA==", + "dev": true, + "requires": { + "@jest/console": "^29.4.1", + "@jest/reporters": "^29.4.1", + "@jest/test-result": "^29.4.1", + "@jest/transform": "^29.4.1", + "@jest/types": "^29.4.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.4.0", + "jest-config": "^29.4.1", + "jest-haste-map": "^29.4.1", + "jest-message-util": "^29.4.1", + "jest-regex-util": "^29.2.0", + "jest-resolve": "^29.4.1", + "jest-resolve-dependencies": "^29.4.1", + "jest-runner": "^29.4.1", + "jest-runtime": "^29.4.1", + "jest-snapshot": "^29.4.1", + "jest-util": "^29.4.1", + "jest-validate": "^29.4.1", + "jest-watcher": "^29.4.1", + "micromatch": "^4.0.4", + "pretty-format": "^29.4.1", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "@jest/environment": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.4.1.tgz", + "integrity": "sha512-pJ14dHGSQke7Q3mkL/UZR9ZtTOxqskZaC91NzamEH4dlKRt42W+maRBXiw/LWkdJe+P0f/zDR37+SPMplMRlPg==", + "dev": true, + "requires": { + "@jest/fake-timers": "^29.4.1", + "@jest/types": "^29.4.1", + "@types/node": "*", + "jest-mock": "^29.4.1" + } + }, + "@jest/expect": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.4.1.tgz", + "integrity": "sha512-ZxKJP5DTUNF2XkpJeZIzvnzF1KkfrhEF6Rz0HGG69fHl6Bgx5/GoU3XyaeFYEjuuKSOOsbqD/k72wFvFxc3iTw==", + "dev": true, + "requires": { + "expect": "^29.4.1", + "jest-snapshot": "^29.4.1" + } + }, + "@jest/expect-utils": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.4.1.tgz", + "integrity": "sha512-w6YJMn5DlzmxjO00i9wu2YSozUYRBhIoJ6nQwpMYcBMtiqMGJm1QBzOf6DDgRao8dbtpDoaqLg6iiQTvv0UHhQ==", + "dev": true, + "requires": { + "jest-get-type": "^29.2.0" + } + }, + "@jest/fake-timers": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.4.1.tgz", + "integrity": "sha512-/1joI6rfHFmmm39JxNfmNAO3Nwm6Y0VoL5fJDy7H1AtWrD1CgRtqJbN9Ld6rhAkGO76qqp4cwhhxJ9o9kYjQMw==", + "dev": true, + "requires": { + "@jest/types": "^29.4.1", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.4.1", + "jest-mock": "^29.4.1", + "jest-util": "^29.4.1" + } + }, + "@jest/globals": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.4.1.tgz", + "integrity": "sha512-znoK2EuFytbHH0ZSf2mQK2K1xtIgmaw4Da21R2C/NE/+NnItm5mPEFQmn8gmF3f0rfOlmZ3Y3bIf7bFj7DHxAA==", + "dev": true, + "requires": { + "@jest/environment": "^29.4.1", + "@jest/expect": "^29.4.1", + "@jest/types": "^29.4.1", + "jest-mock": "^29.4.1" + } + }, + "@jest/reporters": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.4.1.tgz", + "integrity": "sha512-AISY5xpt2Xpxj9R6y0RF1+O6GRy9JsGa8+vK23Lmzdy1AYcpQn5ItX79wJSsTmfzPKSAcsY1LNt/8Y5Xe5LOSg==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.4.1", + "@jest/test-result": "^29.4.1", + "@jest/transform": "^29.4.1", + "@jest/types": "^29.4.1", + "@jridgewell/trace-mapping": "^0.3.15", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.4.1", + "jest-util": "^29.4.1", + "jest-worker": "^29.4.1", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + } + }, + "@jest/schemas": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.0.tgz", + "integrity": "sha512-0E01f/gOZeNTG76i5eWWSupvSHaIINrTie7vCyjiYFKgzNdyEGd12BUv4oNBFHOqlHDbtoJi3HrQ38KCC90NsQ==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.25.16" + } + }, + "@jest/source-map": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.2.0.tgz", + "integrity": "sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.15", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + } + }, + "@jest/test-result": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.4.1.tgz", + "integrity": "sha512-WRt29Lwt+hEgfN8QDrXqXGgCTidq1rLyFqmZ4lmJOpVArC8daXrZWkWjiaijQvgd3aOUj2fM8INclKHsQW9YyQ==", + "dev": true, + "requires": { + "@jest/console": "^29.4.1", + "@jest/types": "^29.4.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.4.1.tgz", + "integrity": "sha512-v5qLBNSsM0eHzWLXsQ5fiB65xi49A3ILPSFQKPXzGL4Vyux0DPZAIN7NAFJa9b4BiTDP9MBF/Zqc/QA1vuiJ0w==", + "dev": true, + "requires": { + "@jest/test-result": "^29.4.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.4.1", + "slash": "^3.0.0" + } + }, + "@jest/transform": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.4.1.tgz", + "integrity": "sha512-5w6YJrVAtiAgr0phzKjYd83UPbCXsBRTeYI4BXokv9Er9CcrH9hfXL/crCvP2d2nGOcovPUnlYiLPFLZrkG5Hg==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.4.1", + "@jridgewell/trace-mapping": "^0.3.15", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.4.1", + "jest-regex-util": "^29.2.0", + "jest-util": "^29.4.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^5.0.0" + } + }, + "@jest/types": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.1.tgz", + "integrity": "sha512-zbrAXDUOnpJ+FMST2rV7QZOgec8rskg2zv8g2ajeqitp4tvZiyqTCYXANrKsM+ryj5o+LI+ZN2EgU9drrkiwSA==", + "dev": true, + "requires": { + "@jest/schemas": "^29.4.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "@sinclair/typebox": { + "version": "0.25.21", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", + "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "dev": true + }, + "@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^2.0.0" + } + }, + "@types/babel__core": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", + "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", + "dev": true, + "requires": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/node": { + "version": "18.11.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", + "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", + "dev": true + }, + "@types/prettier": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", + "dev": true + }, + "@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "@types/yargs": { + "version": "17.0.22", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.22.tgz", + "integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "babel-jest": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.4.1.tgz", + "integrity": "sha512-xBZa/pLSsF/1sNpkgsiT3CmY7zV1kAsZ9OxxtrFqYucnOuRftXAfcJqcDVyOPeN4lttWTwhLdu0T9f8uvoPEUg==", + "dev": true, + "requires": { + "@jest/transform": "^29.4.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.4.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.4.0.tgz", + "integrity": "sha512-a/sZRLQJEmsmejQ2rPEUe35nO1+C9dc9O1gplH1SXmJxveQSRUYdBk8yGZG/VOUuZs1u2aHZJusEGoRMbhhwCg==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.4.0.tgz", + "integrity": "sha512-fUB9vZflUSM3dO/6M2TCAepTzvA4VkOvl67PjErcrQMGt9Eve7uazaeyCZ2th3UtI7ljpiBJES0F7A1vBRsLZA==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^29.4.0", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browserslist": { + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001450", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001450.tgz", + "integrity": "sha512-qMBmvmQmFXaSxexkjjfMvD5rnDL0+m+dUMZKoDYsGG8iZN29RuYh9eRoMvKsT6uMAWlyUUGDEQGJJYjzCIO9ew==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true + }, + "ci-info": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.1.tgz", + "integrity": "sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w==", + "dev": true + }, + "cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "dev": true + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true + }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true + }, + "deepmerge": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.0.tgz", + "integrity": "sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==", + "dev": true + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true + }, + "diff-sequences": { + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz", + "integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.4.285", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.285.tgz", + "integrity": "sha512-47o4PPgxfU1KMNejz+Dgaodf7YTcg48uOfV1oM6cs3adrl2+7R+dHkt3Jpxqo0LRCbGJEzTKMUt0RdvByb/leg==", + "dev": true + }, + "emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true + }, + "expect": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.4.1.tgz", + "integrity": "sha512-OKrGESHOaMxK3b6zxIq9SOW8kEXztKff/Dvg88j4xIJxur1hspEbedVkR3GpHe5LO+WB2Qw7OWN0RMTdp6as5A==", + "dev": true, + "requires": { + "@jest/expect-utils": "^29.4.1", + "jest-get-type": "^29.2.0", + "jest-matcher-utils": "^29.4.1", + "jest-message-util": "^29.4.1", + "jest-util": "^29.4.1" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.4.1.tgz", + "integrity": "sha512-cknimw7gAXPDOmj0QqztlxVtBVCw2lYY9CeIE5N6kD+kET1H4H79HSNISJmijb1HF+qk+G+ploJgiDi5k/fRlg==", + "dev": true, + "requires": { + "@jest/core": "^29.4.1", + "@jest/types": "^29.4.1", + "import-local": "^3.0.2", + "jest-cli": "^29.4.1" + } + }, + "jest-changed-files": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.4.0.tgz", + "integrity": "sha512-rnI1oPxgFghoz32Y8eZsGJMjW54UlqT17ycQeCEktcxxwqqKdlj9afl8LNeO0Pbu+h2JQHThQP0BzS67eTRx4w==", + "dev": true, + "requires": { + "execa": "^5.0.0", + "p-limit": "^3.1.0" + } + }, + "jest-circus": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.4.1.tgz", + "integrity": "sha512-v02NuL5crMNY4CGPHBEflLzl4v91NFb85a+dH9a1pUNx6Xjggrd8l9pPy4LZ1VYNRXlb+f65+7O/MSIbLir6pA==", + "dev": true, + "requires": { + "@jest/environment": "^29.4.1", + "@jest/expect": "^29.4.1", + "@jest/test-result": "^29.4.1", + "@jest/types": "^29.4.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.4.1", + "jest-matcher-utils": "^29.4.1", + "jest-message-util": "^29.4.1", + "jest-runtime": "^29.4.1", + "jest-snapshot": "^29.4.1", + "jest-util": "^29.4.1", + "p-limit": "^3.1.0", + "pretty-format": "^29.4.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-cli": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.4.1.tgz", + "integrity": "sha512-jz7GDIhtxQ37M+9dlbv5K+/FVcIo1O/b1sX3cJgzlQUf/3VG25nvuWzlDC4F1FLLzUThJeWLu8I7JF9eWpuURQ==", + "dev": true, + "requires": { + "@jest/core": "^29.4.1", + "@jest/test-result": "^29.4.1", + "@jest/types": "^29.4.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^29.4.1", + "jest-util": "^29.4.1", + "jest-validate": "^29.4.1", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + } + }, + "jest-config": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.4.1.tgz", + "integrity": "sha512-g7p3q4NuXiM4hrS4XFATTkd+2z0Ml2RhFmFPM8c3WyKwVDNszbl4E7cV7WIx1YZeqqCtqbtTtZhGZWJlJqngzg==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.4.1", + "@jest/types": "^29.4.1", + "babel-jest": "^29.4.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.4.1", + "jest-environment-node": "^29.4.1", + "jest-get-type": "^29.2.0", + "jest-regex-util": "^29.2.0", + "jest-resolve": "^29.4.1", + "jest-runner": "^29.4.1", + "jest-util": "^29.4.1", + "jest-validate": "^29.4.1", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.4.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + } + }, + "jest-diff": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.1.tgz", + "integrity": "sha512-uazdl2g331iY56CEyfbNA0Ut7Mn2ulAG5vUaEHXycf1L6IPyuImIxSz4F0VYBKi7LYIuxOwTZzK3wh5jHzASMw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^29.3.1", + "jest-get-type": "^29.2.0", + "pretty-format": "^29.4.1" + } + }, + "jest-docblock": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.2.0.tgz", + "integrity": "sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.4.1.tgz", + "integrity": "sha512-QlYFiX3llJMWUV0BtWht/esGEz9w+0i7BHwODKCze7YzZzizgExB9MOfiivF/vVT0GSQ8wXLhvHXh3x2fVD4QQ==", + "dev": true, + "requires": { + "@jest/types": "^29.4.1", + "chalk": "^4.0.0", + "jest-get-type": "^29.2.0", + "jest-util": "^29.4.1", + "pretty-format": "^29.4.1" + } + }, + "jest-environment-node": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.4.1.tgz", + "integrity": "sha512-x/H2kdVgxSkxWAIlIh9MfMuBa0hZySmfsC5lCsWmWr6tZySP44ediRKDUiNggX/eHLH7Cd5ZN10Rw+XF5tXsqg==", + "dev": true, + "requires": { + "@jest/environment": "^29.4.1", + "@jest/fake-timers": "^29.4.1", + "@jest/types": "^29.4.1", + "@types/node": "*", + "jest-mock": "^29.4.1", + "jest-util": "^29.4.1" + } + }, + "jest-get-type": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz", + "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==", + "dev": true + }, + "jest-haste-map": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.4.1.tgz", + "integrity": "sha512-imTjcgfVVTvg02khXL11NNLTx9ZaofbAWhilrMg/G8dIkp+HYCswhxf0xxJwBkfhWb3e8dwbjuWburvxmcr58w==", + "dev": true, + "requires": { + "@jest/types": "^29.4.1", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.2.0", + "jest-util": "^29.4.1", + "jest-worker": "^29.4.1", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + } + }, + "jest-leak-detector": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.4.1.tgz", + "integrity": "sha512-akpZv7TPyGMnH2RimOCgy+hPmWZf55EyFUvymQ4LMsQP8xSPlZumCPtXGoDhFNhUE2039RApZkTQDKU79p/FiQ==", + "dev": true, + "requires": { + "jest-get-type": "^29.2.0", + "pretty-format": "^29.4.1" + } + }, + "jest-matcher-utils": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.1.tgz", + "integrity": "sha512-k5h0u8V4nAEy6lSACepxL/rw78FLDkBnXhZVgFneVpnJONhb2DhZj/Gv4eNe+1XqQ5IhgUcqj745UwH0HJmMnA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^29.4.1", + "jest-get-type": "^29.2.0", + "pretty-format": "^29.4.1" + } + }, + "jest-message-util": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.1.tgz", + "integrity": "sha512-H4/I0cXUaLeCw6FM+i4AwCnOwHRgitdaUFOdm49022YD5nfyr8C/DrbXOBEyJaj+w/y0gGJ57klssOaUiLLQGQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.4.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.4.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-mock": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.4.1.tgz", + "integrity": "sha512-MwA4hQ7zBOcgVCVnsM8TzaFLVUD/pFWTfbkY953Y81L5ret3GFRZtmPmRFAjKQSdCKoJvvqOu6Bvfpqlwwb0dQ==", + "dev": true, + "requires": { + "@jest/types": "^29.4.1", + "@types/node": "*", + "jest-util": "^29.4.1" + } + }, + "jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "requires": {} + }, + "jest-regex-util": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.2.0.tgz", + "integrity": "sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==", + "dev": true + }, + "jest-resolve": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.4.1.tgz", + "integrity": "sha512-j/ZFNV2lm9IJ2wmlq1uYK0Y/1PiyDq9g4HEGsNTNr3viRbJdV+8Lf1SXIiLZXFvyiisu0qUyIXGBnw+OKWkJwQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.4.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.4.1", + "jest-validate": "^29.4.1", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.4.1.tgz", + "integrity": "sha512-Y3QG3M1ncAMxfjbYgtqNXC5B595zmB6e//p/qpA/58JkQXu/IpLDoLeOa8YoYfsSglBKQQzNUqtfGJJT/qLmJg==", + "dev": true, + "requires": { + "jest-regex-util": "^29.2.0", + "jest-snapshot": "^29.4.1" + } + }, + "jest-runner": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.4.1.tgz", + "integrity": "sha512-8d6XXXi7GtHmsHrnaqBKWxjKb166Eyj/ksSaUYdcBK09VbjPwIgWov1VwSmtupCIz8q1Xv4Qkzt/BTo3ZqiCeg==", + "dev": true, + "requires": { + "@jest/console": "^29.4.1", + "@jest/environment": "^29.4.1", + "@jest/test-result": "^29.4.1", + "@jest/transform": "^29.4.1", + "@jest/types": "^29.4.1", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.2.0", + "jest-environment-node": "^29.4.1", + "jest-haste-map": "^29.4.1", + "jest-leak-detector": "^29.4.1", + "jest-message-util": "^29.4.1", + "jest-resolve": "^29.4.1", + "jest-runtime": "^29.4.1", + "jest-util": "^29.4.1", + "jest-watcher": "^29.4.1", + "jest-worker": "^29.4.1", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + } + }, + "jest-runtime": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.4.1.tgz", + "integrity": "sha512-UXTMU9uKu2GjYwTtoAw5rn4STxWw/nadOfW7v1sx6LaJYa3V/iymdCLQM6xy3+7C6mY8GfX22vKpgxY171UIoA==", + "dev": true, + "requires": { + "@jest/environment": "^29.4.1", + "@jest/fake-timers": "^29.4.1", + "@jest/globals": "^29.4.1", + "@jest/source-map": "^29.2.0", + "@jest/test-result": "^29.4.1", + "@jest/transform": "^29.4.1", + "@jest/types": "^29.4.1", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.4.1", + "jest-message-util": "^29.4.1", + "jest-mock": "^29.4.1", + "jest-regex-util": "^29.2.0", + "jest-resolve": "^29.4.1", + "jest-snapshot": "^29.4.1", + "jest-util": "^29.4.1", + "semver": "^7.3.5", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "jest-snapshot": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.4.1.tgz", + "integrity": "sha512-l4iV8EjGgQWVz3ee/LR9sULDk2pCkqb71bjvlqn+qp90lFwpnulHj4ZBT8nm1hA1C5wowXLc7MGnw321u0tsYA==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.4.1", + "@jest/transform": "^29.4.1", + "@jest/types": "^29.4.1", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.4.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.4.1", + "jest-get-type": "^29.2.0", + "jest-haste-map": "^29.4.1", + "jest-matcher-utils": "^29.4.1", + "jest-message-util": "^29.4.1", + "jest-util": "^29.4.1", + "natural-compare": "^1.4.0", + "pretty-format": "^29.4.1", + "semver": "^7.3.5" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "jest-util": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.1.tgz", + "integrity": "sha512-bQy9FPGxVutgpN4VRc0hk6w7Hx/m6L53QxpDreTZgJd9gfx/AV2MjyPde9tGyZRINAUrSv57p2inGBu2dRLmkQ==", + "dev": true, + "requires": { + "@jest/types": "^29.4.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, + "jest-validate": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.4.1.tgz", + "integrity": "sha512-qNZXcZQdIQx4SfUB/atWnI4/I2HUvhz8ajOSYUu40CSmf9U5emil8EDHgE7M+3j9/pavtk3knlZBDsgFvv/SWw==", + "dev": true, + "requires": { + "@jest/types": "^29.4.1", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.2.0", + "leven": "^3.1.0", + "pretty-format": "^29.4.1" + }, + "dependencies": { + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + } + } + }, + "jest-watcher": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.4.1.tgz", + "integrity": "sha512-vFOzflGFs27nU6h8dpnVRER3O2rFtL+VMEwnG0H3KLHcllLsU8y9DchSh0AL/Rg5nN1/wSiQ+P4ByMGpuybaVw==", + "dev": true, + "requires": { + "@jest/test-result": "^29.4.1", + "@jest/types": "^29.4.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.4.1", + "string-length": "^4.0.1" + } + }, + "jest-worker": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.4.1.tgz", + "integrity": "sha512-O9doU/S1EBe+yp/mstQ0VpPwpv0Clgn68TkNwGxL6/usX/KUW9Arnn4ag8C3jc6qHcXznhsT5Na1liYzAsuAbQ==", + "dev": true, + "requires": { + "@types/node": "*", + "jest-util": "^29.4.1", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "requires": { + "tmpl": "1.0.5" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node-releases": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.9.tgz", + "integrity": "sha512-2xfmOrRkGogbTK9R6Leda0DGiXeY3p2NJpy4+gNCffdUvV6mdEJnaDEic1i3Ec2djAo8jWYoJMR5PB0MSMpxUA==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + }, + "dependencies": { + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + } + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "pretty-format": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.1.tgz", + "integrity": "sha512-dt/Z761JUVsrIKaY215o1xQJBGlSmTx/h4cSqXqjHLnU1+Kt+mavVE7UgqJJO5ukx5HjSswHfmXz4LjS2oIJfg==", + "dev": true, + "requires": { + "@jest/schemas": "^29.4.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + } + } + }, + "prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "resolve.exports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.0.tgz", + "integrity": "sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + } + }, + "string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + }, + "update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "v8-to-istanbul": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", + "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "dependencies": { + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + } + } + }, + "walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "requires": { + "makeerror": "1.0.12" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "write-file-atomic": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.0.tgz", + "integrity": "sha512-R7NYMnHSlV42K54lwY9lvW6MnSm1HSJqZL3xiSgi9E7//FYaI74r2G0rd+/X6VAMkHEdzxQaU5HUOXWUz5kA/w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yargs": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/package.json b/package.json index 5c10b74..13276e6 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "md-links", + "name": "rvq_md-links", "version": "0.1.0", "engines": { "node": ">=16.x" @@ -8,5 +8,26 @@ "createdAt": "2022-11-30T13:40:29.636Z", "version": "5.5.0", "commit": "51e941edf1cc991930aefd7dd9c406a7c43741c1" + }, + "description": "* [1. Preámbulo](#1-preámbulo)\r * [2. Resumen del proyecto](#2-resumen-del-proyecto)\r * [3. Objetivos de aprendizaje](#3-objetivos-de-aprendizaje)\r * [4. Consideraciones generales](#4-consideraciones-generales)\r * [5. Criterios de aceptación mínimos del proyecto](#5-criterios-de-aceptación-mínimos-del-proyecto)\r * [6. Entregables](#6-entregables)\r * [7. Hacker edition](#7-hacker-edition)\r * [8. Pistas, tips y lecturas complementarias](#8-pistas-tips-y-lecturas-complementarias)\r * [9. Checklist](#9-checklist)\r * [10. Achicando el problema](#10-achicando-el-problema)", + "main": "index.js", + "directories": { + "test": "test" + }, + "scripts": { + "test": "jest --verbose --coverage" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/roxsyVel910/DEV002-md-links.git" + }, + "author": "Roxsy Vq", + "license": "ISC", + "bugs": { + "url": "https://github.com/roxsyVel910/DEV002-md-links/issues" + }, + "homepage": "https://github.com/roxsyVel910/DEV002-md-links#readme", + "devDependencies": { + "jest": "^29.4.1" } -} \ No newline at end of file +} diff --git a/readme/README.md b/readme/README.md new file mode 100644 index 0000000..d4df79b --- /dev/null +++ b/readme/README.md @@ -0,0 +1,666 @@ +# Markdown Links + +## Índice + +* [1. Preámbulo](#1-preámbulo) +* [2. Resumen del proyecto](#2-resumen-del-proyecto) +* [3. Objetivos de aprendizaje](#3-objetivos-de-aprendizaje) +* [4. Consideraciones generales](#4-consideraciones-generales) +* [5. Criterios de aceptación mínimos del proyecto](#5-criterios-de-aceptación-mínimos-del-proyecto) +* [6. Entregables](#6-entregables) +* [7. Hacker edition](#7-hacker-edition) +* [8. Pistas, tips y lecturas complementarias](#8-pistas-tips-y-lecturas-complementarias) +* [9. Checklist](#9-checklist) +* [10. Achicando el problema](#10-achicando-el-problema) + +*** + +## 1. Preámbulo + +[Markdown](https://es.wikipedia.org/wiki/Markdown) es un lenguaje de marcado +ligero muy popular entre developers. Es usado en muchísimas plataformas que +manejan texto plano (GitHub, foros, blogs, ...) y es muy común +encontrar varios archivos en ese formato en cualquier tipo de repositorio +(empezando por el tradicional `README.md`). + +Estos archivos `Markdown` normalmente contienen _links_ (vínculos/ligas) que +muchas veces están rotos o ya no son válidos y eso perjudica mucho el valor de +la información que se quiere compartir. + +Dentro de una comunidad de código abierto, nos han propuesto crear una +herramienta usando [Node.js](https://nodejs.org/), que lea y analice archivos +en formato `Markdown`, para verificar los links que contengan y reportar +algunas estadísticas. + +![md-links](https://user-images.githubusercontent.com/110297/42118443-b7a5f1f0-7bc8-11e8-96ad-9cc5593715a6.jpg) + +## 2. Resumen del proyecto + +En este proyecto crearás una herramienta de línea de comando (CLI) así como tu +propia librería (o biblioteca - library) en JavaScript. + +En esta oportunidad nos alejamos un poco del navegador para construir un +programa que se ejecute usando Node.js. Aprenderemos sobre procesos +(`process.env`, `process.argv`, ...), cómo interactuar con el sistema archivos, +cómo hacer consultas de red, etc. + +[Node.js](https://nodejs.org/es/) es un entorno de ejecución para JavaScript +construido con el [motor de JavaScript V8 de Chrome](https://developers.google.com/v8/). +Esto nos va a permitir ejecutar JavaScript en el entorno del sistema operativo, +ya sea tu máquina o un servidor, lo cual nos abre las puertas para poder +interactuar con el sistema en sí, archivos, redes, ... + +Diseñar tu propia librería es una experiencia fundamental para cualquier +desarrollador porque que te obliga a pensar en la interfaz (API) de tus +_módulos_ y cómo será usado por otros developers. Debes tener especial +consideración en peculiaridades del lenguaje, convenciones y buenas prácticas. + +## 3. Objetivos de aprendizaje + +Reflexiona y luego marca los objetivos que has llegado a entender y aplicar en tu proyecto. Piensa en eso al decidir tu estrategia de trabajo. + +### JavaScript + +- [ ] **Diferenciar entre tipos de datos primitivos y no primitivos** + +- [ ] **Arrays (arreglos)** + +
Links

+ + * [Arreglos](https://curriculum.laboratoria.la/es/topics/javascript/04-arrays) + * [Array - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/) + * [Array.prototype.sort() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) + * [Array.prototype.forEach() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) + * [Array.prototype.map() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/map) + * [Array.prototype.filter() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) + * [Array.prototype.reduce() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) +

+ +- [ ] **Objetos (key, value)** + +
Links

+ + * [Objetos en JavaScript](https://curriculum.laboratoria.la/es/topics/javascript/05-objects/01-objects) +

+ +- [ ] **Uso de condicionales (if-else, switch, operador ternario, lógica booleana)** + +
Links

+ + * [Estructuras condicionales y repetitivas](https://curriculum.laboratoria.la/es/topics/javascript/02-flow-control/01-conditionals-and-loops) + * [Tomando decisiones en tu código — condicionales - MDN](https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/conditionals) +

+ +- [ ] **Funciones (params, args, return)** + +
Links

+ + * [Funciones (control de flujo)](https://curriculum.laboratoria.la/es/topics/javascript/02-flow-control/03-functions) + * [Funciones clásicas](https://curriculum.laboratoria.la/es/topics/javascript/03-functions/01-classic) + * [Arrow Functions](https://curriculum.laboratoria.la/es/topics/javascript/03-functions/02-arrow) + * [Funciones — bloques de código reutilizables - MDN](https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/Functions) +

+ +- [ ] **Recursión o recursividad** + +
Links

+ + * [Píldora recursión - YouTube Laboratoria Developers](https://www.youtube.com/watch?v=lPPgY3HLlhQ) + * [Recursión o Recursividad - Laboratoria Developers en Medium](https://medium.com/laboratoria-developers/recursi%C3%B3n-o-recursividad-ec8f1a359727) +

+ +- [ ] **Módulos de CommonJS** + +
Links

+ + * [Modules: CommonJS modules - Node.js Docs](https://nodejs.org/docs/latest/api/modules.html) +

+ +- [ ] **Diferenciar entre expresiones (expressions) y sentencias (statements)** + +- [ ] **Callbacks** + +
Links

+ + * [Función Callback - MDN](https://developer.mozilla.org/es/docs/Glossary/Callback_function) +

+ +- [ ] **Promesas** + +
Links

+ + * [Promise - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Promise) + * [How to Write a JavaScript Promise - freecodecamp (en inglés)](https://www.freecodecamp.org/news/how-to-write-a-javascript-promise-4ed8d44292b8/) +

+ +- [ ] **Pruebas unitarias (unit tests)** + +
Links

+ + * [Empezando con Jest - Documentación oficial](https://jestjs.io/docs/es-ES/getting-started) +

+ +- [ ] **Pruebas asíncronas** + +
Links

+ + * [Tests de código asincrónico con Jest - Documentación oficial](https://jestjs.io/docs/es-ES/asynchronous) +

+ +- [ ] **Uso de mocks y espías** + +
Links

+ + * [Manual Mocks con Jest - Documentación oficial](https://jestjs.io/docs/es-ES/manual-mocks) +

+ +- [ ] **Pruebas de compatibilidad en múltiples entornos de ejecución** + +- [ ] **Uso de linter (ESLINT)** + +- [ ] **Uso de identificadores descriptivos (Nomenclatura y Semántica)** + +### Node.js + +- [ ] **Instalar y usar módulos con npm** + +
Links

+ + * [Sitio oficial de npm (en inglés)](https://www.npmjs.com/) +

+ +- [ ] **Configuración de package.json** + +
Links

+ + * [package.json - Documentación oficial (en inglés)](https://docs.npmjs.com/files/package.json) +

+ +- [ ] **Configuración de npm-scripts** + +
Links

+ + * [scripts - Documentación oficial (en inglés)](https://docs.npmjs.com/misc/scripts) +

+ +- [ ] **process (env, argv, stdin-stdout-stderr, exit-code)** + +
Links

+ + * [Process - Documentación oficial (en inglés)](https://nodejs.org/api/process.html) +

+ +- [ ] **File system (fs, path)** + +
Links

+ + * [File system - Documentación oficial (en inglés)](https://nodejs.org/api/fs.html) + * [Path - Documentación oficial (en inglés)](https://nodejs.org/api/path.html) +

+ +### Control de Versiones (Git y GitHub) + +- [ ] **Git: Instalación y configuración** + +- [ ] **Git: Control de versiones con git (init, clone, add, commit, status, push, pull, remote)** + +- [ ] **Git: Integración de cambios entre ramas (branch, checkout, fetch, merge, reset, rebase, tag)** + +- [ ] **GitHub: Creación de cuenta y repos, configuración de llaves SSH** + +- [ ] **GitHub: Colaboración en Github (branches | forks | pull requests | code review | tags)** + +- [ ] **GitHub: Organización en Github (projects | issues | labels | milestones | releases)** + +### HTTP + +- [ ] **Consulta o petición (request) y respuesta (response).** + +
Links

+ + * [Generalidades del protocolo HTTP - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/Overview) + * [Mensajes HTTP - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/Messages) +

+ +- [ ] **Códigos de status de HTTP** + +
Links

+ + * [Códigos de estado de respuesta HTTP - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/Status) + * [The Complete Guide to Status Codes for Meaningful ReST APIs - dev.to](https://dev.to/khaosdoctor/the-complete-guide-to-status-codes-for-meaningful-rest-apis-1-5c5) +

+ +## 4. Consideraciones generales + +* Este proyecto se debe "resolver" de manera individual. + +* La **librería** y el **script ejecutable** (herramienta de línea de comando - + CLI) deben estar implementados en JavaScript para ser ejecutados con + Node.js. **Está permitido usar librerías externas**. + +* Tu módulo **debe ser instalable** via `npm install /md-links`. Este + módulo debe incluir tanto un _ejecutable_ que podamos invocar en la línea de + comando como una interfaz que podamos importar con `require` para usarlo + programáticamente. + +* Los **tests unitarios** deben cubrir un mínimo del 70% de _statements_, + _functions_, _lines_ y _branches_. Te recomendamos explorar [Jest](https://jestjs.io/) + para tus pruebas unitarias. + +* Para este proyecto **no está permitido** utilizar `async/await`. + +* Para este proyecto te sugerimos **no utilizar** la versión síncrona +de la función para leer archivos, `readFileSync`, y en cambio intentar +resolver este desafío de manera asíncrona. + +* Para este proyecto es **opcional** el uso de ES Modules `(import/export)`, en el + caso optes utilizarlo deberás de crear un script de `build` en el `package.json` + que los transforme en `requires` y `module.exports` con ayuda de **babel**. + +* Para disminuir la complejidad de tu algoritmo recursivo, te recomendamos +utilizar la versión síncrona de la función para leer directorios, `readdirSync`. + +## 5. Criterios de aceptación mínimos del proyecto + +Para comenzar este proyecto tendrás que hacer un **_fork_** y **_clonar_** este +repositorio. + +Antes de comenzar a codear, es necesario crear un **plan de acción**. Esto debería +quedar detallado en el `README.md` de tu repo y en una serie de **_issues_** +y **_milestones_** para priorizar y organizar el trabajo, y para poder hacer +seguimiento de tu progreso. + +Dentro de cada **_milestone_** se crearán y asignarán los **_issues_** que cada quien +considere necesarios. + +### Archivos del proyecto + +* `README.md` con descripción del módulo, instrucciones de instalación/uso, + documentación del API y ejemplos. Todo lo relevante para que cualquier + developer que quiera usar tu librería pueda hacerlo sin inconvenientes. +* `index.js`: Desde este archivo debes exportar **una** función (`mdLinks`). +* `package.json` con nombre, versión, descripción, autores, licencia, + dependencias, scripts (pretest, test, ...), main, bin +* `.editorconfig` con configuración para editores de texto. Este archivo no se + debe cambiar. +* `.eslintrc` con configuración para linter. Este archivo contiene una + configuración básica para ESLint, si deseas agregar reglas adicionales + como Airbnb deberás modificar este archivo. +* `.gitignore` para ignorar `node_modules` u otras carpetas que no deban + incluirse en control de versiones (`git`). +* `test/md-links.spec.js` debe contener los tests unitarios para la función + `mdLinks()`. Tu inplementación debe pasar estos tets. + +## Este proyecto consta de DOS partes + +### 1) JavaScript API + +El módulo debe poder **importarse** en otros scripts de Node.js y debe ofrecer la +siguiente interfaz: + +#### `mdLinks(path, options)` + +##### Argumentos + +* `path`: Ruta **absoluta** o **relativa** al **archivo** o **directorio**. +Si la ruta pasada es relativa, debe resolverse como relativa al directorio +desde donde se invoca node - _current working directory_). +* `options`: Un objeto con **únicamente** la siguiente propiedad: + - `validate`: Booleano que determina si se desea validar los links + encontrados. + +##### Valor de retorno + +La función debe **retornar una promesa** (`Promise`) que **resuelva a un arreglo** +(`Array`) de objetos (`Object`), donde cada objeto representa un link y contiene +las siguientes propiedades + +Con `validate:false` : + +* `href`: URL encontrada. +* `text`: Texto que aparecía dentro del link (``). +* `file`: Ruta del archivo donde se encontró el link. + +Con `validate:true` : + +* `href`: URL encontrada. +* `text`: Texto que aparecía dentro del link (``). +* `file`: Ruta del archivo donde se encontró el link. +* `status`: Código de respuesta HTTP. +* `ok`: Mensaje `fail` en caso de fallo u `ok` en caso de éxito. + +#### Ejemplo (resultados como comentarios) + +```js +const mdLinks = require("md-links"); + +mdLinks("./some/example.md") + .then(links => { + // => [{ href, text, file }, ...] + }) + .catch(console.error); + +mdLinks("./some/example.md", { validate: true }) + .then(links => { + // => [{ href, text, file, status, ok }, ...] + }) + .catch(console.error); + +mdLinks("./some/dir") + .then(links => { + // => [{ href, text, file }, ...] + }) + .catch(console.error); +``` + +### 2) CLI (Command Line Interface - Interfaz de Línea de Comando) + +El ejecutable de nuestra aplicación debe poder ejecutarse de la siguiente +manera a través de la **terminal**: + +`md-links [options]` + +Por ejemplo: + +```sh +$ md-links ./some/example.md +./some/example.md http://algo.com/2/3/ Link a algo +./some/example.md https://otra-cosa.net/algun-doc.html algún doc +./some/example.md http://google.com/ Google +``` + +El comportamiento por defecto no debe validar si las URLs responden ok o no, +solo debe identificar el archivo markdown (a partir de la ruta que recibe como +argumento), analizar el archivo Markdown e imprimir los links que vaya +encontrando, junto con la ruta del archivo donde aparece y el texto +que hay dentro del link (truncado a 50 caracteres). + +#### Options + +##### `--validate` + +Si pasamos la opción `--validate`, el módulo debe hacer una petición HTTP para +averiguar si el link funciona o no. Si el link resulta en una redirección a una +URL que responde ok, entonces consideraremos el link como ok. + +Por ejemplo: + +```sh +$ md-links ./some/example.md --validate +./some/example.md http://algo.com/2/3/ ok 200 Link a algo +./some/example.md https://otra-cosa.net/algun-doc.html fail 404 algún doc +./some/example.md http://google.com/ ok 301 Google +``` + +Vemos que el _output_ en este caso incluye la palabra `ok` o `fail` después de +la URL, así como el status de la respuesta recibida a la petición HTTP a dicha +URL. + +##### `--stats` + +Si pasamos la opción `--stats` el output (salida) será un texto con estadísticas +básicas sobre los links. + +```sh +$ md-links ./some/example.md --stats +Total: 3 +Unique: 3 +``` + +También podemos combinar `--stats` y `--validate` para obtener estadísticas que +necesiten de los resultados de la validación. + +```sh +$ md-links ./some/example.md --stats --validate +Total: 3 +Unique: 3 +Broken: 1 +``` + +## 6. Entregables + +Módulo instalable via `npm install /md-links`. Este módulo debe +incluir tanto **un ejecutable** como **una interfaz** que podamos importar con `require` +para usarlo programáticamente. + +## 7. Hacker edition + +Las secciones llamadas _Hacker Edition_ son **opcionales**. Si **terminaste** +con todo lo anterior y te queda tiempo, intenta completarlas. Así podrás +profundizar y/o ejercitar más sobre los objetivos de aprendizaje del proyecto. + +* Puedes agregar la propiedad `line` a cada objeto `link` indicando en qué línea + del archivo se encontró el link. +* Puedes agregar más estadísticas. +* Integración continua con Travis o Circle CI. + +*** + +## 8. Pistas, tips y lecturas complementarias + +### FAQs + +#### ¿Cómo hago para que mi módulo sea _instalable_ desde GitHub? + +Para que el módulo sea instalable desde GitHub solo tiene que: + +* Estar en un repo público de GitHub +* Contener un `package.json` válido + +Con el comando `npm install githubname/reponame` podemos instalar directamente +desde GitHub. Ver [docs oficiales de `npm install` acá](https://docs.npmjs.com/cli/install). + +Por ejemplo, el [`course-parser`](https://github.com/Laboratoria/course-parser) +que usamos para la currícula no está publicado en el registro público de NPM, +así que lo instalamos directamente desde GitHub con el comando `npm install +Laboratoria/course-parser`. + +### Sugerencias de implementación + +La implementación de este proyecto tiene varias partes: leer del sistema de +archivos, recibir argumentos a través de la línea de comando, analizar texto, +hacer consultas HTTP, ... y todas estas cosas pueden enfocarse de muchas formas, +tanto usando librerías como implementando en VanillaJS. + +Por poner un ejemplo, el _parseado_ (análisis) del markdown para extraer los +links podría plantearse de las siguientes maneras (todas válidas): + +* Usando un _módulo_ como [markdown-it](https://github.com/markdown-it/markdown-it), + que nos devuelve un arreglo de _tokens_ que podemos recorrer para identificar + los links. +* Siguiendo otro camino completamente, podríamos usar + [expresiones regulares (`RegExp`)](https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Regular_Expressions). +* También podríamos usar una combinación de varios _módulos_ (podría ser válido + transformar el markdown a HTML usando algo como [marked](https://github.com/markedjs/marked) + y de ahí extraer los link con una librería de DOM como [JSDOM](https://github.com/jsdom/jsdom) + o [Cheerio](https://github.com/cheeriojs/cheerio) entre otras). +* Usando un _custom renderer_ de [marked](https://github.com/markedjs/marked) + (`new marked.Renderer()`). + +No dudes en consultar a tus compañeras y coaches +si tienes dudas existenciales con respecto a estas decisiones. No existe una +"única" manera correcta :wink: + +### Tutoriales / NodeSchool workshoppers + +* [learnyounode](https://github.com/workshopper/learnyounode) +* [how-to-npm](https://github.com/workshopper/how-to-npm) +* [promise-it-wont-hurt](https://github.com/stevekane/promise-it-wont-hurt) + +### Otros recursos + +* [Acerca de Node.js - Documentación oficial](https://nodejs.org/es/about/) +* [Node.js file system - Documentación oficial](https://nodejs.org/api/fs.html) +* [Node.js http.get - Documentación oficial](https://nodejs.org/api/http.html#http_http_get_options_callback) +* [Node.js - Wikipedia](https://es.wikipedia.org/wiki/Node.js) +* [What exactly is Node.js? - freeCodeCamp](https://medium.freecodecamp.org/what-exactly-is-node-js-ae36e97449f5) +* [¿Qué es Node.js y para qué sirve? - drauta.com](https://www.drauta.com/que-es-nodejs-y-para-que-sirve) +* [¿Qué es Nodejs? Javascript en el Servidor - Fazt en YouTube](https://www.youtube.com/watch?v=WgSc1nv_4Gw) +* [¿Simplemente qué es Node.js? - IBM Developer Works, 2011](https://www.ibm.com/developerworks/ssa/opensource/library/os-nodejs/index.html) +* [Node.js y npm](https://www.genbeta.com/desarrollo/node-js-y-npm) +* [Módulos, librerías, paquetes, frameworks... ¿cuál es la diferencia?](http://community.laboratoria.la/t/modulos-librerias-paquetes-frameworks-cual-es-la-diferencia/175) +* [Asíncronía en js](https://carlosazaustre.es/manejando-la-asincronia-en-javascript) +* [NPM](https://docs.npmjs.com/getting-started/what-is-npm) +* [Publicar packpage](https://docs.npmjs.com/getting-started/publishing-npm-packages) +* [Crear módulos en Node.js](https://docs.npmjs.com/getting-started/publishing-npm-packages) +* [Leer un archivo](https://nodejs.org/api/fs.html#fs_fs_readfile_path_options_callback) +* [Leer un directorio](https://nodejs.org/api/fs.html#fs_fs_readdir_path_options_callback) +* [Path](https://nodejs.org/api/path.html) +* [Linea de comando CLI](https://medium.com/netscape/a-guide-to-create-a-nodejs-command-line-package-c2166ad0452e) + +## 9. Checklist + +### General + +* [ ] Puede instalarse via `npm install --global /md-links` + +### `README.md` + +* [ ] Un board con el backlog para la implementación de la librería. +* [ ] Documentación técnica de la librería. +* [ ] Guía de uso e instalación de la librería + +### API `mdLinks(path, opts)` + +* [ ] El módulo exporta una función con la interfaz (API) esperada. +* [ ] Implementa soporte para archivo individual +* [ ] Implementa soporte para directorios +* [ ] Implementa `options.validate` + +### CLI + +* [ ] Expone ejecutable `md-links` en el path (configurado en `package.json`) +* [ ] Se ejecuta sin errores / output esperado +* [ ] Implementa `--validate` +* [ ] Implementa `--stats` + +### Pruebas / tests + +* [ ] Pruebas unitarias cubren un mínimo del 70% de statements, functions, + lines, y branches. +* [ ] Pasa tests (y linters) (`npm test`). + +## 10. Achicando el problema + +Un "superpoder" que esperamos puedas desarrollar durante el bootcamp +es el de definir "mini-proyectos" que te acerquen paso a paso a +la solución del "gran proyecto". Es el equivalente a comenzar armando +esquinas o bordes del rompecabezas/puzzle sin saber necesariamente +cómo encajarán al final. Déjate llevar y explora. + +Estas son algunas sugerencias: + +### Empieza con un diagrama de flujo + +Este proyecto es distinto de los que has venido trabajando hasta ahora +dado que no hay una interfaz web, todo se desarrollará en tu editor y +consola/terminal. + +Es por ello que, para visualizar mejor lo que tendrás que hacer +y planificar tus tareas y objetivos, es recomendable hacer un +`diagrama de flujo`. + +Si nunca has hecho un diagrama de flujo revisa este [recurso](https://www.youtube.com/watch?v=Lub5qOmY4JQ). + +Una alternativa al diagrama de flujo puede ser el `pseudocódigo`. + +### Planificación + +En este proyecto te recomendamos usar la herramienta de planificación +y organización de GitHub llamada **Github Projects**. + +Mediante **issues** y **milestones** podrás organizar y planificar +tareas y objetivos concretos. + +Tomando en consideración los **entregables** del proyecto, el +[9. Checklist](#9-checklist) y los **pasos** que definiste en tu +`diagrama de flujo`, crea tu planificación en GitHub Projects. + +### Antes de codear + +En esta ocasión estarás trabajando en **NodeJS**, asegúrate +de saber para qué sirve y sus consideraciones. + +En particular, deberás decidir desde un comienzo si usarás +`ES Modules`, es decir, **import/export**, ó, por el contrario, +`CommonJS Modules`, es decir, **require/module.exports**. + +Asegurate de tener clara esta decisión desde un inicio para +que no encuentres problemas más adelante. + +### Lee un archivo + +Como primer reto, puedes tratar de leer un solo archivo con +una ruta fija e imprimir su contenido en la consola con un `console.log`. + +La librería nativa `FS` (FileSystem) te será de utilidad. + +**Recuerda**: Te sugerimos **no utilizar** la versión síncrona +de la función para leer archivos, `readFileSync`, y en cambio +intentar resolver ese desafío de manera asíncrona. + +### Averigua la extensión de un archivo + +Ya sabiendo leer un archivo, aventúrate a conocer cual +es su extensión. + +Recuerda, las extensiones son esas letras al final del +nombre de un archivo, por ejemplo: .js, .txt, .doc, etc + +Aquí también podrá ser útil `FS`. + +### Obtén el contenido de un directorio + +Este proyecto consiste en buscar archivos, pero para eso, +primero debes poder verlos. + +Intenta imprimir en consola la lista de archivos en una carpeta. + +La librería `FS` también te será útil aquí. + +**Recuerda**: Para disminuir la complejidad de tu algoritmo +recursivo, te recomendamos utilizar la versión síncrona de +la función para leer directorios, `readdirSync`. + +### Une dos rutas + +Para poder acceder a carpetas y archivos será necesario que +indiques en qué lugar de tu computadora se encuentran, a esto +le llamamos **rutas**. + +Usa la librería nativa `path` para unir dos segmentos de ruta, +por ejemplo, si queremos unir: + +1) /home/Laboratoria/ +2) ./test + +El resultado sería: /home/Laboratoria/test + +### Recursividad + +Este proyecto se ha de resolver de forma casi natural con +**recursividad**. + +¿Por qué?. + +Porque no conocemos realmente cuantas carpetas y archivos +tendremos que recorrer antes de terminar. + +Si recibes una ruta de carpeta, no sabrás de ante mano si +dentro hay más carpetas o muchos archivos. + +Por ello, asegurate bien de entender de qué trata la +recursividad y ver algunos ejemplos. + +Entre los recursos de este proyecto hay un video que te ayudará. + +### Crea una promesa + +El valor de retorno de nuestra librería es una `Promesa`, +no un `Array`. + +Prueba leyendo sobre las promesas y creando una por tu +cuenta utilizando **new Promise()** + +Es importante que sepas qué es un **callback** pues las +promesas los utilizarán. diff --git a/test/md-links.spec.js b/test/md-links.spec.js index 31db9e9..1420b5a 100644 --- a/test/md-links.spec.js +++ b/test/md-links.spec.js @@ -1,10 +1,24 @@ -const mdLinks = require('../'); + +const { mdLinks } = require('../index.js'); describe('mdLinks', () => { - it('should...', () => { - console.log('FIX ME!'); + // it('should...', () => { + // console.log('FIX ME!'); + // }); + + // it('deveria devolver una promesa', () => { + // expect(mdLinks()).toBe(typeof Promise); + // }); + + it('Debe rechazar cuando el path no existe ', () => { + return mdLinks('./README.md').catch((error) => { + expect(error).toBe('la ruta no existe') + }) + + + }); }); From 40ca0adb0ae0bb576625a0c2a35512eeaa4f1bab Mon Sep 17 00:00:00 2001 From: Roxsy Date: Mon, 6 Feb 2023 21:41:25 -0500 Subject: [PATCH 02/12] funcion para recursividad en carpetas --- Caperta/README.md | 666 ++++++++++++++++++++++ Caperta/subcarpeta/README.md | 666 ++++++++++++++++++++++ Caperta/subcarpeta/media-Capera/README.md | 666 ++++++++++++++++++++++ app.js | 98 +++- cli.js | 2 +- index.js | 7 +- 6 files changed, 2084 insertions(+), 21 deletions(-) create mode 100644 Caperta/README.md create mode 100644 Caperta/subcarpeta/README.md create mode 100644 Caperta/subcarpeta/media-Capera/README.md diff --git a/Caperta/README.md b/Caperta/README.md new file mode 100644 index 0000000..d4df79b --- /dev/null +++ b/Caperta/README.md @@ -0,0 +1,666 @@ +# Markdown Links + +## Índice + +* [1. Preámbulo](#1-preámbulo) +* [2. Resumen del proyecto](#2-resumen-del-proyecto) +* [3. Objetivos de aprendizaje](#3-objetivos-de-aprendizaje) +* [4. Consideraciones generales](#4-consideraciones-generales) +* [5. Criterios de aceptación mínimos del proyecto](#5-criterios-de-aceptación-mínimos-del-proyecto) +* [6. Entregables](#6-entregables) +* [7. Hacker edition](#7-hacker-edition) +* [8. Pistas, tips y lecturas complementarias](#8-pistas-tips-y-lecturas-complementarias) +* [9. Checklist](#9-checklist) +* [10. Achicando el problema](#10-achicando-el-problema) + +*** + +## 1. Preámbulo + +[Markdown](https://es.wikipedia.org/wiki/Markdown) es un lenguaje de marcado +ligero muy popular entre developers. Es usado en muchísimas plataformas que +manejan texto plano (GitHub, foros, blogs, ...) y es muy común +encontrar varios archivos en ese formato en cualquier tipo de repositorio +(empezando por el tradicional `README.md`). + +Estos archivos `Markdown` normalmente contienen _links_ (vínculos/ligas) que +muchas veces están rotos o ya no son válidos y eso perjudica mucho el valor de +la información que se quiere compartir. + +Dentro de una comunidad de código abierto, nos han propuesto crear una +herramienta usando [Node.js](https://nodejs.org/), que lea y analice archivos +en formato `Markdown`, para verificar los links que contengan y reportar +algunas estadísticas. + +![md-links](https://user-images.githubusercontent.com/110297/42118443-b7a5f1f0-7bc8-11e8-96ad-9cc5593715a6.jpg) + +## 2. Resumen del proyecto + +En este proyecto crearás una herramienta de línea de comando (CLI) así como tu +propia librería (o biblioteca - library) en JavaScript. + +En esta oportunidad nos alejamos un poco del navegador para construir un +programa que se ejecute usando Node.js. Aprenderemos sobre procesos +(`process.env`, `process.argv`, ...), cómo interactuar con el sistema archivos, +cómo hacer consultas de red, etc. + +[Node.js](https://nodejs.org/es/) es un entorno de ejecución para JavaScript +construido con el [motor de JavaScript V8 de Chrome](https://developers.google.com/v8/). +Esto nos va a permitir ejecutar JavaScript en el entorno del sistema operativo, +ya sea tu máquina o un servidor, lo cual nos abre las puertas para poder +interactuar con el sistema en sí, archivos, redes, ... + +Diseñar tu propia librería es una experiencia fundamental para cualquier +desarrollador porque que te obliga a pensar en la interfaz (API) de tus +_módulos_ y cómo será usado por otros developers. Debes tener especial +consideración en peculiaridades del lenguaje, convenciones y buenas prácticas. + +## 3. Objetivos de aprendizaje + +Reflexiona y luego marca los objetivos que has llegado a entender y aplicar en tu proyecto. Piensa en eso al decidir tu estrategia de trabajo. + +### JavaScript + +- [ ] **Diferenciar entre tipos de datos primitivos y no primitivos** + +- [ ] **Arrays (arreglos)** + +
Links

+ + * [Arreglos](https://curriculum.laboratoria.la/es/topics/javascript/04-arrays) + * [Array - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/) + * [Array.prototype.sort() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) + * [Array.prototype.forEach() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) + * [Array.prototype.map() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/map) + * [Array.prototype.filter() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) + * [Array.prototype.reduce() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) +

+ +- [ ] **Objetos (key, value)** + +
Links

+ + * [Objetos en JavaScript](https://curriculum.laboratoria.la/es/topics/javascript/05-objects/01-objects) +

+ +- [ ] **Uso de condicionales (if-else, switch, operador ternario, lógica booleana)** + +
Links

+ + * [Estructuras condicionales y repetitivas](https://curriculum.laboratoria.la/es/topics/javascript/02-flow-control/01-conditionals-and-loops) + * [Tomando decisiones en tu código — condicionales - MDN](https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/conditionals) +

+ +- [ ] **Funciones (params, args, return)** + +
Links

+ + * [Funciones (control de flujo)](https://curriculum.laboratoria.la/es/topics/javascript/02-flow-control/03-functions) + * [Funciones clásicas](https://curriculum.laboratoria.la/es/topics/javascript/03-functions/01-classic) + * [Arrow Functions](https://curriculum.laboratoria.la/es/topics/javascript/03-functions/02-arrow) + * [Funciones — bloques de código reutilizables - MDN](https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/Functions) +

+ +- [ ] **Recursión o recursividad** + +
Links

+ + * [Píldora recursión - YouTube Laboratoria Developers](https://www.youtube.com/watch?v=lPPgY3HLlhQ) + * [Recursión o Recursividad - Laboratoria Developers en Medium](https://medium.com/laboratoria-developers/recursi%C3%B3n-o-recursividad-ec8f1a359727) +

+ +- [ ] **Módulos de CommonJS** + +
Links

+ + * [Modules: CommonJS modules - Node.js Docs](https://nodejs.org/docs/latest/api/modules.html) +

+ +- [ ] **Diferenciar entre expresiones (expressions) y sentencias (statements)** + +- [ ] **Callbacks** + +
Links

+ + * [Función Callback - MDN](https://developer.mozilla.org/es/docs/Glossary/Callback_function) +

+ +- [ ] **Promesas** + +
Links

+ + * [Promise - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Promise) + * [How to Write a JavaScript Promise - freecodecamp (en inglés)](https://www.freecodecamp.org/news/how-to-write-a-javascript-promise-4ed8d44292b8/) +

+ +- [ ] **Pruebas unitarias (unit tests)** + +
Links

+ + * [Empezando con Jest - Documentación oficial](https://jestjs.io/docs/es-ES/getting-started) +

+ +- [ ] **Pruebas asíncronas** + +
Links

+ + * [Tests de código asincrónico con Jest - Documentación oficial](https://jestjs.io/docs/es-ES/asynchronous) +

+ +- [ ] **Uso de mocks y espías** + +
Links

+ + * [Manual Mocks con Jest - Documentación oficial](https://jestjs.io/docs/es-ES/manual-mocks) +

+ +- [ ] **Pruebas de compatibilidad en múltiples entornos de ejecución** + +- [ ] **Uso de linter (ESLINT)** + +- [ ] **Uso de identificadores descriptivos (Nomenclatura y Semántica)** + +### Node.js + +- [ ] **Instalar y usar módulos con npm** + +
Links

+ + * [Sitio oficial de npm (en inglés)](https://www.npmjs.com/) +

+ +- [ ] **Configuración de package.json** + +
Links

+ + * [package.json - Documentación oficial (en inglés)](https://docs.npmjs.com/files/package.json) +

+ +- [ ] **Configuración de npm-scripts** + +
Links

+ + * [scripts - Documentación oficial (en inglés)](https://docs.npmjs.com/misc/scripts) +

+ +- [ ] **process (env, argv, stdin-stdout-stderr, exit-code)** + +
Links

+ + * [Process - Documentación oficial (en inglés)](https://nodejs.org/api/process.html) +

+ +- [ ] **File system (fs, path)** + +
Links

+ + * [File system - Documentación oficial (en inglés)](https://nodejs.org/api/fs.html) + * [Path - Documentación oficial (en inglés)](https://nodejs.org/api/path.html) +

+ +### Control de Versiones (Git y GitHub) + +- [ ] **Git: Instalación y configuración** + +- [ ] **Git: Control de versiones con git (init, clone, add, commit, status, push, pull, remote)** + +- [ ] **Git: Integración de cambios entre ramas (branch, checkout, fetch, merge, reset, rebase, tag)** + +- [ ] **GitHub: Creación de cuenta y repos, configuración de llaves SSH** + +- [ ] **GitHub: Colaboración en Github (branches | forks | pull requests | code review | tags)** + +- [ ] **GitHub: Organización en Github (projects | issues | labels | milestones | releases)** + +### HTTP + +- [ ] **Consulta o petición (request) y respuesta (response).** + +
Links

+ + * [Generalidades del protocolo HTTP - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/Overview) + * [Mensajes HTTP - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/Messages) +

+ +- [ ] **Códigos de status de HTTP** + +
Links

+ + * [Códigos de estado de respuesta HTTP - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/Status) + * [The Complete Guide to Status Codes for Meaningful ReST APIs - dev.to](https://dev.to/khaosdoctor/the-complete-guide-to-status-codes-for-meaningful-rest-apis-1-5c5) +

+ +## 4. Consideraciones generales + +* Este proyecto se debe "resolver" de manera individual. + +* La **librería** y el **script ejecutable** (herramienta de línea de comando - + CLI) deben estar implementados en JavaScript para ser ejecutados con + Node.js. **Está permitido usar librerías externas**. + +* Tu módulo **debe ser instalable** via `npm install /md-links`. Este + módulo debe incluir tanto un _ejecutable_ que podamos invocar en la línea de + comando como una interfaz que podamos importar con `require` para usarlo + programáticamente. + +* Los **tests unitarios** deben cubrir un mínimo del 70% de _statements_, + _functions_, _lines_ y _branches_. Te recomendamos explorar [Jest](https://jestjs.io/) + para tus pruebas unitarias. + +* Para este proyecto **no está permitido** utilizar `async/await`. + +* Para este proyecto te sugerimos **no utilizar** la versión síncrona +de la función para leer archivos, `readFileSync`, y en cambio intentar +resolver este desafío de manera asíncrona. + +* Para este proyecto es **opcional** el uso de ES Modules `(import/export)`, en el + caso optes utilizarlo deberás de crear un script de `build` en el `package.json` + que los transforme en `requires` y `module.exports` con ayuda de **babel**. + +* Para disminuir la complejidad de tu algoritmo recursivo, te recomendamos +utilizar la versión síncrona de la función para leer directorios, `readdirSync`. + +## 5. Criterios de aceptación mínimos del proyecto + +Para comenzar este proyecto tendrás que hacer un **_fork_** y **_clonar_** este +repositorio. + +Antes de comenzar a codear, es necesario crear un **plan de acción**. Esto debería +quedar detallado en el `README.md` de tu repo y en una serie de **_issues_** +y **_milestones_** para priorizar y organizar el trabajo, y para poder hacer +seguimiento de tu progreso. + +Dentro de cada **_milestone_** se crearán y asignarán los **_issues_** que cada quien +considere necesarios. + +### Archivos del proyecto + +* `README.md` con descripción del módulo, instrucciones de instalación/uso, + documentación del API y ejemplos. Todo lo relevante para que cualquier + developer que quiera usar tu librería pueda hacerlo sin inconvenientes. +* `index.js`: Desde este archivo debes exportar **una** función (`mdLinks`). +* `package.json` con nombre, versión, descripción, autores, licencia, + dependencias, scripts (pretest, test, ...), main, bin +* `.editorconfig` con configuración para editores de texto. Este archivo no se + debe cambiar. +* `.eslintrc` con configuración para linter. Este archivo contiene una + configuración básica para ESLint, si deseas agregar reglas adicionales + como Airbnb deberás modificar este archivo. +* `.gitignore` para ignorar `node_modules` u otras carpetas que no deban + incluirse en control de versiones (`git`). +* `test/md-links.spec.js` debe contener los tests unitarios para la función + `mdLinks()`. Tu inplementación debe pasar estos tets. + +## Este proyecto consta de DOS partes + +### 1) JavaScript API + +El módulo debe poder **importarse** en otros scripts de Node.js y debe ofrecer la +siguiente interfaz: + +#### `mdLinks(path, options)` + +##### Argumentos + +* `path`: Ruta **absoluta** o **relativa** al **archivo** o **directorio**. +Si la ruta pasada es relativa, debe resolverse como relativa al directorio +desde donde se invoca node - _current working directory_). +* `options`: Un objeto con **únicamente** la siguiente propiedad: + - `validate`: Booleano que determina si se desea validar los links + encontrados. + +##### Valor de retorno + +La función debe **retornar una promesa** (`Promise`) que **resuelva a un arreglo** +(`Array`) de objetos (`Object`), donde cada objeto representa un link y contiene +las siguientes propiedades + +Con `validate:false` : + +* `href`: URL encontrada. +* `text`: Texto que aparecía dentro del link (`
`). +* `file`: Ruta del archivo donde se encontró el link. + +Con `validate:true` : + +* `href`: URL encontrada. +* `text`: Texto que aparecía dentro del link (``). +* `file`: Ruta del archivo donde se encontró el link. +* `status`: Código de respuesta HTTP. +* `ok`: Mensaje `fail` en caso de fallo u `ok` en caso de éxito. + +#### Ejemplo (resultados como comentarios) + +```js +const mdLinks = require("md-links"); + +mdLinks("./some/example.md") + .then(links => { + // => [{ href, text, file }, ...] + }) + .catch(console.error); + +mdLinks("./some/example.md", { validate: true }) + .then(links => { + // => [{ href, text, file, status, ok }, ...] + }) + .catch(console.error); + +mdLinks("./some/dir") + .then(links => { + // => [{ href, text, file }, ...] + }) + .catch(console.error); +``` + +### 2) CLI (Command Line Interface - Interfaz de Línea de Comando) + +El ejecutable de nuestra aplicación debe poder ejecutarse de la siguiente +manera a través de la **terminal**: + +`md-links [options]` + +Por ejemplo: + +```sh +$ md-links ./some/example.md +./some/example.md http://algo.com/2/3/ Link a algo +./some/example.md https://otra-cosa.net/algun-doc.html algún doc +./some/example.md http://google.com/ Google +``` + +El comportamiento por defecto no debe validar si las URLs responden ok o no, +solo debe identificar el archivo markdown (a partir de la ruta que recibe como +argumento), analizar el archivo Markdown e imprimir los links que vaya +encontrando, junto con la ruta del archivo donde aparece y el texto +que hay dentro del link (truncado a 50 caracteres). + +#### Options + +##### `--validate` + +Si pasamos la opción `--validate`, el módulo debe hacer una petición HTTP para +averiguar si el link funciona o no. Si el link resulta en una redirección a una +URL que responde ok, entonces consideraremos el link como ok. + +Por ejemplo: + +```sh +$ md-links ./some/example.md --validate +./some/example.md http://algo.com/2/3/ ok 200 Link a algo +./some/example.md https://otra-cosa.net/algun-doc.html fail 404 algún doc +./some/example.md http://google.com/ ok 301 Google +``` + +Vemos que el _output_ en este caso incluye la palabra `ok` o `fail` después de +la URL, así como el status de la respuesta recibida a la petición HTTP a dicha +URL. + +##### `--stats` + +Si pasamos la opción `--stats` el output (salida) será un texto con estadísticas +básicas sobre los links. + +```sh +$ md-links ./some/example.md --stats +Total: 3 +Unique: 3 +``` + +También podemos combinar `--stats` y `--validate` para obtener estadísticas que +necesiten de los resultados de la validación. + +```sh +$ md-links ./some/example.md --stats --validate +Total: 3 +Unique: 3 +Broken: 1 +``` + +## 6. Entregables + +Módulo instalable via `npm install /md-links`. Este módulo debe +incluir tanto **un ejecutable** como **una interfaz** que podamos importar con `require` +para usarlo programáticamente. + +## 7. Hacker edition + +Las secciones llamadas _Hacker Edition_ son **opcionales**. Si **terminaste** +con todo lo anterior y te queda tiempo, intenta completarlas. Así podrás +profundizar y/o ejercitar más sobre los objetivos de aprendizaje del proyecto. + +* Puedes agregar la propiedad `line` a cada objeto `link` indicando en qué línea + del archivo se encontró el link. +* Puedes agregar más estadísticas. +* Integración continua con Travis o Circle CI. + +*** + +## 8. Pistas, tips y lecturas complementarias + +### FAQs + +#### ¿Cómo hago para que mi módulo sea _instalable_ desde GitHub? + +Para que el módulo sea instalable desde GitHub solo tiene que: + +* Estar en un repo público de GitHub +* Contener un `package.json` válido + +Con el comando `npm install githubname/reponame` podemos instalar directamente +desde GitHub. Ver [docs oficiales de `npm install` acá](https://docs.npmjs.com/cli/install). + +Por ejemplo, el [`course-parser`](https://github.com/Laboratoria/course-parser) +que usamos para la currícula no está publicado en el registro público de NPM, +así que lo instalamos directamente desde GitHub con el comando `npm install +Laboratoria/course-parser`. + +### Sugerencias de implementación + +La implementación de este proyecto tiene varias partes: leer del sistema de +archivos, recibir argumentos a través de la línea de comando, analizar texto, +hacer consultas HTTP, ... y todas estas cosas pueden enfocarse de muchas formas, +tanto usando librerías como implementando en VanillaJS. + +Por poner un ejemplo, el _parseado_ (análisis) del markdown para extraer los +links podría plantearse de las siguientes maneras (todas válidas): + +* Usando un _módulo_ como [markdown-it](https://github.com/markdown-it/markdown-it), + que nos devuelve un arreglo de _tokens_ que podemos recorrer para identificar + los links. +* Siguiendo otro camino completamente, podríamos usar + [expresiones regulares (`RegExp`)](https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Regular_Expressions). +* También podríamos usar una combinación de varios _módulos_ (podría ser válido + transformar el markdown a HTML usando algo como [marked](https://github.com/markedjs/marked) + y de ahí extraer los link con una librería de DOM como [JSDOM](https://github.com/jsdom/jsdom) + o [Cheerio](https://github.com/cheeriojs/cheerio) entre otras). +* Usando un _custom renderer_ de [marked](https://github.com/markedjs/marked) + (`new marked.Renderer()`). + +No dudes en consultar a tus compañeras y coaches +si tienes dudas existenciales con respecto a estas decisiones. No existe una +"única" manera correcta :wink: + +### Tutoriales / NodeSchool workshoppers + +* [learnyounode](https://github.com/workshopper/learnyounode) +* [how-to-npm](https://github.com/workshopper/how-to-npm) +* [promise-it-wont-hurt](https://github.com/stevekane/promise-it-wont-hurt) + +### Otros recursos + +* [Acerca de Node.js - Documentación oficial](https://nodejs.org/es/about/) +* [Node.js file system - Documentación oficial](https://nodejs.org/api/fs.html) +* [Node.js http.get - Documentación oficial](https://nodejs.org/api/http.html#http_http_get_options_callback) +* [Node.js - Wikipedia](https://es.wikipedia.org/wiki/Node.js) +* [What exactly is Node.js? - freeCodeCamp](https://medium.freecodecamp.org/what-exactly-is-node-js-ae36e97449f5) +* [¿Qué es Node.js y para qué sirve? - drauta.com](https://www.drauta.com/que-es-nodejs-y-para-que-sirve) +* [¿Qué es Nodejs? Javascript en el Servidor - Fazt en YouTube](https://www.youtube.com/watch?v=WgSc1nv_4Gw) +* [¿Simplemente qué es Node.js? - IBM Developer Works, 2011](https://www.ibm.com/developerworks/ssa/opensource/library/os-nodejs/index.html) +* [Node.js y npm](https://www.genbeta.com/desarrollo/node-js-y-npm) +* [Módulos, librerías, paquetes, frameworks... ¿cuál es la diferencia?](http://community.laboratoria.la/t/modulos-librerias-paquetes-frameworks-cual-es-la-diferencia/175) +* [Asíncronía en js](https://carlosazaustre.es/manejando-la-asincronia-en-javascript) +* [NPM](https://docs.npmjs.com/getting-started/what-is-npm) +* [Publicar packpage](https://docs.npmjs.com/getting-started/publishing-npm-packages) +* [Crear módulos en Node.js](https://docs.npmjs.com/getting-started/publishing-npm-packages) +* [Leer un archivo](https://nodejs.org/api/fs.html#fs_fs_readfile_path_options_callback) +* [Leer un directorio](https://nodejs.org/api/fs.html#fs_fs_readdir_path_options_callback) +* [Path](https://nodejs.org/api/path.html) +* [Linea de comando CLI](https://medium.com/netscape/a-guide-to-create-a-nodejs-command-line-package-c2166ad0452e) + +## 9. Checklist + +### General + +* [ ] Puede instalarse via `npm install --global /md-links` + +### `README.md` + +* [ ] Un board con el backlog para la implementación de la librería. +* [ ] Documentación técnica de la librería. +* [ ] Guía de uso e instalación de la librería + +### API `mdLinks(path, opts)` + +* [ ] El módulo exporta una función con la interfaz (API) esperada. +* [ ] Implementa soporte para archivo individual +* [ ] Implementa soporte para directorios +* [ ] Implementa `options.validate` + +### CLI + +* [ ] Expone ejecutable `md-links` en el path (configurado en `package.json`) +* [ ] Se ejecuta sin errores / output esperado +* [ ] Implementa `--validate` +* [ ] Implementa `--stats` + +### Pruebas / tests + +* [ ] Pruebas unitarias cubren un mínimo del 70% de statements, functions, + lines, y branches. +* [ ] Pasa tests (y linters) (`npm test`). + +## 10. Achicando el problema + +Un "superpoder" que esperamos puedas desarrollar durante el bootcamp +es el de definir "mini-proyectos" que te acerquen paso a paso a +la solución del "gran proyecto". Es el equivalente a comenzar armando +esquinas o bordes del rompecabezas/puzzle sin saber necesariamente +cómo encajarán al final. Déjate llevar y explora. + +Estas son algunas sugerencias: + +### Empieza con un diagrama de flujo + +Este proyecto es distinto de los que has venido trabajando hasta ahora +dado que no hay una interfaz web, todo se desarrollará en tu editor y +consola/terminal. + +Es por ello que, para visualizar mejor lo que tendrás que hacer +y planificar tus tareas y objetivos, es recomendable hacer un +`diagrama de flujo`. + +Si nunca has hecho un diagrama de flujo revisa este [recurso](https://www.youtube.com/watch?v=Lub5qOmY4JQ). + +Una alternativa al diagrama de flujo puede ser el `pseudocódigo`. + +### Planificación + +En este proyecto te recomendamos usar la herramienta de planificación +y organización de GitHub llamada **Github Projects**. + +Mediante **issues** y **milestones** podrás organizar y planificar +tareas y objetivos concretos. + +Tomando en consideración los **entregables** del proyecto, el +[9. Checklist](#9-checklist) y los **pasos** que definiste en tu +`diagrama de flujo`, crea tu planificación en GitHub Projects. + +### Antes de codear + +En esta ocasión estarás trabajando en **NodeJS**, asegúrate +de saber para qué sirve y sus consideraciones. + +En particular, deberás decidir desde un comienzo si usarás +`ES Modules`, es decir, **import/export**, ó, por el contrario, +`CommonJS Modules`, es decir, **require/module.exports**. + +Asegurate de tener clara esta decisión desde un inicio para +que no encuentres problemas más adelante. + +### Lee un archivo + +Como primer reto, puedes tratar de leer un solo archivo con +una ruta fija e imprimir su contenido en la consola con un `console.log`. + +La librería nativa `FS` (FileSystem) te será de utilidad. + +**Recuerda**: Te sugerimos **no utilizar** la versión síncrona +de la función para leer archivos, `readFileSync`, y en cambio +intentar resolver ese desafío de manera asíncrona. + +### Averigua la extensión de un archivo + +Ya sabiendo leer un archivo, aventúrate a conocer cual +es su extensión. + +Recuerda, las extensiones son esas letras al final del +nombre de un archivo, por ejemplo: .js, .txt, .doc, etc + +Aquí también podrá ser útil `FS`. + +### Obtén el contenido de un directorio + +Este proyecto consiste en buscar archivos, pero para eso, +primero debes poder verlos. + +Intenta imprimir en consola la lista de archivos en una carpeta. + +La librería `FS` también te será útil aquí. + +**Recuerda**: Para disminuir la complejidad de tu algoritmo +recursivo, te recomendamos utilizar la versión síncrona de +la función para leer directorios, `readdirSync`. + +### Une dos rutas + +Para poder acceder a carpetas y archivos será necesario que +indiques en qué lugar de tu computadora se encuentran, a esto +le llamamos **rutas**. + +Usa la librería nativa `path` para unir dos segmentos de ruta, +por ejemplo, si queremos unir: + +1) /home/Laboratoria/ +2) ./test + +El resultado sería: /home/Laboratoria/test + +### Recursividad + +Este proyecto se ha de resolver de forma casi natural con +**recursividad**. + +¿Por qué?. + +Porque no conocemos realmente cuantas carpetas y archivos +tendremos que recorrer antes de terminar. + +Si recibes una ruta de carpeta, no sabrás de ante mano si +dentro hay más carpetas o muchos archivos. + +Por ello, asegurate bien de entender de qué trata la +recursividad y ver algunos ejemplos. + +Entre los recursos de este proyecto hay un video que te ayudará. + +### Crea una promesa + +El valor de retorno de nuestra librería es una `Promesa`, +no un `Array`. + +Prueba leyendo sobre las promesas y creando una por tu +cuenta utilizando **new Promise()** + +Es importante que sepas qué es un **callback** pues las +promesas los utilizarán. diff --git a/Caperta/subcarpeta/README.md b/Caperta/subcarpeta/README.md new file mode 100644 index 0000000..d4df79b --- /dev/null +++ b/Caperta/subcarpeta/README.md @@ -0,0 +1,666 @@ +# Markdown Links + +## Índice + +* [1. Preámbulo](#1-preámbulo) +* [2. Resumen del proyecto](#2-resumen-del-proyecto) +* [3. Objetivos de aprendizaje](#3-objetivos-de-aprendizaje) +* [4. Consideraciones generales](#4-consideraciones-generales) +* [5. Criterios de aceptación mínimos del proyecto](#5-criterios-de-aceptación-mínimos-del-proyecto) +* [6. Entregables](#6-entregables) +* [7. Hacker edition](#7-hacker-edition) +* [8. Pistas, tips y lecturas complementarias](#8-pistas-tips-y-lecturas-complementarias) +* [9. Checklist](#9-checklist) +* [10. Achicando el problema](#10-achicando-el-problema) + +*** + +## 1. Preámbulo + +[Markdown](https://es.wikipedia.org/wiki/Markdown) es un lenguaje de marcado +ligero muy popular entre developers. Es usado en muchísimas plataformas que +manejan texto plano (GitHub, foros, blogs, ...) y es muy común +encontrar varios archivos en ese formato en cualquier tipo de repositorio +(empezando por el tradicional `README.md`). + +Estos archivos `Markdown` normalmente contienen _links_ (vínculos/ligas) que +muchas veces están rotos o ya no son válidos y eso perjudica mucho el valor de +la información que se quiere compartir. + +Dentro de una comunidad de código abierto, nos han propuesto crear una +herramienta usando [Node.js](https://nodejs.org/), que lea y analice archivos +en formato `Markdown`, para verificar los links que contengan y reportar +algunas estadísticas. + +![md-links](https://user-images.githubusercontent.com/110297/42118443-b7a5f1f0-7bc8-11e8-96ad-9cc5593715a6.jpg) + +## 2. Resumen del proyecto + +En este proyecto crearás una herramienta de línea de comando (CLI) así como tu +propia librería (o biblioteca - library) en JavaScript. + +En esta oportunidad nos alejamos un poco del navegador para construir un +programa que se ejecute usando Node.js. Aprenderemos sobre procesos +(`process.env`, `process.argv`, ...), cómo interactuar con el sistema archivos, +cómo hacer consultas de red, etc. + +[Node.js](https://nodejs.org/es/) es un entorno de ejecución para JavaScript +construido con el [motor de JavaScript V8 de Chrome](https://developers.google.com/v8/). +Esto nos va a permitir ejecutar JavaScript en el entorno del sistema operativo, +ya sea tu máquina o un servidor, lo cual nos abre las puertas para poder +interactuar con el sistema en sí, archivos, redes, ... + +Diseñar tu propia librería es una experiencia fundamental para cualquier +desarrollador porque que te obliga a pensar en la interfaz (API) de tus +_módulos_ y cómo será usado por otros developers. Debes tener especial +consideración en peculiaridades del lenguaje, convenciones y buenas prácticas. + +## 3. Objetivos de aprendizaje + +Reflexiona y luego marca los objetivos que has llegado a entender y aplicar en tu proyecto. Piensa en eso al decidir tu estrategia de trabajo. + +### JavaScript + +- [ ] **Diferenciar entre tipos de datos primitivos y no primitivos** + +- [ ] **Arrays (arreglos)** + +
Links

+ + * [Arreglos](https://curriculum.laboratoria.la/es/topics/javascript/04-arrays) + * [Array - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/) + * [Array.prototype.sort() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) + * [Array.prototype.forEach() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) + * [Array.prototype.map() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/map) + * [Array.prototype.filter() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) + * [Array.prototype.reduce() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) +

+ +- [ ] **Objetos (key, value)** + +
Links

+ + * [Objetos en JavaScript](https://curriculum.laboratoria.la/es/topics/javascript/05-objects/01-objects) +

+ +- [ ] **Uso de condicionales (if-else, switch, operador ternario, lógica booleana)** + +
Links

+ + * [Estructuras condicionales y repetitivas](https://curriculum.laboratoria.la/es/topics/javascript/02-flow-control/01-conditionals-and-loops) + * [Tomando decisiones en tu código — condicionales - MDN](https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/conditionals) +

+ +- [ ] **Funciones (params, args, return)** + +
Links

+ + * [Funciones (control de flujo)](https://curriculum.laboratoria.la/es/topics/javascript/02-flow-control/03-functions) + * [Funciones clásicas](https://curriculum.laboratoria.la/es/topics/javascript/03-functions/01-classic) + * [Arrow Functions](https://curriculum.laboratoria.la/es/topics/javascript/03-functions/02-arrow) + * [Funciones — bloques de código reutilizables - MDN](https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/Functions) +

+ +- [ ] **Recursión o recursividad** + +
Links

+ + * [Píldora recursión - YouTube Laboratoria Developers](https://www.youtube.com/watch?v=lPPgY3HLlhQ) + * [Recursión o Recursividad - Laboratoria Developers en Medium](https://medium.com/laboratoria-developers/recursi%C3%B3n-o-recursividad-ec8f1a359727) +

+ +- [ ] **Módulos de CommonJS** + +
Links

+ + * [Modules: CommonJS modules - Node.js Docs](https://nodejs.org/docs/latest/api/modules.html) +

+ +- [ ] **Diferenciar entre expresiones (expressions) y sentencias (statements)** + +- [ ] **Callbacks** + +
Links

+ + * [Función Callback - MDN](https://developer.mozilla.org/es/docs/Glossary/Callback_function) +

+ +- [ ] **Promesas** + +
Links

+ + * [Promise - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Promise) + * [How to Write a JavaScript Promise - freecodecamp (en inglés)](https://www.freecodecamp.org/news/how-to-write-a-javascript-promise-4ed8d44292b8/) +

+ +- [ ] **Pruebas unitarias (unit tests)** + +
Links

+ + * [Empezando con Jest - Documentación oficial](https://jestjs.io/docs/es-ES/getting-started) +

+ +- [ ] **Pruebas asíncronas** + +
Links

+ + * [Tests de código asincrónico con Jest - Documentación oficial](https://jestjs.io/docs/es-ES/asynchronous) +

+ +- [ ] **Uso de mocks y espías** + +
Links

+ + * [Manual Mocks con Jest - Documentación oficial](https://jestjs.io/docs/es-ES/manual-mocks) +

+ +- [ ] **Pruebas de compatibilidad en múltiples entornos de ejecución** + +- [ ] **Uso de linter (ESLINT)** + +- [ ] **Uso de identificadores descriptivos (Nomenclatura y Semántica)** + +### Node.js + +- [ ] **Instalar y usar módulos con npm** + +
Links

+ + * [Sitio oficial de npm (en inglés)](https://www.npmjs.com/) +

+ +- [ ] **Configuración de package.json** + +
Links

+ + * [package.json - Documentación oficial (en inglés)](https://docs.npmjs.com/files/package.json) +

+ +- [ ] **Configuración de npm-scripts** + +
Links

+ + * [scripts - Documentación oficial (en inglés)](https://docs.npmjs.com/misc/scripts) +

+ +- [ ] **process (env, argv, stdin-stdout-stderr, exit-code)** + +
Links

+ + * [Process - Documentación oficial (en inglés)](https://nodejs.org/api/process.html) +

+ +- [ ] **File system (fs, path)** + +
Links

+ + * [File system - Documentación oficial (en inglés)](https://nodejs.org/api/fs.html) + * [Path - Documentación oficial (en inglés)](https://nodejs.org/api/path.html) +

+ +### Control de Versiones (Git y GitHub) + +- [ ] **Git: Instalación y configuración** + +- [ ] **Git: Control de versiones con git (init, clone, add, commit, status, push, pull, remote)** + +- [ ] **Git: Integración de cambios entre ramas (branch, checkout, fetch, merge, reset, rebase, tag)** + +- [ ] **GitHub: Creación de cuenta y repos, configuración de llaves SSH** + +- [ ] **GitHub: Colaboración en Github (branches | forks | pull requests | code review | tags)** + +- [ ] **GitHub: Organización en Github (projects | issues | labels | milestones | releases)** + +### HTTP + +- [ ] **Consulta o petición (request) y respuesta (response).** + +
Links

+ + * [Generalidades del protocolo HTTP - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/Overview) + * [Mensajes HTTP - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/Messages) +

+ +- [ ] **Códigos de status de HTTP** + +
Links

+ + * [Códigos de estado de respuesta HTTP - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/Status) + * [The Complete Guide to Status Codes for Meaningful ReST APIs - dev.to](https://dev.to/khaosdoctor/the-complete-guide-to-status-codes-for-meaningful-rest-apis-1-5c5) +

+ +## 4. Consideraciones generales + +* Este proyecto se debe "resolver" de manera individual. + +* La **librería** y el **script ejecutable** (herramienta de línea de comando - + CLI) deben estar implementados en JavaScript para ser ejecutados con + Node.js. **Está permitido usar librerías externas**. + +* Tu módulo **debe ser instalable** via `npm install /md-links`. Este + módulo debe incluir tanto un _ejecutable_ que podamos invocar en la línea de + comando como una interfaz que podamos importar con `require` para usarlo + programáticamente. + +* Los **tests unitarios** deben cubrir un mínimo del 70% de _statements_, + _functions_, _lines_ y _branches_. Te recomendamos explorar [Jest](https://jestjs.io/) + para tus pruebas unitarias. + +* Para este proyecto **no está permitido** utilizar `async/await`. + +* Para este proyecto te sugerimos **no utilizar** la versión síncrona +de la función para leer archivos, `readFileSync`, y en cambio intentar +resolver este desafío de manera asíncrona. + +* Para este proyecto es **opcional** el uso de ES Modules `(import/export)`, en el + caso optes utilizarlo deberás de crear un script de `build` en el `package.json` + que los transforme en `requires` y `module.exports` con ayuda de **babel**. + +* Para disminuir la complejidad de tu algoritmo recursivo, te recomendamos +utilizar la versión síncrona de la función para leer directorios, `readdirSync`. + +## 5. Criterios de aceptación mínimos del proyecto + +Para comenzar este proyecto tendrás que hacer un **_fork_** y **_clonar_** este +repositorio. + +Antes de comenzar a codear, es necesario crear un **plan de acción**. Esto debería +quedar detallado en el `README.md` de tu repo y en una serie de **_issues_** +y **_milestones_** para priorizar y organizar el trabajo, y para poder hacer +seguimiento de tu progreso. + +Dentro de cada **_milestone_** se crearán y asignarán los **_issues_** que cada quien +considere necesarios. + +### Archivos del proyecto + +* `README.md` con descripción del módulo, instrucciones de instalación/uso, + documentación del API y ejemplos. Todo lo relevante para que cualquier + developer que quiera usar tu librería pueda hacerlo sin inconvenientes. +* `index.js`: Desde este archivo debes exportar **una** función (`mdLinks`). +* `package.json` con nombre, versión, descripción, autores, licencia, + dependencias, scripts (pretest, test, ...), main, bin +* `.editorconfig` con configuración para editores de texto. Este archivo no se + debe cambiar. +* `.eslintrc` con configuración para linter. Este archivo contiene una + configuración básica para ESLint, si deseas agregar reglas adicionales + como Airbnb deberás modificar este archivo. +* `.gitignore` para ignorar `node_modules` u otras carpetas que no deban + incluirse en control de versiones (`git`). +* `test/md-links.spec.js` debe contener los tests unitarios para la función + `mdLinks()`. Tu inplementación debe pasar estos tets. + +## Este proyecto consta de DOS partes + +### 1) JavaScript API + +El módulo debe poder **importarse** en otros scripts de Node.js y debe ofrecer la +siguiente interfaz: + +#### `mdLinks(path, options)` + +##### Argumentos + +* `path`: Ruta **absoluta** o **relativa** al **archivo** o **directorio**. +Si la ruta pasada es relativa, debe resolverse como relativa al directorio +desde donde se invoca node - _current working directory_). +* `options`: Un objeto con **únicamente** la siguiente propiedad: + - `validate`: Booleano que determina si se desea validar los links + encontrados. + +##### Valor de retorno + +La función debe **retornar una promesa** (`Promise`) que **resuelva a un arreglo** +(`Array`) de objetos (`Object`), donde cada objeto representa un link y contiene +las siguientes propiedades + +Con `validate:false` : + +* `href`: URL encontrada. +* `text`: Texto que aparecía dentro del link (`
`). +* `file`: Ruta del archivo donde se encontró el link. + +Con `validate:true` : + +* `href`: URL encontrada. +* `text`: Texto que aparecía dentro del link (``). +* `file`: Ruta del archivo donde se encontró el link. +* `status`: Código de respuesta HTTP. +* `ok`: Mensaje `fail` en caso de fallo u `ok` en caso de éxito. + +#### Ejemplo (resultados como comentarios) + +```js +const mdLinks = require("md-links"); + +mdLinks("./some/example.md") + .then(links => { + // => [{ href, text, file }, ...] + }) + .catch(console.error); + +mdLinks("./some/example.md", { validate: true }) + .then(links => { + // => [{ href, text, file, status, ok }, ...] + }) + .catch(console.error); + +mdLinks("./some/dir") + .then(links => { + // => [{ href, text, file }, ...] + }) + .catch(console.error); +``` + +### 2) CLI (Command Line Interface - Interfaz de Línea de Comando) + +El ejecutable de nuestra aplicación debe poder ejecutarse de la siguiente +manera a través de la **terminal**: + +`md-links [options]` + +Por ejemplo: + +```sh +$ md-links ./some/example.md +./some/example.md http://algo.com/2/3/ Link a algo +./some/example.md https://otra-cosa.net/algun-doc.html algún doc +./some/example.md http://google.com/ Google +``` + +El comportamiento por defecto no debe validar si las URLs responden ok o no, +solo debe identificar el archivo markdown (a partir de la ruta que recibe como +argumento), analizar el archivo Markdown e imprimir los links que vaya +encontrando, junto con la ruta del archivo donde aparece y el texto +que hay dentro del link (truncado a 50 caracteres). + +#### Options + +##### `--validate` + +Si pasamos la opción `--validate`, el módulo debe hacer una petición HTTP para +averiguar si el link funciona o no. Si el link resulta en una redirección a una +URL que responde ok, entonces consideraremos el link como ok. + +Por ejemplo: + +```sh +$ md-links ./some/example.md --validate +./some/example.md http://algo.com/2/3/ ok 200 Link a algo +./some/example.md https://otra-cosa.net/algun-doc.html fail 404 algún doc +./some/example.md http://google.com/ ok 301 Google +``` + +Vemos que el _output_ en este caso incluye la palabra `ok` o `fail` después de +la URL, así como el status de la respuesta recibida a la petición HTTP a dicha +URL. + +##### `--stats` + +Si pasamos la opción `--stats` el output (salida) será un texto con estadísticas +básicas sobre los links. + +```sh +$ md-links ./some/example.md --stats +Total: 3 +Unique: 3 +``` + +También podemos combinar `--stats` y `--validate` para obtener estadísticas que +necesiten de los resultados de la validación. + +```sh +$ md-links ./some/example.md --stats --validate +Total: 3 +Unique: 3 +Broken: 1 +``` + +## 6. Entregables + +Módulo instalable via `npm install /md-links`. Este módulo debe +incluir tanto **un ejecutable** como **una interfaz** que podamos importar con `require` +para usarlo programáticamente. + +## 7. Hacker edition + +Las secciones llamadas _Hacker Edition_ son **opcionales**. Si **terminaste** +con todo lo anterior y te queda tiempo, intenta completarlas. Así podrás +profundizar y/o ejercitar más sobre los objetivos de aprendizaje del proyecto. + +* Puedes agregar la propiedad `line` a cada objeto `link` indicando en qué línea + del archivo se encontró el link. +* Puedes agregar más estadísticas. +* Integración continua con Travis o Circle CI. + +*** + +## 8. Pistas, tips y lecturas complementarias + +### FAQs + +#### ¿Cómo hago para que mi módulo sea _instalable_ desde GitHub? + +Para que el módulo sea instalable desde GitHub solo tiene que: + +* Estar en un repo público de GitHub +* Contener un `package.json` válido + +Con el comando `npm install githubname/reponame` podemos instalar directamente +desde GitHub. Ver [docs oficiales de `npm install` acá](https://docs.npmjs.com/cli/install). + +Por ejemplo, el [`course-parser`](https://github.com/Laboratoria/course-parser) +que usamos para la currícula no está publicado en el registro público de NPM, +así que lo instalamos directamente desde GitHub con el comando `npm install +Laboratoria/course-parser`. + +### Sugerencias de implementación + +La implementación de este proyecto tiene varias partes: leer del sistema de +archivos, recibir argumentos a través de la línea de comando, analizar texto, +hacer consultas HTTP, ... y todas estas cosas pueden enfocarse de muchas formas, +tanto usando librerías como implementando en VanillaJS. + +Por poner un ejemplo, el _parseado_ (análisis) del markdown para extraer los +links podría plantearse de las siguientes maneras (todas válidas): + +* Usando un _módulo_ como [markdown-it](https://github.com/markdown-it/markdown-it), + que nos devuelve un arreglo de _tokens_ que podemos recorrer para identificar + los links. +* Siguiendo otro camino completamente, podríamos usar + [expresiones regulares (`RegExp`)](https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Regular_Expressions). +* También podríamos usar una combinación de varios _módulos_ (podría ser válido + transformar el markdown a HTML usando algo como [marked](https://github.com/markedjs/marked) + y de ahí extraer los link con una librería de DOM como [JSDOM](https://github.com/jsdom/jsdom) + o [Cheerio](https://github.com/cheeriojs/cheerio) entre otras). +* Usando un _custom renderer_ de [marked](https://github.com/markedjs/marked) + (`new marked.Renderer()`). + +No dudes en consultar a tus compañeras y coaches +si tienes dudas existenciales con respecto a estas decisiones. No existe una +"única" manera correcta :wink: + +### Tutoriales / NodeSchool workshoppers + +* [learnyounode](https://github.com/workshopper/learnyounode) +* [how-to-npm](https://github.com/workshopper/how-to-npm) +* [promise-it-wont-hurt](https://github.com/stevekane/promise-it-wont-hurt) + +### Otros recursos + +* [Acerca de Node.js - Documentación oficial](https://nodejs.org/es/about/) +* [Node.js file system - Documentación oficial](https://nodejs.org/api/fs.html) +* [Node.js http.get - Documentación oficial](https://nodejs.org/api/http.html#http_http_get_options_callback) +* [Node.js - Wikipedia](https://es.wikipedia.org/wiki/Node.js) +* [What exactly is Node.js? - freeCodeCamp](https://medium.freecodecamp.org/what-exactly-is-node-js-ae36e97449f5) +* [¿Qué es Node.js y para qué sirve? - drauta.com](https://www.drauta.com/que-es-nodejs-y-para-que-sirve) +* [¿Qué es Nodejs? Javascript en el Servidor - Fazt en YouTube](https://www.youtube.com/watch?v=WgSc1nv_4Gw) +* [¿Simplemente qué es Node.js? - IBM Developer Works, 2011](https://www.ibm.com/developerworks/ssa/opensource/library/os-nodejs/index.html) +* [Node.js y npm](https://www.genbeta.com/desarrollo/node-js-y-npm) +* [Módulos, librerías, paquetes, frameworks... ¿cuál es la diferencia?](http://community.laboratoria.la/t/modulos-librerias-paquetes-frameworks-cual-es-la-diferencia/175) +* [Asíncronía en js](https://carlosazaustre.es/manejando-la-asincronia-en-javascript) +* [NPM](https://docs.npmjs.com/getting-started/what-is-npm) +* [Publicar packpage](https://docs.npmjs.com/getting-started/publishing-npm-packages) +* [Crear módulos en Node.js](https://docs.npmjs.com/getting-started/publishing-npm-packages) +* [Leer un archivo](https://nodejs.org/api/fs.html#fs_fs_readfile_path_options_callback) +* [Leer un directorio](https://nodejs.org/api/fs.html#fs_fs_readdir_path_options_callback) +* [Path](https://nodejs.org/api/path.html) +* [Linea de comando CLI](https://medium.com/netscape/a-guide-to-create-a-nodejs-command-line-package-c2166ad0452e) + +## 9. Checklist + +### General + +* [ ] Puede instalarse via `npm install --global /md-links` + +### `README.md` + +* [ ] Un board con el backlog para la implementación de la librería. +* [ ] Documentación técnica de la librería. +* [ ] Guía de uso e instalación de la librería + +### API `mdLinks(path, opts)` + +* [ ] El módulo exporta una función con la interfaz (API) esperada. +* [ ] Implementa soporte para archivo individual +* [ ] Implementa soporte para directorios +* [ ] Implementa `options.validate` + +### CLI + +* [ ] Expone ejecutable `md-links` en el path (configurado en `package.json`) +* [ ] Se ejecuta sin errores / output esperado +* [ ] Implementa `--validate` +* [ ] Implementa `--stats` + +### Pruebas / tests + +* [ ] Pruebas unitarias cubren un mínimo del 70% de statements, functions, + lines, y branches. +* [ ] Pasa tests (y linters) (`npm test`). + +## 10. Achicando el problema + +Un "superpoder" que esperamos puedas desarrollar durante el bootcamp +es el de definir "mini-proyectos" que te acerquen paso a paso a +la solución del "gran proyecto". Es el equivalente a comenzar armando +esquinas o bordes del rompecabezas/puzzle sin saber necesariamente +cómo encajarán al final. Déjate llevar y explora. + +Estas son algunas sugerencias: + +### Empieza con un diagrama de flujo + +Este proyecto es distinto de los que has venido trabajando hasta ahora +dado que no hay una interfaz web, todo se desarrollará en tu editor y +consola/terminal. + +Es por ello que, para visualizar mejor lo que tendrás que hacer +y planificar tus tareas y objetivos, es recomendable hacer un +`diagrama de flujo`. + +Si nunca has hecho un diagrama de flujo revisa este [recurso](https://www.youtube.com/watch?v=Lub5qOmY4JQ). + +Una alternativa al diagrama de flujo puede ser el `pseudocódigo`. + +### Planificación + +En este proyecto te recomendamos usar la herramienta de planificación +y organización de GitHub llamada **Github Projects**. + +Mediante **issues** y **milestones** podrás organizar y planificar +tareas y objetivos concretos. + +Tomando en consideración los **entregables** del proyecto, el +[9. Checklist](#9-checklist) y los **pasos** que definiste en tu +`diagrama de flujo`, crea tu planificación en GitHub Projects. + +### Antes de codear + +En esta ocasión estarás trabajando en **NodeJS**, asegúrate +de saber para qué sirve y sus consideraciones. + +En particular, deberás decidir desde un comienzo si usarás +`ES Modules`, es decir, **import/export**, ó, por el contrario, +`CommonJS Modules`, es decir, **require/module.exports**. + +Asegurate de tener clara esta decisión desde un inicio para +que no encuentres problemas más adelante. + +### Lee un archivo + +Como primer reto, puedes tratar de leer un solo archivo con +una ruta fija e imprimir su contenido en la consola con un `console.log`. + +La librería nativa `FS` (FileSystem) te será de utilidad. + +**Recuerda**: Te sugerimos **no utilizar** la versión síncrona +de la función para leer archivos, `readFileSync`, y en cambio +intentar resolver ese desafío de manera asíncrona. + +### Averigua la extensión de un archivo + +Ya sabiendo leer un archivo, aventúrate a conocer cual +es su extensión. + +Recuerda, las extensiones son esas letras al final del +nombre de un archivo, por ejemplo: .js, .txt, .doc, etc + +Aquí también podrá ser útil `FS`. + +### Obtén el contenido de un directorio + +Este proyecto consiste en buscar archivos, pero para eso, +primero debes poder verlos. + +Intenta imprimir en consola la lista de archivos en una carpeta. + +La librería `FS` también te será útil aquí. + +**Recuerda**: Para disminuir la complejidad de tu algoritmo +recursivo, te recomendamos utilizar la versión síncrona de +la función para leer directorios, `readdirSync`. + +### Une dos rutas + +Para poder acceder a carpetas y archivos será necesario que +indiques en qué lugar de tu computadora se encuentran, a esto +le llamamos **rutas**. + +Usa la librería nativa `path` para unir dos segmentos de ruta, +por ejemplo, si queremos unir: + +1) /home/Laboratoria/ +2) ./test + +El resultado sería: /home/Laboratoria/test + +### Recursividad + +Este proyecto se ha de resolver de forma casi natural con +**recursividad**. + +¿Por qué?. + +Porque no conocemos realmente cuantas carpetas y archivos +tendremos que recorrer antes de terminar. + +Si recibes una ruta de carpeta, no sabrás de ante mano si +dentro hay más carpetas o muchos archivos. + +Por ello, asegurate bien de entender de qué trata la +recursividad y ver algunos ejemplos. + +Entre los recursos de este proyecto hay un video que te ayudará. + +### Crea una promesa + +El valor de retorno de nuestra librería es una `Promesa`, +no un `Array`. + +Prueba leyendo sobre las promesas y creando una por tu +cuenta utilizando **new Promise()** + +Es importante que sepas qué es un **callback** pues las +promesas los utilizarán. diff --git a/Caperta/subcarpeta/media-Capera/README.md b/Caperta/subcarpeta/media-Capera/README.md new file mode 100644 index 0000000..d4df79b --- /dev/null +++ b/Caperta/subcarpeta/media-Capera/README.md @@ -0,0 +1,666 @@ +# Markdown Links + +## Índice + +* [1. Preámbulo](#1-preámbulo) +* [2. Resumen del proyecto](#2-resumen-del-proyecto) +* [3. Objetivos de aprendizaje](#3-objetivos-de-aprendizaje) +* [4. Consideraciones generales](#4-consideraciones-generales) +* [5. Criterios de aceptación mínimos del proyecto](#5-criterios-de-aceptación-mínimos-del-proyecto) +* [6. Entregables](#6-entregables) +* [7. Hacker edition](#7-hacker-edition) +* [8. Pistas, tips y lecturas complementarias](#8-pistas-tips-y-lecturas-complementarias) +* [9. Checklist](#9-checklist) +* [10. Achicando el problema](#10-achicando-el-problema) + +*** + +## 1. Preámbulo + +[Markdown](https://es.wikipedia.org/wiki/Markdown) es un lenguaje de marcado +ligero muy popular entre developers. Es usado en muchísimas plataformas que +manejan texto plano (GitHub, foros, blogs, ...) y es muy común +encontrar varios archivos en ese formato en cualquier tipo de repositorio +(empezando por el tradicional `README.md`). + +Estos archivos `Markdown` normalmente contienen _links_ (vínculos/ligas) que +muchas veces están rotos o ya no son válidos y eso perjudica mucho el valor de +la información que se quiere compartir. + +Dentro de una comunidad de código abierto, nos han propuesto crear una +herramienta usando [Node.js](https://nodejs.org/), que lea y analice archivos +en formato `Markdown`, para verificar los links que contengan y reportar +algunas estadísticas. + +![md-links](https://user-images.githubusercontent.com/110297/42118443-b7a5f1f0-7bc8-11e8-96ad-9cc5593715a6.jpg) + +## 2. Resumen del proyecto + +En este proyecto crearás una herramienta de línea de comando (CLI) así como tu +propia librería (o biblioteca - library) en JavaScript. + +En esta oportunidad nos alejamos un poco del navegador para construir un +programa que se ejecute usando Node.js. Aprenderemos sobre procesos +(`process.env`, `process.argv`, ...), cómo interactuar con el sistema archivos, +cómo hacer consultas de red, etc. + +[Node.js](https://nodejs.org/es/) es un entorno de ejecución para JavaScript +construido con el [motor de JavaScript V8 de Chrome](https://developers.google.com/v8/). +Esto nos va a permitir ejecutar JavaScript en el entorno del sistema operativo, +ya sea tu máquina o un servidor, lo cual nos abre las puertas para poder +interactuar con el sistema en sí, archivos, redes, ... + +Diseñar tu propia librería es una experiencia fundamental para cualquier +desarrollador porque que te obliga a pensar en la interfaz (API) de tus +_módulos_ y cómo será usado por otros developers. Debes tener especial +consideración en peculiaridades del lenguaje, convenciones y buenas prácticas. + +## 3. Objetivos de aprendizaje + +Reflexiona y luego marca los objetivos que has llegado a entender y aplicar en tu proyecto. Piensa en eso al decidir tu estrategia de trabajo. + +### JavaScript + +- [ ] **Diferenciar entre tipos de datos primitivos y no primitivos** + +- [ ] **Arrays (arreglos)** + +
Links

+ + * [Arreglos](https://curriculum.laboratoria.la/es/topics/javascript/04-arrays) + * [Array - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/) + * [Array.prototype.sort() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) + * [Array.prototype.forEach() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) + * [Array.prototype.map() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/map) + * [Array.prototype.filter() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) + * [Array.prototype.reduce() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) +

+ +- [ ] **Objetos (key, value)** + +
Links

+ + * [Objetos en JavaScript](https://curriculum.laboratoria.la/es/topics/javascript/05-objects/01-objects) +

+ +- [ ] **Uso de condicionales (if-else, switch, operador ternario, lógica booleana)** + +
Links

+ + * [Estructuras condicionales y repetitivas](https://curriculum.laboratoria.la/es/topics/javascript/02-flow-control/01-conditionals-and-loops) + * [Tomando decisiones en tu código — condicionales - MDN](https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/conditionals) +

+ +- [ ] **Funciones (params, args, return)** + +
Links

+ + * [Funciones (control de flujo)](https://curriculum.laboratoria.la/es/topics/javascript/02-flow-control/03-functions) + * [Funciones clásicas](https://curriculum.laboratoria.la/es/topics/javascript/03-functions/01-classic) + * [Arrow Functions](https://curriculum.laboratoria.la/es/topics/javascript/03-functions/02-arrow) + * [Funciones — bloques de código reutilizables - MDN](https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/Functions) +

+ +- [ ] **Recursión o recursividad** + +
Links

+ + * [Píldora recursión - YouTube Laboratoria Developers](https://www.youtube.com/watch?v=lPPgY3HLlhQ) + * [Recursión o Recursividad - Laboratoria Developers en Medium](https://medium.com/laboratoria-developers/recursi%C3%B3n-o-recursividad-ec8f1a359727) +

+ +- [ ] **Módulos de CommonJS** + +
Links

+ + * [Modules: CommonJS modules - Node.js Docs](https://nodejs.org/docs/latest/api/modules.html) +

+ +- [ ] **Diferenciar entre expresiones (expressions) y sentencias (statements)** + +- [ ] **Callbacks** + +
Links

+ + * [Función Callback - MDN](https://developer.mozilla.org/es/docs/Glossary/Callback_function) +

+ +- [ ] **Promesas** + +
Links

+ + * [Promise - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Promise) + * [How to Write a JavaScript Promise - freecodecamp (en inglés)](https://www.freecodecamp.org/news/how-to-write-a-javascript-promise-4ed8d44292b8/) +

+ +- [ ] **Pruebas unitarias (unit tests)** + +
Links

+ + * [Empezando con Jest - Documentación oficial](https://jestjs.io/docs/es-ES/getting-started) +

+ +- [ ] **Pruebas asíncronas** + +
Links

+ + * [Tests de código asincrónico con Jest - Documentación oficial](https://jestjs.io/docs/es-ES/asynchronous) +

+ +- [ ] **Uso de mocks y espías** + +
Links

+ + * [Manual Mocks con Jest - Documentación oficial](https://jestjs.io/docs/es-ES/manual-mocks) +

+ +- [ ] **Pruebas de compatibilidad en múltiples entornos de ejecución** + +- [ ] **Uso de linter (ESLINT)** + +- [ ] **Uso de identificadores descriptivos (Nomenclatura y Semántica)** + +### Node.js + +- [ ] **Instalar y usar módulos con npm** + +
Links

+ + * [Sitio oficial de npm (en inglés)](https://www.npmjs.com/) +

+ +- [ ] **Configuración de package.json** + +
Links

+ + * [package.json - Documentación oficial (en inglés)](https://docs.npmjs.com/files/package.json) +

+ +- [ ] **Configuración de npm-scripts** + +
Links

+ + * [scripts - Documentación oficial (en inglés)](https://docs.npmjs.com/misc/scripts) +

+ +- [ ] **process (env, argv, stdin-stdout-stderr, exit-code)** + +
Links

+ + * [Process - Documentación oficial (en inglés)](https://nodejs.org/api/process.html) +

+ +- [ ] **File system (fs, path)** + +
Links

+ + * [File system - Documentación oficial (en inglés)](https://nodejs.org/api/fs.html) + * [Path - Documentación oficial (en inglés)](https://nodejs.org/api/path.html) +

+ +### Control de Versiones (Git y GitHub) + +- [ ] **Git: Instalación y configuración** + +- [ ] **Git: Control de versiones con git (init, clone, add, commit, status, push, pull, remote)** + +- [ ] **Git: Integración de cambios entre ramas (branch, checkout, fetch, merge, reset, rebase, tag)** + +- [ ] **GitHub: Creación de cuenta y repos, configuración de llaves SSH** + +- [ ] **GitHub: Colaboración en Github (branches | forks | pull requests | code review | tags)** + +- [ ] **GitHub: Organización en Github (projects | issues | labels | milestones | releases)** + +### HTTP + +- [ ] **Consulta o petición (request) y respuesta (response).** + +
Links

+ + * [Generalidades del protocolo HTTP - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/Overview) + * [Mensajes HTTP - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/Messages) +

+ +- [ ] **Códigos de status de HTTP** + +
Links

+ + * [Códigos de estado de respuesta HTTP - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/Status) + * [The Complete Guide to Status Codes for Meaningful ReST APIs - dev.to](https://dev.to/khaosdoctor/the-complete-guide-to-status-codes-for-meaningful-rest-apis-1-5c5) +

+ +## 4. Consideraciones generales + +* Este proyecto se debe "resolver" de manera individual. + +* La **librería** y el **script ejecutable** (herramienta de línea de comando - + CLI) deben estar implementados en JavaScript para ser ejecutados con + Node.js. **Está permitido usar librerías externas**. + +* Tu módulo **debe ser instalable** via `npm install /md-links`. Este + módulo debe incluir tanto un _ejecutable_ que podamos invocar en la línea de + comando como una interfaz que podamos importar con `require` para usarlo + programáticamente. + +* Los **tests unitarios** deben cubrir un mínimo del 70% de _statements_, + _functions_, _lines_ y _branches_. Te recomendamos explorar [Jest](https://jestjs.io/) + para tus pruebas unitarias. + +* Para este proyecto **no está permitido** utilizar `async/await`. + +* Para este proyecto te sugerimos **no utilizar** la versión síncrona +de la función para leer archivos, `readFileSync`, y en cambio intentar +resolver este desafío de manera asíncrona. + +* Para este proyecto es **opcional** el uso de ES Modules `(import/export)`, en el + caso optes utilizarlo deberás de crear un script de `build` en el `package.json` + que los transforme en `requires` y `module.exports` con ayuda de **babel**. + +* Para disminuir la complejidad de tu algoritmo recursivo, te recomendamos +utilizar la versión síncrona de la función para leer directorios, `readdirSync`. + +## 5. Criterios de aceptación mínimos del proyecto + +Para comenzar este proyecto tendrás que hacer un **_fork_** y **_clonar_** este +repositorio. + +Antes de comenzar a codear, es necesario crear un **plan de acción**. Esto debería +quedar detallado en el `README.md` de tu repo y en una serie de **_issues_** +y **_milestones_** para priorizar y organizar el trabajo, y para poder hacer +seguimiento de tu progreso. + +Dentro de cada **_milestone_** se crearán y asignarán los **_issues_** que cada quien +considere necesarios. + +### Archivos del proyecto + +* `README.md` con descripción del módulo, instrucciones de instalación/uso, + documentación del API y ejemplos. Todo lo relevante para que cualquier + developer que quiera usar tu librería pueda hacerlo sin inconvenientes. +* `index.js`: Desde este archivo debes exportar **una** función (`mdLinks`). +* `package.json` con nombre, versión, descripción, autores, licencia, + dependencias, scripts (pretest, test, ...), main, bin +* `.editorconfig` con configuración para editores de texto. Este archivo no se + debe cambiar. +* `.eslintrc` con configuración para linter. Este archivo contiene una + configuración básica para ESLint, si deseas agregar reglas adicionales + como Airbnb deberás modificar este archivo. +* `.gitignore` para ignorar `node_modules` u otras carpetas que no deban + incluirse en control de versiones (`git`). +* `test/md-links.spec.js` debe contener los tests unitarios para la función + `mdLinks()`. Tu inplementación debe pasar estos tets. + +## Este proyecto consta de DOS partes + +### 1) JavaScript API + +El módulo debe poder **importarse** en otros scripts de Node.js y debe ofrecer la +siguiente interfaz: + +#### `mdLinks(path, options)` + +##### Argumentos + +* `path`: Ruta **absoluta** o **relativa** al **archivo** o **directorio**. +Si la ruta pasada es relativa, debe resolverse como relativa al directorio +desde donde se invoca node - _current working directory_). +* `options`: Un objeto con **únicamente** la siguiente propiedad: + - `validate`: Booleano que determina si se desea validar los links + encontrados. + +##### Valor de retorno + +La función debe **retornar una promesa** (`Promise`) que **resuelva a un arreglo** +(`Array`) de objetos (`Object`), donde cada objeto representa un link y contiene +las siguientes propiedades + +Con `validate:false` : + +* `href`: URL encontrada. +* `text`: Texto que aparecía dentro del link (`
`). +* `file`: Ruta del archivo donde se encontró el link. + +Con `validate:true` : + +* `href`: URL encontrada. +* `text`: Texto que aparecía dentro del link (``). +* `file`: Ruta del archivo donde se encontró el link. +* `status`: Código de respuesta HTTP. +* `ok`: Mensaje `fail` en caso de fallo u `ok` en caso de éxito. + +#### Ejemplo (resultados como comentarios) + +```js +const mdLinks = require("md-links"); + +mdLinks("./some/example.md") + .then(links => { + // => [{ href, text, file }, ...] + }) + .catch(console.error); + +mdLinks("./some/example.md", { validate: true }) + .then(links => { + // => [{ href, text, file, status, ok }, ...] + }) + .catch(console.error); + +mdLinks("./some/dir") + .then(links => { + // => [{ href, text, file }, ...] + }) + .catch(console.error); +``` + +### 2) CLI (Command Line Interface - Interfaz de Línea de Comando) + +El ejecutable de nuestra aplicación debe poder ejecutarse de la siguiente +manera a través de la **terminal**: + +`md-links [options]` + +Por ejemplo: + +```sh +$ md-links ./some/example.md +./some/example.md http://algo.com/2/3/ Link a algo +./some/example.md https://otra-cosa.net/algun-doc.html algún doc +./some/example.md http://google.com/ Google +``` + +El comportamiento por defecto no debe validar si las URLs responden ok o no, +solo debe identificar el archivo markdown (a partir de la ruta que recibe como +argumento), analizar el archivo Markdown e imprimir los links que vaya +encontrando, junto con la ruta del archivo donde aparece y el texto +que hay dentro del link (truncado a 50 caracteres). + +#### Options + +##### `--validate` + +Si pasamos la opción `--validate`, el módulo debe hacer una petición HTTP para +averiguar si el link funciona o no. Si el link resulta en una redirección a una +URL que responde ok, entonces consideraremos el link como ok. + +Por ejemplo: + +```sh +$ md-links ./some/example.md --validate +./some/example.md http://algo.com/2/3/ ok 200 Link a algo +./some/example.md https://otra-cosa.net/algun-doc.html fail 404 algún doc +./some/example.md http://google.com/ ok 301 Google +``` + +Vemos que el _output_ en este caso incluye la palabra `ok` o `fail` después de +la URL, así como el status de la respuesta recibida a la petición HTTP a dicha +URL. + +##### `--stats` + +Si pasamos la opción `--stats` el output (salida) será un texto con estadísticas +básicas sobre los links. + +```sh +$ md-links ./some/example.md --stats +Total: 3 +Unique: 3 +``` + +También podemos combinar `--stats` y `--validate` para obtener estadísticas que +necesiten de los resultados de la validación. + +```sh +$ md-links ./some/example.md --stats --validate +Total: 3 +Unique: 3 +Broken: 1 +``` + +## 6. Entregables + +Módulo instalable via `npm install /md-links`. Este módulo debe +incluir tanto **un ejecutable** como **una interfaz** que podamos importar con `require` +para usarlo programáticamente. + +## 7. Hacker edition + +Las secciones llamadas _Hacker Edition_ son **opcionales**. Si **terminaste** +con todo lo anterior y te queda tiempo, intenta completarlas. Así podrás +profundizar y/o ejercitar más sobre los objetivos de aprendizaje del proyecto. + +* Puedes agregar la propiedad `line` a cada objeto `link` indicando en qué línea + del archivo se encontró el link. +* Puedes agregar más estadísticas. +* Integración continua con Travis o Circle CI. + +*** + +## 8. Pistas, tips y lecturas complementarias + +### FAQs + +#### ¿Cómo hago para que mi módulo sea _instalable_ desde GitHub? + +Para que el módulo sea instalable desde GitHub solo tiene que: + +* Estar en un repo público de GitHub +* Contener un `package.json` válido + +Con el comando `npm install githubname/reponame` podemos instalar directamente +desde GitHub. Ver [docs oficiales de `npm install` acá](https://docs.npmjs.com/cli/install). + +Por ejemplo, el [`course-parser`](https://github.com/Laboratoria/course-parser) +que usamos para la currícula no está publicado en el registro público de NPM, +así que lo instalamos directamente desde GitHub con el comando `npm install +Laboratoria/course-parser`. + +### Sugerencias de implementación + +La implementación de este proyecto tiene varias partes: leer del sistema de +archivos, recibir argumentos a través de la línea de comando, analizar texto, +hacer consultas HTTP, ... y todas estas cosas pueden enfocarse de muchas formas, +tanto usando librerías como implementando en VanillaJS. + +Por poner un ejemplo, el _parseado_ (análisis) del markdown para extraer los +links podría plantearse de las siguientes maneras (todas válidas): + +* Usando un _módulo_ como [markdown-it](https://github.com/markdown-it/markdown-it), + que nos devuelve un arreglo de _tokens_ que podemos recorrer para identificar + los links. +* Siguiendo otro camino completamente, podríamos usar + [expresiones regulares (`RegExp`)](https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Regular_Expressions). +* También podríamos usar una combinación de varios _módulos_ (podría ser válido + transformar el markdown a HTML usando algo como [marked](https://github.com/markedjs/marked) + y de ahí extraer los link con una librería de DOM como [JSDOM](https://github.com/jsdom/jsdom) + o [Cheerio](https://github.com/cheeriojs/cheerio) entre otras). +* Usando un _custom renderer_ de [marked](https://github.com/markedjs/marked) + (`new marked.Renderer()`). + +No dudes en consultar a tus compañeras y coaches +si tienes dudas existenciales con respecto a estas decisiones. No existe una +"única" manera correcta :wink: + +### Tutoriales / NodeSchool workshoppers + +* [learnyounode](https://github.com/workshopper/learnyounode) +* [how-to-npm](https://github.com/workshopper/how-to-npm) +* [promise-it-wont-hurt](https://github.com/stevekane/promise-it-wont-hurt) + +### Otros recursos + +* [Acerca de Node.js - Documentación oficial](https://nodejs.org/es/about/) +* [Node.js file system - Documentación oficial](https://nodejs.org/api/fs.html) +* [Node.js http.get - Documentación oficial](https://nodejs.org/api/http.html#http_http_get_options_callback) +* [Node.js - Wikipedia](https://es.wikipedia.org/wiki/Node.js) +* [What exactly is Node.js? - freeCodeCamp](https://medium.freecodecamp.org/what-exactly-is-node-js-ae36e97449f5) +* [¿Qué es Node.js y para qué sirve? - drauta.com](https://www.drauta.com/que-es-nodejs-y-para-que-sirve) +* [¿Qué es Nodejs? Javascript en el Servidor - Fazt en YouTube](https://www.youtube.com/watch?v=WgSc1nv_4Gw) +* [¿Simplemente qué es Node.js? - IBM Developer Works, 2011](https://www.ibm.com/developerworks/ssa/opensource/library/os-nodejs/index.html) +* [Node.js y npm](https://www.genbeta.com/desarrollo/node-js-y-npm) +* [Módulos, librerías, paquetes, frameworks... ¿cuál es la diferencia?](http://community.laboratoria.la/t/modulos-librerias-paquetes-frameworks-cual-es-la-diferencia/175) +* [Asíncronía en js](https://carlosazaustre.es/manejando-la-asincronia-en-javascript) +* [NPM](https://docs.npmjs.com/getting-started/what-is-npm) +* [Publicar packpage](https://docs.npmjs.com/getting-started/publishing-npm-packages) +* [Crear módulos en Node.js](https://docs.npmjs.com/getting-started/publishing-npm-packages) +* [Leer un archivo](https://nodejs.org/api/fs.html#fs_fs_readfile_path_options_callback) +* [Leer un directorio](https://nodejs.org/api/fs.html#fs_fs_readdir_path_options_callback) +* [Path](https://nodejs.org/api/path.html) +* [Linea de comando CLI](https://medium.com/netscape/a-guide-to-create-a-nodejs-command-line-package-c2166ad0452e) + +## 9. Checklist + +### General + +* [ ] Puede instalarse via `npm install --global /md-links` + +### `README.md` + +* [ ] Un board con el backlog para la implementación de la librería. +* [ ] Documentación técnica de la librería. +* [ ] Guía de uso e instalación de la librería + +### API `mdLinks(path, opts)` + +* [ ] El módulo exporta una función con la interfaz (API) esperada. +* [ ] Implementa soporte para archivo individual +* [ ] Implementa soporte para directorios +* [ ] Implementa `options.validate` + +### CLI + +* [ ] Expone ejecutable `md-links` en el path (configurado en `package.json`) +* [ ] Se ejecuta sin errores / output esperado +* [ ] Implementa `--validate` +* [ ] Implementa `--stats` + +### Pruebas / tests + +* [ ] Pruebas unitarias cubren un mínimo del 70% de statements, functions, + lines, y branches. +* [ ] Pasa tests (y linters) (`npm test`). + +## 10. Achicando el problema + +Un "superpoder" que esperamos puedas desarrollar durante el bootcamp +es el de definir "mini-proyectos" que te acerquen paso a paso a +la solución del "gran proyecto". Es el equivalente a comenzar armando +esquinas o bordes del rompecabezas/puzzle sin saber necesariamente +cómo encajarán al final. Déjate llevar y explora. + +Estas son algunas sugerencias: + +### Empieza con un diagrama de flujo + +Este proyecto es distinto de los que has venido trabajando hasta ahora +dado que no hay una interfaz web, todo se desarrollará en tu editor y +consola/terminal. + +Es por ello que, para visualizar mejor lo que tendrás que hacer +y planificar tus tareas y objetivos, es recomendable hacer un +`diagrama de flujo`. + +Si nunca has hecho un diagrama de flujo revisa este [recurso](https://www.youtube.com/watch?v=Lub5qOmY4JQ). + +Una alternativa al diagrama de flujo puede ser el `pseudocódigo`. + +### Planificación + +En este proyecto te recomendamos usar la herramienta de planificación +y organización de GitHub llamada **Github Projects**. + +Mediante **issues** y **milestones** podrás organizar y planificar +tareas y objetivos concretos. + +Tomando en consideración los **entregables** del proyecto, el +[9. Checklist](#9-checklist) y los **pasos** que definiste en tu +`diagrama de flujo`, crea tu planificación en GitHub Projects. + +### Antes de codear + +En esta ocasión estarás trabajando en **NodeJS**, asegúrate +de saber para qué sirve y sus consideraciones. + +En particular, deberás decidir desde un comienzo si usarás +`ES Modules`, es decir, **import/export**, ó, por el contrario, +`CommonJS Modules`, es decir, **require/module.exports**. + +Asegurate de tener clara esta decisión desde un inicio para +que no encuentres problemas más adelante. + +### Lee un archivo + +Como primer reto, puedes tratar de leer un solo archivo con +una ruta fija e imprimir su contenido en la consola con un `console.log`. + +La librería nativa `FS` (FileSystem) te será de utilidad. + +**Recuerda**: Te sugerimos **no utilizar** la versión síncrona +de la función para leer archivos, `readFileSync`, y en cambio +intentar resolver ese desafío de manera asíncrona. + +### Averigua la extensión de un archivo + +Ya sabiendo leer un archivo, aventúrate a conocer cual +es su extensión. + +Recuerda, las extensiones son esas letras al final del +nombre de un archivo, por ejemplo: .js, .txt, .doc, etc + +Aquí también podrá ser útil `FS`. + +### Obtén el contenido de un directorio + +Este proyecto consiste en buscar archivos, pero para eso, +primero debes poder verlos. + +Intenta imprimir en consola la lista de archivos en una carpeta. + +La librería `FS` también te será útil aquí. + +**Recuerda**: Para disminuir la complejidad de tu algoritmo +recursivo, te recomendamos utilizar la versión síncrona de +la función para leer directorios, `readdirSync`. + +### Une dos rutas + +Para poder acceder a carpetas y archivos será necesario que +indiques en qué lugar de tu computadora se encuentran, a esto +le llamamos **rutas**. + +Usa la librería nativa `path` para unir dos segmentos de ruta, +por ejemplo, si queremos unir: + +1) /home/Laboratoria/ +2) ./test + +El resultado sería: /home/Laboratoria/test + +### Recursividad + +Este proyecto se ha de resolver de forma casi natural con +**recursividad**. + +¿Por qué?. + +Porque no conocemos realmente cuantas carpetas y archivos +tendremos que recorrer antes de terminar. + +Si recibes una ruta de carpeta, no sabrás de ante mano si +dentro hay más carpetas o muchos archivos. + +Por ello, asegurate bien de entender de qué trata la +recursividad y ver algunos ejemplos. + +Entre los recursos de este proyecto hay un video que te ayudará. + +### Crea una promesa + +El valor de retorno de nuestra librería es una `Promesa`, +no un `Array`. + +Prueba leyendo sobre las promesas y creando una por tu +cuenta utilizando **new Promise()** + +Es importante que sepas qué es un **callback** pues las +promesas los utilizarán. diff --git a/app.js b/app.js index 29644ee..81a3026 100644 --- a/app.js +++ b/app.js @@ -1,5 +1,7 @@ const fs = require('fs'); const path = require('path'); +const axios = require('axios'); +const mdFiles = []; // regex para ver si es ruta absoluta const regEx = /^(\/|[A-Za-z]:\\)/; @@ -16,25 +18,87 @@ const changeToAbsolute = (ruta) => { } +/*const checkPath = (ruta) => { + + const files = fs.readdirSync(ruta); + files.forEach(file => { + const filePath = path.join(ruta, file) + //console.log("filepath",filePath); + const stats = fs.lstatSync(filePath); + // console.log("fuera", stats) + //console.log("extencion", path.extname(filePath) ) + if(stats.isDirectory()){ + checkPath(filePath); + } else if(stats.isFile() && path.extname(filePath) === '.md'){ + mdFiles.push(filePath); + } + }); + return mdFiles; +} */ +const checkPath = (dir) => { + const stats = fs.lstatSync(dir); + if (stats.isFile() && path.extname(dir) === '.md') { + mdFiles.push(dir); + } else if (stats.isDirectory()) { + const files = fs.readdirSync(dir); + files.forEach(file => { + const filePath = path.join(dir, file); + checkPath(filePath); + }); + } + return mdFiles; +} + + -const idDirFil = (path) => { - -fs.lstat(path, (err, stats) => { - console.log("que es eto", stats); + + + + + + + +//Función para leer los archivos +/* const readFiles = (path)=>{ + fs.readFile(path, 'utf8', (err, data) => { if (err) { console.error(err); - } else if (stats.isDirectory()) { + return err; + } + console.log("¿estás leyendo archivos?",data); - console.log('Es una carpeta',stats.isDirectory()); - } else if (stats.isFile()) { - path. - console.log('Es un archivo', stats.isFile()); - } else { - console.log('No es ni una carpeta ni un archivo'); + }); + }*/ + + +/*const mdFiles = []; + +function checkPath(dir) { + fs.lstat(dir, (err, stats) => { + if (err) { + console.error(err); + return; + } + console.log("fills", path.extname(dir)) + console.log("file. md", ) + if (stats.isFile() && path.extname(dir) === '.md') { + console.log(" dir ", dir); + } else if (stats.isDirectory()) { + fs.readdir(dir, (err, files) => { + if (err) { + console.error(err); + return; + } + + + }); } }); -} +} */ + + + @@ -60,14 +124,14 @@ const mdLinks = (path) => { console.log("absoluta booleano", isAbsolute(path)); // path == relativa return new Promise((resolve, reject) => { - // resolve => relativa al directorio desde donde se invoca node + // resolve => relativa al rutaectorio desde donde se invoca node // istat para saber si es una carpeta fs.lstat(path, (err, stats) => { if (err) { console.error(err); - } else if (stats.isDirectory()) { + } else if (stats.isrutaectory()) { console.log('Es una carpeta'); } else if (stats.isFile()) { console.log('Es un archivo'); @@ -78,8 +142,8 @@ const mdLinks = (path) => { // funcion - chequear o convertir una ruta absoluta - // probar si esa ruta absoluta es una archivo o directorio - // Si es un directorio filtrar los archivos md. arry filtrado + // probar si esa ruta absoluta es una archivo o rutaectorio + // Si es un rutaectorio filtrar los archivos md. arry filtrado @@ -89,6 +153,6 @@ const mdLinks = (path) => { module.exports = { - changeToAbsolute, idDirFil, checkPath + changeToAbsolute, checkPath,findLinks }; \ No newline at end of file diff --git a/cli.js b/cli.js index 44c8a90..266a0c7 100644 --- a/cli.js +++ b/cli.js @@ -1,6 +1,6 @@ const { mdLinks } = require('./index.js'); -mdLinks('./node_modules') +mdLinks('./Caperta') .then(() => { mdLinks => console.log(mdLinks) diff --git a/index.js b/index.js index 7c9be38..6442ad7 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,4 @@ -const { pathAbsolute, changeToAbsolute, idDirFil,checkPath } = require('./app') +const { pathAbsolute, changeToAbsolute, checkPath } = require('./app') const fs = require("fs"); const path = require("path"); @@ -8,8 +8,9 @@ const mdLinks = (path, options) => { if(fs.existsSync(path)){ console.log(" dino q es",changeToAbsolute(path)) - console.log(" que s",idDirFil(path)); - console.log("klear 2", checkPath(path)); + findLinks(path) + + console.log("sdsfsdf",checkPath(path)); } else { From 8e7d7d2fbaab3dc4983dde292ea7f0757c1efd22 Mon Sep 17 00:00:00 2001 From: Roxsy Date: Mon, 6 Feb 2023 21:43:16 -0500 Subject: [PATCH 03/12] instalacion de axios --- app.js | 1 - package-lock.json | 154 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 3 + 3 files changed, 157 insertions(+), 1 deletion(-) diff --git a/app.js b/app.js index 81a3026..46b940d 100644 --- a/app.js +++ b/app.js @@ -57,7 +57,6 @@ const checkPath = (dir) => { - //Función para leer los archivos /* const readFiles = (path)=>{ diff --git a/package-lock.json b/package-lock.json index 1a976ae..d8c8ab4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "rvq_md-links", "version": "0.1.0", "license": "ISC", + "dependencies": { + "axios": "^1.3.2" + }, "devDependencies": { "jest": "^29.4.1" }, @@ -1142,6 +1145,21 @@ "sprintf-js": "~1.0.2" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.2.tgz", + "integrity": "sha512-1M3O703bYqYuPhbHeya5bnhpYVsDDRyQSabNja04mZtboLNSuZ4YrltestrLXfHgmzua4TpUqRiVKbiQuo2epw==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/babel-jest": { "version": "29.4.1", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.4.1.tgz", @@ -1432,6 +1450,17 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1490,6 +1519,14 @@ "node": ">=0.10.0" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -1660,6 +1697,38 @@ "node": ">=8" } }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2731,6 +2800,25 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -3001,6 +3089,11 @@ "node": ">= 6" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", @@ -4362,6 +4455,21 @@ "sprintf-js": "~1.0.2" } }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "axios": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.2.tgz", + "integrity": "sha512-1M3O703bYqYuPhbHeya5bnhpYVsDDRyQSabNja04mZtboLNSuZ4YrltestrLXfHgmzua4TpUqRiVKbiQuo2epw==", + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "babel-jest": { "version": "29.4.1", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.4.1.tgz", @@ -4568,6 +4676,14 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -4612,6 +4728,11 @@ "integrity": "sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==", "dev": true }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, "detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -4739,6 +4860,21 @@ "path-exists": "^4.0.0" } }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -5549,6 +5685,19 @@ "picomatch": "^2.3.1" } }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -5748,6 +5897,11 @@ "sisteransi": "^1.0.5" } }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", diff --git a/package.json b/package.json index 13276e6..bf3cf1b 100644 --- a/package.json +++ b/package.json @@ -29,5 +29,8 @@ "homepage": "https://github.com/roxsyVel910/DEV002-md-links#readme", "devDependencies": { "jest": "^29.4.1" + }, + "dependencies": { + "axios": "^1.3.2" } } From ff5ce1bd28bc0435ecca191c3a25d3c43c2db7f0 Mon Sep 17 00:00:00 2001 From: Roxsy Date: Tue, 7 Feb 2023 10:55:51 -0500 Subject: [PATCH 04/12] comentarios de la funcion checkPath --- .../media-Capera/Nueva carpeta/README.md | 666 ++++++++++++++++++ app.js | 32 +- index.js | 2 +- 3 files changed, 698 insertions(+), 2 deletions(-) create mode 100644 Caperta/subcarpeta/media-Capera/Nueva carpeta/README.md diff --git a/Caperta/subcarpeta/media-Capera/Nueva carpeta/README.md b/Caperta/subcarpeta/media-Capera/Nueva carpeta/README.md new file mode 100644 index 0000000..d4df79b --- /dev/null +++ b/Caperta/subcarpeta/media-Capera/Nueva carpeta/README.md @@ -0,0 +1,666 @@ +# Markdown Links + +## Índice + +* [1. Preámbulo](#1-preámbulo) +* [2. Resumen del proyecto](#2-resumen-del-proyecto) +* [3. Objetivos de aprendizaje](#3-objetivos-de-aprendizaje) +* [4. Consideraciones generales](#4-consideraciones-generales) +* [5. Criterios de aceptación mínimos del proyecto](#5-criterios-de-aceptación-mínimos-del-proyecto) +* [6. Entregables](#6-entregables) +* [7. Hacker edition](#7-hacker-edition) +* [8. Pistas, tips y lecturas complementarias](#8-pistas-tips-y-lecturas-complementarias) +* [9. Checklist](#9-checklist) +* [10. Achicando el problema](#10-achicando-el-problema) + +*** + +## 1. Preámbulo + +[Markdown](https://es.wikipedia.org/wiki/Markdown) es un lenguaje de marcado +ligero muy popular entre developers. Es usado en muchísimas plataformas que +manejan texto plano (GitHub, foros, blogs, ...) y es muy común +encontrar varios archivos en ese formato en cualquier tipo de repositorio +(empezando por el tradicional `README.md`). + +Estos archivos `Markdown` normalmente contienen _links_ (vínculos/ligas) que +muchas veces están rotos o ya no son válidos y eso perjudica mucho el valor de +la información que se quiere compartir. + +Dentro de una comunidad de código abierto, nos han propuesto crear una +herramienta usando [Node.js](https://nodejs.org/), que lea y analice archivos +en formato `Markdown`, para verificar los links que contengan y reportar +algunas estadísticas. + +![md-links](https://user-images.githubusercontent.com/110297/42118443-b7a5f1f0-7bc8-11e8-96ad-9cc5593715a6.jpg) + +## 2. Resumen del proyecto + +En este proyecto crearás una herramienta de línea de comando (CLI) así como tu +propia librería (o biblioteca - library) en JavaScript. + +En esta oportunidad nos alejamos un poco del navegador para construir un +programa que se ejecute usando Node.js. Aprenderemos sobre procesos +(`process.env`, `process.argv`, ...), cómo interactuar con el sistema archivos, +cómo hacer consultas de red, etc. + +[Node.js](https://nodejs.org/es/) es un entorno de ejecución para JavaScript +construido con el [motor de JavaScript V8 de Chrome](https://developers.google.com/v8/). +Esto nos va a permitir ejecutar JavaScript en el entorno del sistema operativo, +ya sea tu máquina o un servidor, lo cual nos abre las puertas para poder +interactuar con el sistema en sí, archivos, redes, ... + +Diseñar tu propia librería es una experiencia fundamental para cualquier +desarrollador porque que te obliga a pensar en la interfaz (API) de tus +_módulos_ y cómo será usado por otros developers. Debes tener especial +consideración en peculiaridades del lenguaje, convenciones y buenas prácticas. + +## 3. Objetivos de aprendizaje + +Reflexiona y luego marca los objetivos que has llegado a entender y aplicar en tu proyecto. Piensa en eso al decidir tu estrategia de trabajo. + +### JavaScript + +- [ ] **Diferenciar entre tipos de datos primitivos y no primitivos** + +- [ ] **Arrays (arreglos)** + +
Links

+ + * [Arreglos](https://curriculum.laboratoria.la/es/topics/javascript/04-arrays) + * [Array - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/) + * [Array.prototype.sort() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) + * [Array.prototype.forEach() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) + * [Array.prototype.map() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/map) + * [Array.prototype.filter() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) + * [Array.prototype.reduce() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) +

+ +- [ ] **Objetos (key, value)** + +
Links

+ + * [Objetos en JavaScript](https://curriculum.laboratoria.la/es/topics/javascript/05-objects/01-objects) +

+ +- [ ] **Uso de condicionales (if-else, switch, operador ternario, lógica booleana)** + +
Links

+ + * [Estructuras condicionales y repetitivas](https://curriculum.laboratoria.la/es/topics/javascript/02-flow-control/01-conditionals-and-loops) + * [Tomando decisiones en tu código — condicionales - MDN](https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/conditionals) +

+ +- [ ] **Funciones (params, args, return)** + +
Links

+ + * [Funciones (control de flujo)](https://curriculum.laboratoria.la/es/topics/javascript/02-flow-control/03-functions) + * [Funciones clásicas](https://curriculum.laboratoria.la/es/topics/javascript/03-functions/01-classic) + * [Arrow Functions](https://curriculum.laboratoria.la/es/topics/javascript/03-functions/02-arrow) + * [Funciones — bloques de código reutilizables - MDN](https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/Functions) +

+ +- [ ] **Recursión o recursividad** + +
Links

+ + * [Píldora recursión - YouTube Laboratoria Developers](https://www.youtube.com/watch?v=lPPgY3HLlhQ) + * [Recursión o Recursividad - Laboratoria Developers en Medium](https://medium.com/laboratoria-developers/recursi%C3%B3n-o-recursividad-ec8f1a359727) +

+ +- [ ] **Módulos de CommonJS** + +
Links

+ + * [Modules: CommonJS modules - Node.js Docs](https://nodejs.org/docs/latest/api/modules.html) +

+ +- [ ] **Diferenciar entre expresiones (expressions) y sentencias (statements)** + +- [ ] **Callbacks** + +
Links

+ + * [Función Callback - MDN](https://developer.mozilla.org/es/docs/Glossary/Callback_function) +

+ +- [ ] **Promesas** + +
Links

+ + * [Promise - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Promise) + * [How to Write a JavaScript Promise - freecodecamp (en inglés)](https://www.freecodecamp.org/news/how-to-write-a-javascript-promise-4ed8d44292b8/) +

+ +- [ ] **Pruebas unitarias (unit tests)** + +
Links

+ + * [Empezando con Jest - Documentación oficial](https://jestjs.io/docs/es-ES/getting-started) +

+ +- [ ] **Pruebas asíncronas** + +
Links

+ + * [Tests de código asincrónico con Jest - Documentación oficial](https://jestjs.io/docs/es-ES/asynchronous) +

+ +- [ ] **Uso de mocks y espías** + +
Links

+ + * [Manual Mocks con Jest - Documentación oficial](https://jestjs.io/docs/es-ES/manual-mocks) +

+ +- [ ] **Pruebas de compatibilidad en múltiples entornos de ejecución** + +- [ ] **Uso de linter (ESLINT)** + +- [ ] **Uso de identificadores descriptivos (Nomenclatura y Semántica)** + +### Node.js + +- [ ] **Instalar y usar módulos con npm** + +
Links

+ + * [Sitio oficial de npm (en inglés)](https://www.npmjs.com/) +

+ +- [ ] **Configuración de package.json** + +
Links

+ + * [package.json - Documentación oficial (en inglés)](https://docs.npmjs.com/files/package.json) +

+ +- [ ] **Configuración de npm-scripts** + +
Links

+ + * [scripts - Documentación oficial (en inglés)](https://docs.npmjs.com/misc/scripts) +

+ +- [ ] **process (env, argv, stdin-stdout-stderr, exit-code)** + +
Links

+ + * [Process - Documentación oficial (en inglés)](https://nodejs.org/api/process.html) +

+ +- [ ] **File system (fs, path)** + +
Links

+ + * [File system - Documentación oficial (en inglés)](https://nodejs.org/api/fs.html) + * [Path - Documentación oficial (en inglés)](https://nodejs.org/api/path.html) +

+ +### Control de Versiones (Git y GitHub) + +- [ ] **Git: Instalación y configuración** + +- [ ] **Git: Control de versiones con git (init, clone, add, commit, status, push, pull, remote)** + +- [ ] **Git: Integración de cambios entre ramas (branch, checkout, fetch, merge, reset, rebase, tag)** + +- [ ] **GitHub: Creación de cuenta y repos, configuración de llaves SSH** + +- [ ] **GitHub: Colaboración en Github (branches | forks | pull requests | code review | tags)** + +- [ ] **GitHub: Organización en Github (projects | issues | labels | milestones | releases)** + +### HTTP + +- [ ] **Consulta o petición (request) y respuesta (response).** + +
Links

+ + * [Generalidades del protocolo HTTP - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/Overview) + * [Mensajes HTTP - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/Messages) +

+ +- [ ] **Códigos de status de HTTP** + +
Links

+ + * [Códigos de estado de respuesta HTTP - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/Status) + * [The Complete Guide to Status Codes for Meaningful ReST APIs - dev.to](https://dev.to/khaosdoctor/the-complete-guide-to-status-codes-for-meaningful-rest-apis-1-5c5) +

+ +## 4. Consideraciones generales + +* Este proyecto se debe "resolver" de manera individual. + +* La **librería** y el **script ejecutable** (herramienta de línea de comando - + CLI) deben estar implementados en JavaScript para ser ejecutados con + Node.js. **Está permitido usar librerías externas**. + +* Tu módulo **debe ser instalable** via `npm install /md-links`. Este + módulo debe incluir tanto un _ejecutable_ que podamos invocar en la línea de + comando como una interfaz que podamos importar con `require` para usarlo + programáticamente. + +* Los **tests unitarios** deben cubrir un mínimo del 70% de _statements_, + _functions_, _lines_ y _branches_. Te recomendamos explorar [Jest](https://jestjs.io/) + para tus pruebas unitarias. + +* Para este proyecto **no está permitido** utilizar `async/await`. + +* Para este proyecto te sugerimos **no utilizar** la versión síncrona +de la función para leer archivos, `readFileSync`, y en cambio intentar +resolver este desafío de manera asíncrona. + +* Para este proyecto es **opcional** el uso de ES Modules `(import/export)`, en el + caso optes utilizarlo deberás de crear un script de `build` en el `package.json` + que los transforme en `requires` y `module.exports` con ayuda de **babel**. + +* Para disminuir la complejidad de tu algoritmo recursivo, te recomendamos +utilizar la versión síncrona de la función para leer directorios, `readdirSync`. + +## 5. Criterios de aceptación mínimos del proyecto + +Para comenzar este proyecto tendrás que hacer un **_fork_** y **_clonar_** este +repositorio. + +Antes de comenzar a codear, es necesario crear un **plan de acción**. Esto debería +quedar detallado en el `README.md` de tu repo y en una serie de **_issues_** +y **_milestones_** para priorizar y organizar el trabajo, y para poder hacer +seguimiento de tu progreso. + +Dentro de cada **_milestone_** se crearán y asignarán los **_issues_** que cada quien +considere necesarios. + +### Archivos del proyecto + +* `README.md` con descripción del módulo, instrucciones de instalación/uso, + documentación del API y ejemplos. Todo lo relevante para que cualquier + developer que quiera usar tu librería pueda hacerlo sin inconvenientes. +* `index.js`: Desde este archivo debes exportar **una** función (`mdLinks`). +* `package.json` con nombre, versión, descripción, autores, licencia, + dependencias, scripts (pretest, test, ...), main, bin +* `.editorconfig` con configuración para editores de texto. Este archivo no se + debe cambiar. +* `.eslintrc` con configuración para linter. Este archivo contiene una + configuración básica para ESLint, si deseas agregar reglas adicionales + como Airbnb deberás modificar este archivo. +* `.gitignore` para ignorar `node_modules` u otras carpetas que no deban + incluirse en control de versiones (`git`). +* `test/md-links.spec.js` debe contener los tests unitarios para la función + `mdLinks()`. Tu inplementación debe pasar estos tets. + +## Este proyecto consta de DOS partes + +### 1) JavaScript API + +El módulo debe poder **importarse** en otros scripts de Node.js y debe ofrecer la +siguiente interfaz: + +#### `mdLinks(path, options)` + +##### Argumentos + +* `path`: Ruta **absoluta** o **relativa** al **archivo** o **directorio**. +Si la ruta pasada es relativa, debe resolverse como relativa al directorio +desde donde se invoca node - _current working directory_). +* `options`: Un objeto con **únicamente** la siguiente propiedad: + - `validate`: Booleano que determina si se desea validar los links + encontrados. + +##### Valor de retorno + +La función debe **retornar una promesa** (`Promise`) que **resuelva a un arreglo** +(`Array`) de objetos (`Object`), donde cada objeto representa un link y contiene +las siguientes propiedades + +Con `validate:false` : + +* `href`: URL encontrada. +* `text`: Texto que aparecía dentro del link (`
`). +* `file`: Ruta del archivo donde se encontró el link. + +Con `validate:true` : + +* `href`: URL encontrada. +* `text`: Texto que aparecía dentro del link (``). +* `file`: Ruta del archivo donde se encontró el link. +* `status`: Código de respuesta HTTP. +* `ok`: Mensaje `fail` en caso de fallo u `ok` en caso de éxito. + +#### Ejemplo (resultados como comentarios) + +```js +const mdLinks = require("md-links"); + +mdLinks("./some/example.md") + .then(links => { + // => [{ href, text, file }, ...] + }) + .catch(console.error); + +mdLinks("./some/example.md", { validate: true }) + .then(links => { + // => [{ href, text, file, status, ok }, ...] + }) + .catch(console.error); + +mdLinks("./some/dir") + .then(links => { + // => [{ href, text, file }, ...] + }) + .catch(console.error); +``` + +### 2) CLI (Command Line Interface - Interfaz de Línea de Comando) + +El ejecutable de nuestra aplicación debe poder ejecutarse de la siguiente +manera a través de la **terminal**: + +`md-links [options]` + +Por ejemplo: + +```sh +$ md-links ./some/example.md +./some/example.md http://algo.com/2/3/ Link a algo +./some/example.md https://otra-cosa.net/algun-doc.html algún doc +./some/example.md http://google.com/ Google +``` + +El comportamiento por defecto no debe validar si las URLs responden ok o no, +solo debe identificar el archivo markdown (a partir de la ruta que recibe como +argumento), analizar el archivo Markdown e imprimir los links que vaya +encontrando, junto con la ruta del archivo donde aparece y el texto +que hay dentro del link (truncado a 50 caracteres). + +#### Options + +##### `--validate` + +Si pasamos la opción `--validate`, el módulo debe hacer una petición HTTP para +averiguar si el link funciona o no. Si el link resulta en una redirección a una +URL que responde ok, entonces consideraremos el link como ok. + +Por ejemplo: + +```sh +$ md-links ./some/example.md --validate +./some/example.md http://algo.com/2/3/ ok 200 Link a algo +./some/example.md https://otra-cosa.net/algun-doc.html fail 404 algún doc +./some/example.md http://google.com/ ok 301 Google +``` + +Vemos que el _output_ en este caso incluye la palabra `ok` o `fail` después de +la URL, así como el status de la respuesta recibida a la petición HTTP a dicha +URL. + +##### `--stats` + +Si pasamos la opción `--stats` el output (salida) será un texto con estadísticas +básicas sobre los links. + +```sh +$ md-links ./some/example.md --stats +Total: 3 +Unique: 3 +``` + +También podemos combinar `--stats` y `--validate` para obtener estadísticas que +necesiten de los resultados de la validación. + +```sh +$ md-links ./some/example.md --stats --validate +Total: 3 +Unique: 3 +Broken: 1 +``` + +## 6. Entregables + +Módulo instalable via `npm install /md-links`. Este módulo debe +incluir tanto **un ejecutable** como **una interfaz** que podamos importar con `require` +para usarlo programáticamente. + +## 7. Hacker edition + +Las secciones llamadas _Hacker Edition_ son **opcionales**. Si **terminaste** +con todo lo anterior y te queda tiempo, intenta completarlas. Así podrás +profundizar y/o ejercitar más sobre los objetivos de aprendizaje del proyecto. + +* Puedes agregar la propiedad `line` a cada objeto `link` indicando en qué línea + del archivo se encontró el link. +* Puedes agregar más estadísticas. +* Integración continua con Travis o Circle CI. + +*** + +## 8. Pistas, tips y lecturas complementarias + +### FAQs + +#### ¿Cómo hago para que mi módulo sea _instalable_ desde GitHub? + +Para que el módulo sea instalable desde GitHub solo tiene que: + +* Estar en un repo público de GitHub +* Contener un `package.json` válido + +Con el comando `npm install githubname/reponame` podemos instalar directamente +desde GitHub. Ver [docs oficiales de `npm install` acá](https://docs.npmjs.com/cli/install). + +Por ejemplo, el [`course-parser`](https://github.com/Laboratoria/course-parser) +que usamos para la currícula no está publicado en el registro público de NPM, +así que lo instalamos directamente desde GitHub con el comando `npm install +Laboratoria/course-parser`. + +### Sugerencias de implementación + +La implementación de este proyecto tiene varias partes: leer del sistema de +archivos, recibir argumentos a través de la línea de comando, analizar texto, +hacer consultas HTTP, ... y todas estas cosas pueden enfocarse de muchas formas, +tanto usando librerías como implementando en VanillaJS. + +Por poner un ejemplo, el _parseado_ (análisis) del markdown para extraer los +links podría plantearse de las siguientes maneras (todas válidas): + +* Usando un _módulo_ como [markdown-it](https://github.com/markdown-it/markdown-it), + que nos devuelve un arreglo de _tokens_ que podemos recorrer para identificar + los links. +* Siguiendo otro camino completamente, podríamos usar + [expresiones regulares (`RegExp`)](https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Regular_Expressions). +* También podríamos usar una combinación de varios _módulos_ (podría ser válido + transformar el markdown a HTML usando algo como [marked](https://github.com/markedjs/marked) + y de ahí extraer los link con una librería de DOM como [JSDOM](https://github.com/jsdom/jsdom) + o [Cheerio](https://github.com/cheeriojs/cheerio) entre otras). +* Usando un _custom renderer_ de [marked](https://github.com/markedjs/marked) + (`new marked.Renderer()`). + +No dudes en consultar a tus compañeras y coaches +si tienes dudas existenciales con respecto a estas decisiones. No existe una +"única" manera correcta :wink: + +### Tutoriales / NodeSchool workshoppers + +* [learnyounode](https://github.com/workshopper/learnyounode) +* [how-to-npm](https://github.com/workshopper/how-to-npm) +* [promise-it-wont-hurt](https://github.com/stevekane/promise-it-wont-hurt) + +### Otros recursos + +* [Acerca de Node.js - Documentación oficial](https://nodejs.org/es/about/) +* [Node.js file system - Documentación oficial](https://nodejs.org/api/fs.html) +* [Node.js http.get - Documentación oficial](https://nodejs.org/api/http.html#http_http_get_options_callback) +* [Node.js - Wikipedia](https://es.wikipedia.org/wiki/Node.js) +* [What exactly is Node.js? - freeCodeCamp](https://medium.freecodecamp.org/what-exactly-is-node-js-ae36e97449f5) +* [¿Qué es Node.js y para qué sirve? - drauta.com](https://www.drauta.com/que-es-nodejs-y-para-que-sirve) +* [¿Qué es Nodejs? Javascript en el Servidor - Fazt en YouTube](https://www.youtube.com/watch?v=WgSc1nv_4Gw) +* [¿Simplemente qué es Node.js? - IBM Developer Works, 2011](https://www.ibm.com/developerworks/ssa/opensource/library/os-nodejs/index.html) +* [Node.js y npm](https://www.genbeta.com/desarrollo/node-js-y-npm) +* [Módulos, librerías, paquetes, frameworks... ¿cuál es la diferencia?](http://community.laboratoria.la/t/modulos-librerias-paquetes-frameworks-cual-es-la-diferencia/175) +* [Asíncronía en js](https://carlosazaustre.es/manejando-la-asincronia-en-javascript) +* [NPM](https://docs.npmjs.com/getting-started/what-is-npm) +* [Publicar packpage](https://docs.npmjs.com/getting-started/publishing-npm-packages) +* [Crear módulos en Node.js](https://docs.npmjs.com/getting-started/publishing-npm-packages) +* [Leer un archivo](https://nodejs.org/api/fs.html#fs_fs_readfile_path_options_callback) +* [Leer un directorio](https://nodejs.org/api/fs.html#fs_fs_readdir_path_options_callback) +* [Path](https://nodejs.org/api/path.html) +* [Linea de comando CLI](https://medium.com/netscape/a-guide-to-create-a-nodejs-command-line-package-c2166ad0452e) + +## 9. Checklist + +### General + +* [ ] Puede instalarse via `npm install --global /md-links` + +### `README.md` + +* [ ] Un board con el backlog para la implementación de la librería. +* [ ] Documentación técnica de la librería. +* [ ] Guía de uso e instalación de la librería + +### API `mdLinks(path, opts)` + +* [ ] El módulo exporta una función con la interfaz (API) esperada. +* [ ] Implementa soporte para archivo individual +* [ ] Implementa soporte para directorios +* [ ] Implementa `options.validate` + +### CLI + +* [ ] Expone ejecutable `md-links` en el path (configurado en `package.json`) +* [ ] Se ejecuta sin errores / output esperado +* [ ] Implementa `--validate` +* [ ] Implementa `--stats` + +### Pruebas / tests + +* [ ] Pruebas unitarias cubren un mínimo del 70% de statements, functions, + lines, y branches. +* [ ] Pasa tests (y linters) (`npm test`). + +## 10. Achicando el problema + +Un "superpoder" que esperamos puedas desarrollar durante el bootcamp +es el de definir "mini-proyectos" que te acerquen paso a paso a +la solución del "gran proyecto". Es el equivalente a comenzar armando +esquinas o bordes del rompecabezas/puzzle sin saber necesariamente +cómo encajarán al final. Déjate llevar y explora. + +Estas son algunas sugerencias: + +### Empieza con un diagrama de flujo + +Este proyecto es distinto de los que has venido trabajando hasta ahora +dado que no hay una interfaz web, todo se desarrollará en tu editor y +consola/terminal. + +Es por ello que, para visualizar mejor lo que tendrás que hacer +y planificar tus tareas y objetivos, es recomendable hacer un +`diagrama de flujo`. + +Si nunca has hecho un diagrama de flujo revisa este [recurso](https://www.youtube.com/watch?v=Lub5qOmY4JQ). + +Una alternativa al diagrama de flujo puede ser el `pseudocódigo`. + +### Planificación + +En este proyecto te recomendamos usar la herramienta de planificación +y organización de GitHub llamada **Github Projects**. + +Mediante **issues** y **milestones** podrás organizar y planificar +tareas y objetivos concretos. + +Tomando en consideración los **entregables** del proyecto, el +[9. Checklist](#9-checklist) y los **pasos** que definiste en tu +`diagrama de flujo`, crea tu planificación en GitHub Projects. + +### Antes de codear + +En esta ocasión estarás trabajando en **NodeJS**, asegúrate +de saber para qué sirve y sus consideraciones. + +En particular, deberás decidir desde un comienzo si usarás +`ES Modules`, es decir, **import/export**, ó, por el contrario, +`CommonJS Modules`, es decir, **require/module.exports**. + +Asegurate de tener clara esta decisión desde un inicio para +que no encuentres problemas más adelante. + +### Lee un archivo + +Como primer reto, puedes tratar de leer un solo archivo con +una ruta fija e imprimir su contenido en la consola con un `console.log`. + +La librería nativa `FS` (FileSystem) te será de utilidad. + +**Recuerda**: Te sugerimos **no utilizar** la versión síncrona +de la función para leer archivos, `readFileSync`, y en cambio +intentar resolver ese desafío de manera asíncrona. + +### Averigua la extensión de un archivo + +Ya sabiendo leer un archivo, aventúrate a conocer cual +es su extensión. + +Recuerda, las extensiones son esas letras al final del +nombre de un archivo, por ejemplo: .js, .txt, .doc, etc + +Aquí también podrá ser útil `FS`. + +### Obtén el contenido de un directorio + +Este proyecto consiste en buscar archivos, pero para eso, +primero debes poder verlos. + +Intenta imprimir en consola la lista de archivos en una carpeta. + +La librería `FS` también te será útil aquí. + +**Recuerda**: Para disminuir la complejidad de tu algoritmo +recursivo, te recomendamos utilizar la versión síncrona de +la función para leer directorios, `readdirSync`. + +### Une dos rutas + +Para poder acceder a carpetas y archivos será necesario que +indiques en qué lugar de tu computadora se encuentran, a esto +le llamamos **rutas**. + +Usa la librería nativa `path` para unir dos segmentos de ruta, +por ejemplo, si queremos unir: + +1) /home/Laboratoria/ +2) ./test + +El resultado sería: /home/Laboratoria/test + +### Recursividad + +Este proyecto se ha de resolver de forma casi natural con +**recursividad**. + +¿Por qué?. + +Porque no conocemos realmente cuantas carpetas y archivos +tendremos que recorrer antes de terminar. + +Si recibes una ruta de carpeta, no sabrás de ante mano si +dentro hay más carpetas o muchos archivos. + +Por ello, asegurate bien de entender de qué trata la +recursividad y ver algunos ejemplos. + +Entre los recursos de este proyecto hay un video que te ayudará. + +### Crea una promesa + +El valor de retorno de nuestra librería es una `Promesa`, +no un `Array`. + +Prueba leyendo sobre las promesas y creando una por tu +cuenta utilizando **new Promise()** + +Es importante que sepas qué es un **callback** pues las +promesas los utilizarán. diff --git a/app.js b/app.js index 46b940d..9e5f5ad 100644 --- a/app.js +++ b/app.js @@ -18,6 +18,8 @@ const changeToAbsolute = (ruta) => { } + + /*const checkPath = (ruta) => { const files = fs.readdirSync(ruta); @@ -50,6 +52,34 @@ const checkPath = (dir) => { } +const shareLinks = () => { + + + +} + + + +/*function findLinks(mdFiles) { + const links = []; + mdFiles.forEach(fileUrl => { + axios + .get(fileUrl) + .then(response => { + const content = response.data; + const regex = /\[(.*?)\]\((.*?)\)/g; + let match; + while ((match = regex.exec(content)) !== null) { + links.push(match[2]); + } + }) + .catch(error => { + console.error(error); + }); + }); + return links; +} */ + @@ -152,6 +182,6 @@ const mdLinks = (path) => { module.exports = { - changeToAbsolute, checkPath,findLinks + changeToAbsolute, checkPath }; \ No newline at end of file diff --git a/index.js b/index.js index 6442ad7..f4460a8 100644 --- a/index.js +++ b/index.js @@ -8,7 +8,7 @@ const mdLinks = (path, options) => { if(fs.existsSync(path)){ console.log(" dino q es",changeToAbsolute(path)) - findLinks(path) + console.log("sdsfsdf",checkPath(path)); From d2695c06eb0726c1059a78e02f3bdba5a97fef99 Mon Sep 17 00:00:00 2001 From: Roxsy Date: Thu, 9 Feb 2023 17:36:57 -0500 Subject: [PATCH 05/12] recorrer las rutas --- app.js | 82 +++++++++++++++++++++++++++++++++----------------------- cli.js | 2 +- index.js | 13 +++++---- 3 files changed, 58 insertions(+), 39 deletions(-) diff --git a/app.js b/app.js index 9e5f5ad..84b40fd 100644 --- a/app.js +++ b/app.js @@ -1,6 +1,8 @@ const fs = require('fs'); const path = require('path'); const axios = require('axios'); +const { Console } = require('console'); + const mdFiles = []; // regex para ver si es ruta absoluta @@ -10,11 +12,11 @@ function isAbsolute(path) { } // validando si es absoluta o relativa tmb esta convirtiendo la ruta relativa a absoluta const changeToAbsolute = (ruta) => { - if (isAbsolute(ruta)) { - return ruta; - } else { - return path.resolve(ruta); - } + if (isAbsolute(ruta)) { + return ruta; + } else { + return path.resolve(ruta); + } } @@ -38,13 +40,22 @@ const changeToAbsolute = (ruta) => { return mdFiles; } */ const checkPath = (dir) => { + const stats = fs.lstatSync(dir); + if (stats.isFile() && path.extname(dir) === '.md') { + mdFiles.push(dir); } else if (stats.isDirectory()) { + const files = fs.readdirSync(dir); + files.forEach(file => { + const filePath = path.join(dir, file); + + // nombre de la ruta ./carpeta + readme.md + checkPath(filePath); }); } @@ -52,54 +63,59 @@ const checkPath = (dir) => { } -const shareLinks = () => { - +const readFiles = (path)=>{ + fs.readFile(path, 'utf8', (err, data) => { + if (err) { + console.error(err); + return err; + + } + console.log(data) + return data; + }); + + } + +const findLinks = (mdFiles) => { + console.log("mdLinks en findLinks", mdFiles) + mdFiles.forEach(file => { + + console.log("lista array", file); + + console.log("lectura de arr", readFiles(file)) + return readFiles(file) + + }); } -/*function findLinks(mdFiles) { - const links = []; - mdFiles.forEach(fileUrl => { +/* axios - .get(fileUrl) + .get(file) .then(response => { + console.log("reponse", response.status); const content = response.data; const regex = /\[(.*?)\]\((.*?)\)/g; - let match; - while ((match = regex.exec(content)) !== null) { - links.push(match[2]); + + let contLink; + if((contLink = regex.match(content)) !== null){ + links.push(contLink) } }) .catch(error => { console.error(error); }); - }); - return links; -} */ - - +*/ +//Función para leer los archivos - -//Función para leer los archivos -/* const readFiles = (path)=>{ - fs.readFile(path, 'utf8', (err, data) => { - if (err) { - console.error(err); - return err; - } - console.log("¿estás leyendo archivos?",data); - - }); - }*/ - /*const mdFiles = []; @@ -182,6 +198,6 @@ const mdLinks = (path) => { module.exports = { - changeToAbsolute, checkPath + changeToAbsolute, checkPath,findLinks,readFiles }; \ No newline at end of file diff --git a/cli.js b/cli.js index 266a0c7..b1184bf 100644 --- a/cli.js +++ b/cli.js @@ -1,6 +1,6 @@ const { mdLinks } = require('./index.js'); -mdLinks('./Caperta') +mdLinks('./README.md') .then(() => { mdLinks => console.log(mdLinks) diff --git a/index.js b/index.js index f4460a8..8069f22 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,4 @@ -const { pathAbsolute, changeToAbsolute, checkPath } = require('./app') +const { changeToAbsolute, checkPath, findLinks,readFiles } = require('./app') const fs = require("fs"); const path = require("path"); @@ -7,11 +7,14 @@ const mdLinks = (path, options) => { if(fs.existsSync(path)){ - console.log(" dino q es",changeToAbsolute(path)) + //console.log(" dino q es",changeToAbsolute(path)) + //const arrPaths = checkPath(path); - - console.log("sdsfsdf",checkPath(path)); - + console.log("mdlinks",checkPath(path)); + // findLinks(['https://www.google.com/search?q=google+traductor&oq=goo&aqs=chrome.0.69i59l2j69i57j69i60l2j69i65l3.1503j0j7&sourceid=chrome&ie=UTF-8']) + + console.log("leer archivo", readFiles(path)) + console.log( findLinks()) } else { reject("la ruta no existe") From 41fc041d3a4bef5b9e9671fbbc999dbdfb472579 Mon Sep 17 00:00:00 2001 From: Roxsy Date: Fri, 10 Feb 2023 11:00:27 -0500 Subject: [PATCH 06/12] agregando axios para validar links --- app.js | 93 +++++++++++++++++++++++++++++++++++++++++++++++--------- index.js | 23 ++++++++++---- 2 files changed, 96 insertions(+), 20 deletions(-) diff --git a/app.js b/app.js index 84b40fd..840ff1e 100644 --- a/app.js +++ b/app.js @@ -4,25 +4,88 @@ const axios = require('axios'); const { Console } = require('console'); const mdFiles = []; +//Devuelve true si el path es absoluto sino false. +const pathRelative = (ruta) => { + return path.isAbsolute(ruta) +}; -// regex para ver si es ruta absoluta -const regEx = /^(\/|[A-Za-z]:\\)/; -function isAbsolute(path) { - return regEx.test(path); -} -// validando si es absoluta o relativa tmb esta convirtiendo la ruta relativa a absoluta +//Convertir el path en Absoluto const changeToAbsolute = (ruta) => { - if (isAbsolute(ruta)) { - return ruta; - } else { - return path.resolve(ruta); - } -} + return path.resolve(ruta); +}; + + + +const checkFile = filePath => { + return new Promise((resolve, reject) => { + fs.lstat(filePath, (err, stat) => { + if (err) { + reject(err); + return; + } + if (stat.isFile()) { + resolve(`${filePath} is a file`); + } else if (stat.isDirectory()) { + resolve(`${filePath} is a directory`); + } + }); + }); +}; +// regex para ver si es ruta absoluta + -/*const checkPath = (ruta) => { + + +const extractLinks = (ruta) => { + return new Promise((resolve, reject) => { + fs.readFile(ruta, 'utf-8', (error, fileContents) => { + if (error) { + return reject(error); + } + + const regex = /\[(.*)\]\((https?:\/\/\S+)\)/g; + const links = []; + + let match; + while ((match = regex.exec(fileContents))) { + links.push({ + text: match[1], + href: match[2], + file: ruta + }); + } + + resolve(links); + }); + }); +}; + +const validateLinks = (links) => { + return Promise.all( + links.map((link) => { + return axios.head(link.href) + .then(() => { + link.status = 'OK'; + return link; + }) + .catch((error) => { + link.status = error.message; + return link; + }); + }) + ); +}; + + + +// + + + +/*const checkPath = () => { const files = fs.readdirSync(ruta); files.forEach(file => { @@ -65,6 +128,7 @@ const checkPath = (dir) => { const readFiles = (path)=>{ + fs.readFile(path, 'utf8', (err, data) => { if (err) { console.error(err); @@ -79,6 +143,7 @@ const readFiles = (path)=>{ const findLinks = (mdFiles) => { + console.log("mdLinks en findLinks", mdFiles) mdFiles.forEach(file => { @@ -198,6 +263,6 @@ const mdLinks = (path) => { module.exports = { - changeToAbsolute, checkPath,findLinks,readFiles + changeToAbsolute, checkPath,findLinks,readFiles,pathRelative,extractLinks,validateLinks }; \ No newline at end of file diff --git a/index.js b/index.js index 8069f22..587afa9 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,4 @@ -const { changeToAbsolute, checkPath, findLinks,readFiles } = require('./app') +const { changeToAbsolute, checkPath, findLinks,readFiles,pathRelative,extractLinks, validateLinks } = require('./app') const fs = require("fs"); const path = require("path"); @@ -7,18 +7,29 @@ const mdLinks = (path, options) => { if(fs.existsSync(path)){ - //console.log(" dino q es",changeToAbsolute(path)) - //const arrPaths = checkPath(path); + + console.log("es relatiuva",pathRelative(path)) + console.log("es relatiuva",changeToAbsolute(path)) - console.log("mdlinks",checkPath(path)); + //console.log("mdlinks",checkPath(path)); // findLinks(['https://www.google.com/search?q=google+traductor&oq=goo&aqs=chrome.0.69i59l2j69i57j69i60l2j69i65l3.1503j0j7&sourceid=chrome&ie=UTF-8']) - console.log("leer archivo", readFiles(path)) - console.log( findLinks()) + // console.log("leer archivo", readFiles(path)) + //console.log( findLinks()) + + extractLinks(path) + .then(validateLinks) + .then((links) => console.log("linksss",links)) + .catch((error) => console.error(error)); } else { reject("la ruta no existe") } + const { extractLinks, validateLinks } = require('./links.js'); + + + + }) } module.exports = { From 5b2905b7f557ae892df4c021b90e4a679ea78b21 Mon Sep 17 00:00:00 2001 From: Roxsy Date: Mon, 13 Feb 2023 21:12:58 -0500 Subject: [PATCH 07/12] recorrer array de objeto de link y poniendo status --- app.js | 158 ++++++++++++++++++++++++++++++++++--------------------- index.js | 23 ++++---- 2 files changed, 111 insertions(+), 70 deletions(-) diff --git a/app.js b/app.js index 840ff1e..5b3f254 100644 --- a/app.js +++ b/app.js @@ -2,6 +2,7 @@ const fs = require('fs'); const path = require('path'); const axios = require('axios'); const { Console } = require('console'); +const { resolve } = require('path'); const mdFiles = []; //Devuelve true si el path es absoluto sino false. @@ -36,51 +37,106 @@ const checkFile = filePath => { // regex para ver si es ruta absoluta +const extractLinks = (ruta) => { + return new Promise((resolve, reject) => { + fs.readFile(ruta, 'utf-8', (error, fileContents) => { + if (error) { + return reject(error); + } + const regex = /\[(.*)\]\((https?:\/\/\S+)\)/g; + const links = []; + let match; + while ((match = regex.exec(fileContents))) { + links.push({ + text: match[1], + href: match[2], + file: ruta, -const extractLinks = (ruta) => { - return new Promise((resolve, reject) => { - fs.readFile(ruta, 'utf-8', (error, fileContents) => { - if (error) { - return reject(error); - } - - const regex = /\[(.*)\]\((https?:\/\/\S+)\)/g; - const links = []; - - let match; - while ((match = regex.exec(fileContents))) { - links.push({ - text: match[1], - href: match[2], - file: ruta - }); - } - - resolve(links); - }); + }); + } + + resolve(links); + }); }); }; + const validateLinks = (links) => { - return Promise.all( - links.map((link) => { - return axios.head(link.href) - .then(() => { - link.status = 'OK'; - return link; - }) - .catch((error) => { - link.status = error.message; - return link; - }); + + return new Promise((resolve, reject) => { + + + axios + .get(links) + .then(response => { + //console.log("repose", response) + const contStatus = response.status; + const contStatusText = response.statusText; + //statusMessage + // http: __currentUrl + //statusCode + + + + resolve({ contStatus, contStatusText }) }) - ); + .catch(error => { + if (error.code === 'ENOTFOUND') { + reject("codigo roto") + + } + + + }) + + + }) +}; +const processLinks = (extract) => { + extract.then((links) => { + // Aquí puedes recorrer los links + links.forEach(link => { + const arrli = [] + const linkHref = link.href + + validateLinks(linkHref) + .then(({ contStatus, contStatusText }) => ({ contStatus, contStatusText })) + + .catch((error) => console.error(error)) + + + arrli.push({ + ...links, + + + + }) + console.log("arrli", arrli) + + + }); + }); }; + +/* + axios + .get(file) + .then(response => { + console.log("reponse", response.status); + + }) + .catch(error => { + console.error(error); + }); +*/ + + + // @@ -127,29 +183,29 @@ const checkPath = (dir) => { -const readFiles = (path)=>{ +const readFiles = (path) => { fs.readFile(path, 'utf8', (err, data) => { if (err) { console.error(err); return err; - } - console.log(data) - return data; + } + console.log(data) + return data; }); - } +} const findLinks = (mdFiles) => { - + console.log("mdLinks en findLinks", mdFiles) - mdFiles.forEach(file => { + mdFiles.forEach(file => { console.log("lista array", file); - console.log("lectura de arr", readFiles(file)) + console.log("lectura de arr", readFiles(file)) return readFiles(file) }); @@ -157,23 +213,7 @@ const findLinks = (mdFiles) => { -/* - axios - .get(file) - .then(response => { - console.log("reponse", response.status); - const content = response.data; - const regex = /\[(.*?)\]\((.*?)\)/g; - - let contLink; - if((contLink = regex.match(content)) !== null){ - links.push(contLink) - } - }) - .catch(error => { - console.error(error); - }); -*/ + @@ -263,6 +303,6 @@ const mdLinks = (path) => { module.exports = { - changeToAbsolute, checkPath,findLinks,readFiles,pathRelative,extractLinks,validateLinks + changeToAbsolute, checkPath, findLinks, readFiles, pathRelative, extractLinks, validateLinks, processLinks }; \ No newline at end of file diff --git a/index.js b/index.js index 587afa9..1edcb64 100644 --- a/index.js +++ b/index.js @@ -1,31 +1,32 @@ -const { changeToAbsolute, checkPath, findLinks,readFiles,pathRelative,extractLinks, validateLinks } = require('./app') +const { changeToAbsolute,pathRelative, extractLinks, validateLinks,processLinks } = require('./app') const fs = require("fs"); const path = require("path"); +const { Console } = require('console'); const mdLinks = (path, options) => { return new Promise((resolve, reject) => { if(fs.existsSync(path)){ - - console.log("es relatiuva",pathRelative(path)) - console.log("es relatiuva",changeToAbsolute(path)) + + processLinks(extractLinks(path)) + + // console.log("es relatiuva",pathRelative(path)) + // console.log("es relatiuva",changeToAbsolute(path)) //console.log("mdlinks",checkPath(path)); - // findLinks(['https://www.google.com/search?q=google+traductor&oq=goo&aqs=chrome.0.69i59l2j69i57j69i60l2j69i65l3.1503j0j7&sourceid=chrome&ie=UTF-8']) - + // validateLinks(['http://google.com/ ']) + // .then(({contStatus, contStatusText}) => console.log({contStatus, contStatusText})) + // .catch((error) => console.error(error)) // console.log("leer archivo", readFiles(path)) //console.log( findLinks()) - extractLinks(path) - .then(validateLinks) - .then((links) => console.log("linksss",links)) - .catch((error) => console.error(error)); + } else { reject("la ruta no existe") } - const { extractLinks, validateLinks } = require('./links.js'); + From d9c894da9f9f094897c6bc230615b405e0c9f65b Mon Sep 17 00:00:00 2001 From: Roxsy Date: Mon, 13 Feb 2023 22:11:20 -0500 Subject: [PATCH 08/12] configuracion de package json --- app.js | 18 ++++++++++-------- cli.js | 5 +++++ package.json | 8 ++++++++ 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/app.js b/app.js index 5b3f254..28f5b10 100644 --- a/app.js +++ b/app.js @@ -80,7 +80,7 @@ const validateLinks = (links) => { - resolve({ contStatus, contStatusText }) + resolve(response) }) .catch(error => { if (error.code === 'ENOTFOUND') { @@ -102,18 +102,20 @@ const processLinks = (extract) => { const linkHref = link.href validateLinks(linkHref) - .then(({ contStatus, contStatusText }) => ({ contStatus, contStatusText })) + .then((response) => { + const obj = { + ...links, + status: response.status, + ok: response.statusText + }; + console.log("DFSDFSDF", obj) + return obj; + } ) .catch((error) => console.error(error)) - arrli.push({ - ...links, - - - }) - console.log("arrli", arrli) }); diff --git a/cli.js b/cli.js index b1184bf..09959a7 100644 --- a/cli.js +++ b/cli.js @@ -2,8 +2,13 @@ const { mdLinks } = require('./index.js'); mdLinks('./README.md') + .then(() => { mdLinks => console.log(mdLinks) + console.log(process.env); // muestra todas las variables de entorno +console.log(process.argv); // muestra todos los argumentos de línea de comandos +console.log(process.argv[2]); // muestra el tercer argumento + }) .catch((error) => { console.log(error) diff --git a/package.json b/package.json index bf3cf1b..3c4c51a 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,14 @@ "engines": { "node": ">=16.x" }, + "bin": { + "mi-comando": "./cli.js" + + }, + "keywords": [ + "cli" + ], + "bootcamp": { "createdAt": "2022-11-30T13:40:29.636Z", "version": "5.5.0", From f3ebc739fd9c7692d5e56a1d3fbaa420a2d778b3 Mon Sep 17 00:00:00 2001 From: Roxsy Date: Wed, 15 Feb 2023 12:54:47 -0500 Subject: [PATCH 09/12] configuracion de bin, para probar option y argv --- app.js | 23 ++++++++++++----------- cli.js | 38 ++++++++++++++++++++++++++++---------- index.js | 12 ++++++++---- option.js | 19 +++++++++++++++++++ package.json | 2 +- 5 files changed, 68 insertions(+), 26 deletions(-) create mode 100644 option.js diff --git a/app.js b/app.js index 28f5b10..8f28f2d 100644 --- a/app.js +++ b/app.js @@ -67,20 +67,17 @@ const validateLinks = (links) => { return new Promise((resolve, reject) => { - axios .get(links) .then(response => { - //console.log("repose", response) + const contStatus = response.status; const contStatusText = response.statusText; //statusMessage // http: __currentUrl //statusCode - - - resolve(response) + resolve({contStatus, contStatusText}) }) .catch(error => { if (error.code === 'ENOTFOUND') { @@ -95,31 +92,35 @@ const validateLinks = (links) => { }) }; const processLinks = (extract) => { - extract.then((links) => { + return extract.then((links) => { // Aquí puedes recorrer los links - links.forEach(link => { - const arrli = [] + const arrLinks = links.map(link => { + // console.log("linkss", link) const linkHref = link.href - validateLinks(linkHref) + const promesaLink = validateLinks(linkHref) + .then((response) => { const obj = { ...links, status: response.status, ok: response.statusText }; - console.log("DFSDFSDF", obj) + return obj; } ) .catch((error) => console.error(error)) - + return promesaLink; }); + return arrLinks; }); + + }; diff --git a/cli.js b/cli.js index 09959a7..0e43d48 100644 --- a/cli.js +++ b/cli.js @@ -1,3 +1,4 @@ +#!/usr/bin/env node const { mdLinks } = require('./index.js'); mdLinks('./README.md') @@ -5,21 +6,38 @@ mdLinks('./README.md') .then(() => { mdLinks => console.log(mdLinks) - console.log(process.env); // muestra todas las variables de entorno -console.log(process.argv); // muestra todos los argumentos de línea de comandos -console.log(process.argv[2]); // muestra el tercer argumento + }) .catch((error) => { console.log(error) }) -/*absoOurRelative('./README.md') -.then(() => { - absoOurRelative => console.log(absoOurRelative) -}) -.catch((error) => { - error => console.error(error) -})*/ + + + + + + +// const [,, ...args] = process.argv + +// console.log(`hola mundo ${args}`) + + + +// const { argv } = require('process'); +// const { mdLinks } = require('./promise'); + +// // Interface to get the arguments passed to the +// // node.js process when run in the command line +// let path = argv[2]; +// let optionOne = argv[3]; +// let optionTwo = argv[4]; +// let options = [optionOne, optionTwo]; + + +// mdLinks(path, options); + +// module.exports = { mdLinks } diff --git a/index.js b/index.js index 1edcb64..585c605 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,6 @@ const { changeToAbsolute,pathRelative, extractLinks, validateLinks,processLinks } = require('./app') const fs = require("fs"); const path = require("path"); -const { Console } = require('console'); const mdLinks = (path, options) => { return new Promise((resolve, reject) => { @@ -9,8 +8,10 @@ const mdLinks = (path, options) => { if(fs.existsSync(path)){ - processLinks(extractLinks(path)) - + const objFalse = processLinks(extractLinks(path)) + console.log("objs false", objFalse) + objFalse + .then(console.log) // console.log("es relatiuva",pathRelative(path)) // console.log("es relatiuva",changeToAbsolute(path)) @@ -35,4 +36,7 @@ const mdLinks = (path, options) => { } module.exports = { mdLinks -} \ No newline at end of file +} +const [,, ...args] = process.argv + +console.log(`hola mundo ${args}`) \ No newline at end of file diff --git a/option.js b/option.js new file mode 100644 index 0000000..944dfdb --- /dev/null +++ b/option.js @@ -0,0 +1,19 @@ +const { mdLinks } = require('./promise.js'); + +const md_Links = (pathname, options) => { + if ((options === null || options === undefined) || options === '{ validate: false }' || options.validate === false/*&& (secondOption === null || firstOption === undefined)*/) { + // console.log(`You entered ${pathname} only without options`); + mdLinks(pathname, '') + .then(links => { + console.log(links); + }) + } else if (options === '{ validate: true }' || options.validate === true) { + // console.log(`You entered ${pathname} and '{ validate: true }'`); + mdLinks(pathname, ['--validate']) + .then(outcome => { + console.log(outcome); + }) + } +} + +// md_Links('./test/folder', '{ validate: true }'); diff --git a/package.json b/package.json index 3c4c51a..a9cab8c 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "node": ">=16.x" }, "bin": { - "mi-comando": "./cli.js" + "mycli": "./cli.js" }, "keywords": [ From 231601aee54c8fd1ce0f6e33a61a342756538cb9 Mon Sep 17 00:00:00 2001 From: Roxsy Date: Wed, 22 Feb 2023 22:08:00 -0500 Subject: [PATCH 10/12] funciones ejecutables en cli --- app.js | 230 +++++++++------------------------------------- index.js | 60 ++++++++---- package-lock.json | 3 + 3 files changed, 90 insertions(+), 203 deletions(-) diff --git a/app.js b/app.js index 8f28f2d..a5c64e0 100644 --- a/app.js +++ b/app.js @@ -5,38 +5,60 @@ const { Console } = require('console'); const { resolve } = require('path'); const mdFiles = []; -//Devuelve true si el path es absoluto sino false. -const pathRelative = (ruta) => { - return path.isAbsolute(ruta) -}; + + // si es¡xiste el archivo +const fileExists = (pathname) => { + return fs.existsSync(pathname); +} -//Convertir el path en Absoluto -const changeToAbsolute = (ruta) => { - return path.resolve(ruta); -}; +// si es absoluta +const checkPath = (pathname) => { + return path.isAbsolute(pathname) +} + +//convierte a absoluta +const getAbsolutePath = (relativePath) => { + return new Promise((resolve, reject) => { + const absolutePath = path.resolve(relativePath); + if (absolutePath) { + resolve(absolutePath); + } else { + reject('No se pudo obtener la ruta absoluta.'); + } + }); +} +// archivo con terminacion .m +const isMdFile = (filePath) => { + return path.extname(filePath) === '.md'; +}; -const checkFile = filePath => { +// es directorio +const readDir = (dir) => { return new Promise((resolve, reject) => { - fs.lstat(filePath, (err, stat) => { - if (err) { - reject(err); - return; + fs.readdir(dir, (error, files) => { + if (error) { + reject(error); + } else { + resolve(files); } + }); + }); +}; - if (stat.isFile()) { - resolve(`${filePath} is a file`); - } else if (stat.isDirectory()) { - resolve(`${filePath} is a directory`); +const isDirectory = (filePath) => { + return new Promise((resolve, reject) => { + fs.lstat(filePath, (error, stats) => { + if (error) { + reject(error); + } else { + resolve(stats.isDirectory()); } }); }); }; - -// regex para ver si es ruta absoluta - const extractLinks = (ruta) => { return new Promise((resolve, reject) => { fs.readFile(ruta, 'utf-8', (error, fileContents) => { @@ -62,7 +84,6 @@ const extractLinks = (ruta) => { }); }; - const validateLinks = (links) => { return new Promise((resolve, reject) => { @@ -91,6 +112,7 @@ const validateLinks = (links) => { }) }; + const processLinks = (extract) => { return extract.then((links) => { // Aquí puedes recorrer los links @@ -126,186 +148,22 @@ const processLinks = (extract) => { -/* - axios - .get(file) - .then(response => { - console.log("reponse", response.status); - - }) - .catch(error => { - console.error(error); - }); -*/ - - -// -/*const checkPath = () => { - - const files = fs.readdirSync(ruta); - files.forEach(file => { - const filePath = path.join(ruta, file) - //console.log("filepath",filePath); - const stats = fs.lstatSync(filePath); - // console.log("fuera", stats) - //console.log("extencion", path.extname(filePath) ) - if(stats.isDirectory()){ - checkPath(filePath); - } else if(stats.isFile() && path.extname(filePath) === '.md'){ - mdFiles.push(filePath); - } - }); - return mdFiles; -} */ -const checkPath = (dir) => { - const stats = fs.lstatSync(dir); - if (stats.isFile() && path.extname(dir) === '.md') { - mdFiles.push(dir); - } else if (stats.isDirectory()) { - const files = fs.readdirSync(dir); - - files.forEach(file => { - - const filePath = path.join(dir, file); - - // nombre de la ruta ./carpeta + readme.md - - checkPath(filePath); - }); - } - return mdFiles; -} -const readFiles = (path) => { - fs.readFile(path, 'utf8', (err, data) => { - if (err) { - console.error(err); - return err; - - } - console.log(data) - return data; - }); - -} - - -const findLinks = (mdFiles) => { - - console.log("mdLinks en findLinks", mdFiles) - mdFiles.forEach(file => { - - console.log("lista array", file); - - console.log("lectura de arr", readFiles(file)) - return readFiles(file) - - }); -} - - - - - - - -//Función para leer los archivos - - - - -/*const mdFiles = []; - -function checkPath(dir) { - fs.lstat(dir, (err, stats) => { - if (err) { - console.error(err); - return; - } - console.log("fills", path.extname(dir)) - console.log("file. md", ) - if (stats.isFile() && path.extname(dir) === '.md') { - console.log(" dir ", dir); - } else if (stats.isDirectory()) { - fs.readdir(dir, (err, files) => { - if (err) { - console.error(err); - return; - } - - - }); - } - }); -} */ - - - - - - - - -// esto es prueba - -/* - -const absoOurRelative = (path) => { - return new Promise((resolve, reject) => { - if (isAbsolute(path)) { - resolve(path); - } else { - resolve(path.resolve(path)); - } - }); -}; - - -const mdLinks = (path) => { - - console.log("absoluta booleano", isAbsolute(path)); - // path == relativa - return new Promise((resolve, reject) => { - // resolve => relativa al rutaectorio desde donde se invoca node - - - // istat para saber si es una carpeta - fs.lstat(path, (err, stats) => { - if (err) { - console.error(err); - } else if (stats.isrutaectory()) { - console.log('Es una carpeta'); - } else if (stats.isFile()) { - console.log('Es un archivo'); - } else { - console.log('No es ni una carpeta ni un archivo'); - } - }); - - - // funcion - chequear o convertir una ruta absoluta - // probar si esa ruta absoluta es una archivo o rutaectorio - // Si es un rutaectorio filtrar los archivos md. arry filtrado - - - - }) -} */ module.exports = { - changeToAbsolute, checkPath, findLinks, readFiles, pathRelative, extractLinks, validateLinks, processLinks + getAbsolutePath,checkPath,isDirectory, readDir, extractLinks,processLinks,isMdFile }; \ No newline at end of file diff --git a/index.js b/index.js index 585c605..2ba5049 100644 --- a/index.js +++ b/index.js @@ -1,17 +1,46 @@ -const { changeToAbsolute,pathRelative, extractLinks, validateLinks,processLinks } = require('./app') + +const { getAbsolutePath,checkPath,isDirectory, readDir, extractLinks,processLinks,isMdFile } = require('./app') const fs = require("fs"); const path = require("path"); -const mdLinks = (path, options) => { - return new Promise((resolve, reject) => { - +const mdLinks = (relativePath, options) => { + + + return getAbsolutePath(relativePath) + .then((absolutePath) => { + if (!checkPath(absolutePath)) { + throw new Error('La ruta no es absoluta'); + } + return isDirectory(absolutePath) + .then((isDir) => { + if (isDir) { + return readDir(absolutePath) + .then((files) => { + const mdFiles = files.filter((file) => isMdFile(file)); + const promises = mdFiles.map((file) => + extractLinks(path.join(absolutePath, file)).then((links) => + Promise.all(processLinks(links)) + ) + ); + return Promise.all(promises).then((results) => [].concat(...results)); + }); + } else { + return extractLinks(absolutePath).then((links) => + Promise.all(processLinks(links)) + ); + } + }); + }) + .catch((error) => { + console.error(error); + }); - if(fs.existsSync(path)){ + // if(fs.existsSync(path)){ - const objFalse = processLinks(extractLinks(path)) - console.log("objs false", objFalse) - objFalse - .then(console.log) + // const objFalse = processLinks(extractLinks(path)) + //////console.log("objs false", objFalse) + //// objFalse + //.then(console.log) // console.log("es relatiuva",pathRelative(path)) // console.log("es relatiuva",changeToAbsolute(path)) @@ -24,19 +53,16 @@ const mdLinks = (path, options) => { - } else { - reject("la ruta no existe") - } + // } else { + //reject("la ruta no existe") + // } + + - }) -} module.exports = { mdLinks } -const [,, ...args] = process.argv - -console.log(`hola mundo ${args}`) \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d8c8ab4..06684ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,9 @@ "dependencies": { "axios": "^1.3.2" }, + "bin": { + "mycli": "cli.js" + }, "devDependencies": { "jest": "^29.4.1" }, From d327f44c9a0e8a18251fbd8a3afa0397b02fcf9b Mon Sep 17 00:00:00 2001 From: Roxsy Date: Thu, 2 Mar 2023 09:05:03 -0500 Subject: [PATCH 11/12] funcion de processLinks --- app.js | 52 ++++++++++------ {Caperta => carpeta}/README.md | 0 {Caperta => carpeta}/subcarpeta/README.md | 0 .../media-Capera/Nueva carpeta/README.md | 0 .../subcarpeta/media-Capera/README.md | 0 cli.js | 5 +- index.js | 61 ++++++++----------- option.js | 5 +- 8 files changed, 61 insertions(+), 62 deletions(-) rename {Caperta => carpeta}/README.md (100%) rename {Caperta => carpeta}/subcarpeta/README.md (100%) rename {Caperta => carpeta}/subcarpeta/media-Capera/Nueva carpeta/README.md (100%) rename {Caperta => carpeta}/subcarpeta/media-Capera/README.md (100%) diff --git a/app.js b/app.js index a5c64e0..e4a029e 100644 --- a/app.js +++ b/app.js @@ -1,19 +1,17 @@ const fs = require('fs'); const path = require('path'); const axios = require('axios'); -const { Console } = require('console'); -const { resolve } = require('path'); const mdFiles = []; // si es¡xiste el archivo -const fileExists = (pathname) => { - return fs.existsSync(pathname); +const fileExists = (path) => { + return fs.existsSync(path); } // si es absoluta -const checkPath = (pathname) => { - return path.isAbsolute(pathname) +const checkPath = (path) => { + return path.isAbsolute(path) } //convierte a absoluta @@ -60,6 +58,7 @@ const isDirectory = (filePath) => { }; const extractLinks = (ruta) => { + console.log("ruta",ruta); return new Promise((resolve, reject) => { fs.readFile(ruta, 'utf-8', (error, fileContents) => { if (error) { @@ -81,16 +80,26 @@ const extractLinks = (ruta) => { resolve(links); }); + .catch((error) => reject(error)); + }); }; +extractLinks("./README") +.then() + + + + + const validateLinks = (links) => { + return new Promise((resolve, reject) => { axios .get(links) - .then(response => { + .then((response) => { const contStatus = response.status; const contStatusText = response.statusText; @@ -100,21 +109,16 @@ const validateLinks = (links) => { resolve({contStatus, contStatusText}) }) - .catch(error => { - if (error.code === 'ENOTFOUND') { - reject("codigo roto") - - } - - - }) + .catch((error) => error) }) }; -const processLinks = (extract) => { - return extract.then((links) => { + +const processLinks = (path) => { + extractLinks(path) + .then((links) => { // Aquí puedes recorrer los links const arrLinks = links.map(link => { // console.log("linkss", link) @@ -132,6 +136,7 @@ const processLinks = (extract) => { return obj; } ) + .catch((error) => console.error(error)) return promesaLink; @@ -164,6 +169,13 @@ const processLinks = (extract) => { module.exports = { - getAbsolutePath,checkPath,isDirectory, readDir, extractLinks,processLinks,isMdFile - -}; \ No newline at end of file + fileExists, + checkPath, + getAbsolutePath, + isMdFile, + readDir, + isDirectory, + extractLinks, + validateLinks, + processLinks, +}; diff --git a/Caperta/README.md b/carpeta/README.md similarity index 100% rename from Caperta/README.md rename to carpeta/README.md diff --git a/Caperta/subcarpeta/README.md b/carpeta/subcarpeta/README.md similarity index 100% rename from Caperta/subcarpeta/README.md rename to carpeta/subcarpeta/README.md diff --git a/Caperta/subcarpeta/media-Capera/Nueva carpeta/README.md b/carpeta/subcarpeta/media-Capera/Nueva carpeta/README.md similarity index 100% rename from Caperta/subcarpeta/media-Capera/Nueva carpeta/README.md rename to carpeta/subcarpeta/media-Capera/Nueva carpeta/README.md diff --git a/Caperta/subcarpeta/media-Capera/README.md b/carpeta/subcarpeta/media-Capera/README.md similarity index 100% rename from Caperta/subcarpeta/media-Capera/README.md rename to carpeta/subcarpeta/media-Capera/README.md diff --git a/cli.js b/cli.js index 0e43d48..1498c42 100644 --- a/cli.js +++ b/cli.js @@ -4,11 +4,8 @@ const { mdLinks } = require('./index.js'); mdLinks('./README.md') -.then(() => { - mdLinks => console.log(mdLinks) +.then((resp) => console.log(resp)) - -}) .catch((error) => { console.log(error) }) diff --git a/index.js b/index.js index 2ba5049..ffa4a5a 100644 --- a/index.js +++ b/index.js @@ -1,39 +1,31 @@ +const fs = require('fs'); +const path = require('path'); + +const { + fileExists, + checkPath, + getAbsolutePath, + isMdFile, + readDir, + isDirectory, + extractLinks, + validateLinks, + processLinks, +} += require('./app') -const { getAbsolutePath,checkPath,isDirectory, readDir, extractLinks,processLinks,isMdFile } = require('./app') -const fs = require("fs"); -const path = require("path"); -const mdLinks = (relativePath, options) => { - +const mdLinks = (path, options) => { + return new Promise((resolve, reject) => { - return getAbsolutePath(relativePath) - .then((absolutePath) => { - if (!checkPath(absolutePath)) { - throw new Error('La ruta no es absoluta'); - } - return isDirectory(absolutePath) - .then((isDir) => { - if (isDir) { - return readDir(absolutePath) - .then((files) => { - const mdFiles = files.filter((file) => isMdFile(file)); - const promises = mdFiles.map((file) => - extractLinks(path.join(absolutePath, file)).then((links) => - Promise.all(processLinks(links)) - ) - ); - return Promise.all(promises).then((results) => [].concat(...results)); - }); - } else { - return extractLinks(absolutePath).then((links) => - Promise.all(processLinks(links)) - ); - } - }); - }) - .catch((error) => { - console.error(error); - }); + validateLinks(['http://google.com/ ']) + .then(({contStatus, contStatusText}) => console.log({contStatus, contStatusText})) + + + }); +}; + + // if(fs.existsSync(path)){ @@ -45,8 +37,7 @@ const mdLinks = (relativePath, options) => { // console.log("es relatiuva",changeToAbsolute(path)) //console.log("mdlinks",checkPath(path)); - // validateLinks(['http://google.com/ ']) - // .then(({contStatus, contStatusText}) => console.log({contStatus, contStatusText})) + // // .catch((error) => console.error(error)) // console.log("leer archivo", readFiles(path)) //console.log( findLinks()) diff --git a/option.js b/option.js index 944dfdb..de2564d 100644 --- a/option.js +++ b/option.js @@ -2,13 +2,13 @@ const { mdLinks } = require('./promise.js'); const md_Links = (pathname, options) => { if ((options === null || options === undefined) || options === '{ validate: false }' || options.validate === false/*&& (secondOption === null || firstOption === undefined)*/) { - // console.log(`You entered ${pathname} only without options`); + mdLinks(pathname, '') .then(links => { console.log(links); }) } else if (options === '{ validate: true }' || options.validate === true) { - // console.log(`You entered ${pathname} and '{ validate: true }'`); + mdLinks(pathname, ['--validate']) .then(outcome => { console.log(outcome); @@ -16,4 +16,3 @@ const md_Links = (pathname, options) => { } } -// md_Links('./test/folder', '{ validate: true }'); From d9c595127671d018d193d7535e3d76d66199c1ca Mon Sep 17 00:00:00 2001 From: Roxsy Date: Thu, 2 Mar 2023 09:08:25 -0500 Subject: [PATCH 12/12] progress funcion --- option.js | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/option.js b/option.js index de2564d..b28b04f 100644 --- a/option.js +++ b/option.js @@ -1,18 +1,3 @@ -const { mdLinks } = require('./promise.js'); -const md_Links = (pathname, options) => { - if ((options === null || options === undefined) || options === '{ validate: false }' || options.validate === false/*&& (secondOption === null || firstOption === undefined)*/) { - - mdLinks(pathname, '') - .then(links => { - console.log(links); - }) - } else if (options === '{ validate: true }' || options.validate === true) { - mdLinks(pathname, ['--validate']) - .then(outcome => { - console.log(outcome); - }) - } -}